摘要:前言說到面向?qū)ο?,可能第一想到的是或者這樣的語言。默認(rèn)情況下,所有原型對象都會自動獲得一個構(gòu)造函數(shù)屬性會執(zhí)行屬性所在函數(shù)。相對于原型鏈而言,借用構(gòu)造函數(shù)有一個很大的優(yōu)勢,即
前言
說到面向?qū)ο?,可能第一想到的是C++或者Java這樣的語言。這些語言有都一個標(biāo)志,那就是引入了類的概念。我們可以通過類創(chuàng)建任意數(shù)量的具有相同屬性和方法的對象。ECMAScript(JavaScript分為ECMAScript、DOM和BOM)中沒有類的概念,所以它的對象相比較基于類的語言還是有所不同的。
說說對象的屬性var person={ name:"張三", age:23, sex:"男", sayName:function () { alert(this.name); } }
上面我們用了對象字面量的方式建了一個非常簡單的person對象,他擁有name、age、sex、sayName這些屬性,而這些屬性在創(chuàng)建時都帶有一些特征值,JavaScript通過這些特征值就可以定義這些屬性的行為。在ECMAScript中,屬性分為兩種:數(shù)據(jù)屬性和訪問器屬性。下面我們一一學(xué)習(xí)下。
數(shù)據(jù)屬性數(shù)據(jù)屬性有四個特征值,分別為如下四個:
configurable
表示能否delete刪除屬性,能否修改屬性的特性,默認(rèn)值是false
enumerable
表示能否通過for-in循環(huán)返回屬性,默認(rèn)值是false
writable
表示能否修改屬性的值,默認(rèn)值是false
value
表示該屬性的值,我們讀取和修改都是在這個位置,默認(rèn)值是undefined
接下來我們一一理解這四個特征值。要修改屬性默認(rèn)的特性,必須使用ECMAScript 5的Object.defineProperty()方法
configurablevar person={}; Object.defineProperty(person,"name",{ configurable:false, value:"張三" }); console.log(person.name);//張三 delete person.name; console.log(person.name);//張三
var person={}; Object.defineProperty(person,"name",{ configurable:true, value:"張三" }); Object.defineProperty(person,"name",{ value:"李四" }); console.log(person.name);//李四
var person={}; Object.defineProperty(person,"name",{ configurable:false, value:"張三" }); Object.defineProperty(person,"name",{ value:"李四" }); console.log(person.name); //控制臺報錯 Uncaught TypeError: Cannot redefine property: nameenumerable
var person={}; Object.defineProperty(person,"name",{ enumerable:true, value:"張三" }); Object.defineProperty(person,"age",{ value:"23" }); Object.defineProperty(person,"sayName",{ enumerable:true, value:function () { alert(this.name); } }); for( var prop in person){ console.log(prop); } //控制臺輸出 name和sayNamewritable
var person={}; Object.defineProperty(person,"name",{ writable:false, value:"張三" }); console.log(person.name);//張三 person.name="李四"; console.log(person.name);//張三value
var person={}; Object.defineProperty(person,"name",{ writable:true, value:"張三" }); console.log(person.name);//張三 person.name="李四"; console.log(person.name);//李四訪問器屬性
訪問器屬性有四個特征值,分別為如下四個:
configurable
表示能否delete刪除屬性,能否修改屬性的特性,默認(rèn)值是false
enumerable
表示能否通過for-in循環(huán)返回屬性,默認(rèn)值是false
get
在讀取屬性調(diào)用的函數(shù),默認(rèn)值是undefined
set
在設(shè)置屬性調(diào)用的函數(shù),默認(rèn)值是undefined
下面我們一一了解一下訪問器屬性的特征值,其中configurable和enumerable與上面數(shù)據(jù)類型一樣,這里我們就不多做介紹,主要我們說一下get和set。
var person={ name:"張三", age:32 }; Object.defineProperty(person,"sayAge",{ get:function () { return this.name+":"+this.age+"歲"; }, set:function (newAge) { console.log("想要重返"+newAge+"歲?不存在的!"); } }); console.log(person.sayAge);//張三:32歲 person.sayAge=18;//想要重返18歲?不存在的! console.log(person.sayAge);//張三:32歲
get和set并非需要同時都要指定。如果只指定get,那么這個屬性就是不可寫的;如果只指定set,那么這個屬性就是不可讀的。
var person1={ name:"張三", age:32 }; Object.defineProperty(person1,"sayAge",{ get:function () { return this.name+":"+this.age+"歲"; } }); console.log(person1.sayAge);//張三:32歲 person1.sayAge=18; console.log(person1.sayAge);//張三:32歲 var person2={ name:"李四", age:46 }; Object.defineProperty(person2,"sayAge",{ set:function () { console.log("想要重返18歲?不存在的!"); } }); console.log(person2.sayAge);//undefined person2.sayAge=18;//想要重返18歲?不存在的! console.log(person2.sayAge);//undefined定義多個屬性
這個里我們就要說一個Object.defineProperties()方法,具體用下看如下示例:
var person = {}; Object.defineProperties(person, { name: { writable: true, value: "張三" }, age: { enumerable: true, value: 23, }, sayName: { get: function () { return this.name; }, set: function (newName) { console.log("名字修改完成"); this.name=newName+"(修改)"; } } });讀取屬性的特性
這里我們可以正好驗(yàn)證我們前面所有默認(rèn)值。
var person={}; Object.defineProperty(person,"name",{ value:"張三" }); var descriptor=Object.getOwnPropertyDescriptor(person,"name"); console.log("configurable:"+descriptor.configurable); //configurable:false console.log("enumerable:"+descriptor.enumerable); //enumerable:false console.log("writable:"+descriptor.writable); //writable:false console.log("value:"+descriptor.value); //張三創(chuàng)建對象 字面量模式
var person={}; person.name="張三"; person.age=22; person.sex="男"; person.sayName=function () { alert(this.name); }
優(yōu)點(diǎn):創(chuàng)建單個對象簡單方便
缺點(diǎn):創(chuàng)建多個相似對象會產(chǎn)生大量代碼
function createPerson(name, age, sex) { var person = new Object(); person.name = name; person.age = age; person.sex = sex; person.sayName = function () { alert(this.name); }; return person; } var person=createPerson("張三",22,"男");
優(yōu)點(diǎn):可以快速創(chuàng)建多個相似對象
缺點(diǎn):無法進(jìn)行對象的識別
function Person(name, age, sex) { this.name = name; this.age = age; this.sex = sex; this.sayName = function () { alert(this.name); }; } var person=new Person("張三",22,"男");
以構(gòu)造函數(shù)的方式創(chuàng)建對象要經(jīng)歷下面四個步驟:
創(chuàng)建一個新對象
將構(gòu)造函數(shù)的作用域賦給新對象(因此this指向這個新對象)
執(zhí)行構(gòu)造函數(shù)中的代碼,為這個新對象添加屬性
返回新對象
這里person有一個constructor(構(gòu)造函數(shù))屬性指向Person,我們可以驗(yàn)證一下。
alert(person.constructor===Person);//true
鑒于這個特性我們可以用constructor來驗(yàn)證對象的類型。除了這個,我們還可以利用instanceof。
alert(person instanceof Person);//true
雖然我們使用構(gòu)造函數(shù)模式可以進(jìn)行對象的識別,但是構(gòu)造函數(shù)模式卻有一個缺點(diǎn),就是每個方法都要在每個實(shí)例上重新創(chuàng)建一遍。下面我們舉個例子說明一下。
function Person(name, age, sex) { this.name = name; this.age = age; this.sex = sex; this.sayName = function () { alert(this.name); }; } var person1=new Person("張三",22,"男"); var person2=new Person("李四",25,"男"); alert(person1.sayName===person2.sayName);//false
從上面的例子我們看出來,person1和person2的sayName函數(shù)并非共用同一個。
優(yōu)點(diǎn):可以進(jìn)行對象的識別
缺點(diǎn):構(gòu)造函數(shù)里面的函數(shù)在實(shí)例化的時候都需要每次都創(chuàng)建一遍,導(dǎo)致不同作用域鏈和標(biāo)識符解析。
function Person() { } Person.prototype.name="張三"; Person.prototype.age=22; Person.prototype.sex="男"; Person.prototype.sayName=function () { alert(this.name); }; var person=new Person();
任何時候我們只要創(chuàng)建一個新函數(shù),就會根據(jù)一組特定的規(guī)則為該函數(shù)創(chuàng)建一個prototype屬性這個屬性指向函數(shù)的原型對象。默認(rèn)情況下,所有原型對象都會自動獲得一個constructor(構(gòu)造函數(shù))屬性會執(zhí)行prototype屬性所在函數(shù)。以上面這個例子為例,即:
Person.prototype.constructor===Person//true
另外我們的實(shí)例對象都會有一個__proto__屬性指向構(gòu)造函數(shù)的原型對象。即:
person.__proto__===Person.prototype //true
接下來我們要說的一點(diǎn)是我們可以通過對象實(shí)例訪問保存在原型中的值,但是不能通過對象實(shí)例重寫原型中的值。下面我們看個例子:
function Person() { } Person.prototype.name="張三"; Person.prototype.age=22; Person.prototype.sex="男"; Person.prototype.sayName=function () { alert(this.name); }; var person1=new Person(); var person2=new Person(); person1.name="李四"; alert(person1.name);//李四 alert(person2.name);//張三
從上面的例子我們可以看出,我們修改了person1的name屬性實(shí)際是實(shí)例對象person1中的屬性,而不是Person.prototype原型對象。如果我們想要person1.name指向Person.prototype.name則需要刪除實(shí)例對象person1中name屬性,如下所示:
delete person1.name; alert(person1.name);//張三
說到這里我們遇到一個一個問題,就是如何判斷一個屬性在原型上還是在實(shí)例對象上?這個是有方法可以做到的,那就是hasOwnProperty()方法,接著上面的代碼,我們可以用這個hasOwnProperty()方法去驗(yàn)證一下。
alert(person1.hasOwnProperty("name"));//false
上面我們刪除實(shí)例對象person1中name屬性之后,name應(yīng)該不屬于實(shí)例對象person1的屬性,所以hasOwnProperty()返回false.
如果只是想知道person1能否訪問name屬性,不論在實(shí)例對象上還是原型上的話,我們可以用in操作符。如下所示:
alert("name" in person1);//true
相對上面的原型語法,我們有一個相對簡單的原型語法。
function Person() { } Person.prototype = { constructor:Person, name: "張三", age: 22, sex:"男", sayName: function () { alert(this.name); } };
這里注意的是,需要重新設(shè)置constructor為Person,否則constructor指向Object而不是Person。但是這樣有一個缺點(diǎn),就是constructor的enumerable特性被設(shè)為true。導(dǎo)致constructor屬性由原本不可枚舉變成可枚舉。如果想解決這個問題可以嘗試這種寫法:
function Person() { } Person.prototype = { name: "張三", age: 22, sex:"男", sayName: function () { alert(this.name); } }; Object.defineProperty(Person.prototype,"constructor",{ enumerable:false, value:Person });
說完這個之后,我們來說一下原型的動態(tài)性。由于在原型中查找值的過程是一次搜索,因此我們對原型對象所做的任何修改都能夠立即從實(shí)例上反映出來。我們看一下下面的例子:
function Person() { } var person=new Person(); person.name="張三"; person.sayName=function () { alert(this.name); }; person.sayName();//張三
但是在重寫整個原型對象的時候情況就不一樣了,我們看一下下面這個例子:
function Person() { } var person = new Person(); Person.prototype = { constructor:Person, name: "張三", age: 22, sayName: function () { alert(this.name); } }; person.sayName(); //Uncaught TypeError: person.sayName is not a function
重寫原型對象會切斷現(xiàn)有原型與任何之前已經(jīng)存在的對象實(shí)例之間的聯(lián)系,引用的仍然是最初的原型,上面的例子由于最初的原型的沒有sayName()方法,所以會報錯。
優(yōu)點(diǎn):可以進(jìn)行對象的識別,以及實(shí)例對象的函數(shù)不會被重復(fù)創(chuàng)建,從而不會導(dǎo)致不同的作用域鏈。
缺點(diǎn):省略了為構(gòu)造函數(shù)傳遞初始化參數(shù)這一環(huán)節(jié),所有實(shí)例在默認(rèn)情況都取相同的值。
function Person(name, age) { this.name = name; this.age = age; } Person.prototype = { constructor:Person, sayName: function () { alert(this.name); } }; var person1 = new Person("張三", 22); var person2 = new Person("李四", 23); alert(person1.sayName===person2.sayName);//true
優(yōu)點(diǎn):結(jié)合構(gòu)造函數(shù)模式和原型模式的優(yōu)點(diǎn),是目前使用最廣泛、認(rèn)同度最高的一種創(chuàng)建自定義類型的方法。
動態(tài)原型模式function Person(name,age,sex) { this.name=name; this.age=age; this.sex=sex; if(typeof this.sayName!="function"){ Person.prototype.sayName=function () { alert(this.name); }; } } var person=new Person("張三",22,"男"); person.sayName();//張三
上面代碼中if語句只有在初次調(diào)用構(gòu)造函數(shù)時才會執(zhí)行。此后,原型已經(jīng)初始化,不需要再做什么修改了。
優(yōu)點(diǎn):保留了構(gòu)造函數(shù)模式和原型模式的優(yōu)點(diǎn),又將所有信息封裝信息封裝在了構(gòu)造函數(shù)中。
function Person(name,age,sex) { var object=new Object(); object.name=name; object.age=age; object.sex=sex; object.sayName=function () { alert(this.name); }; return object; } var person=new Person("張三",22,"男"); person.sayName();//張三
由于我們可以重寫調(diào)用構(gòu)造函數(shù)時的返回值,所以我們可以在特殊情況下為對象創(chuàng)建構(gòu)造函數(shù)。例如我們想創(chuàng)建一個具有特殊方法的數(shù)組,由于我們不能修改Array構(gòu)造函數(shù),因此可以使用這種方式。
function SpecialArray() { var values=new Array(); values.push.apply(values,arguments); values.toPipedString=function () { return this.join("|"); }; return values; } var colors=new SpecialArray("red","yellow","white"); alert(colors.toPipedString());//"red|yellow|white"
但這種方式缺點(diǎn)也是很明顯,由于構(gòu)造函數(shù)返回的對象與構(gòu)造函數(shù)外部創(chuàng)建的對象沒有什么不同。所以,instanceof操作符不能確定對象類型。因此這種模式優(yōu)先級很低,不推薦優(yōu)先使用。
優(yōu)點(diǎn):可以重寫構(gòu)造函數(shù)函數(shù)的返回值,特殊情況下比較好用。
缺點(diǎn):instanceof操作符不能確定對象類型。
function Person(name) { var object=new Object(); var name=name; object.sayName=function () { alert(name); }; return object; } var person=new Person("張三",22,"男"); person.sayName();//張三 alert(person.name);//undefined
在這種模式下,想訪問name這個數(shù)據(jù)成員時,除了調(diào)用sayName()方法,沒有其他方法可以訪問傳入構(gòu)造函數(shù)中的原始數(shù)據(jù)。這種模式的安全性就很高。
優(yōu)點(diǎn):安全性高。
缺點(diǎn):instanceof操作符不能確定對象類型。
function SuperType() { this.property=true; } SuperType.prototype.getSuperValue=function () { return this.property; }; function SubType() { this.subproperty=false; } //繼承SuperType SubType.prototype=new SuperType(); SubType.prototype.getSubValue=function () { return this.subproperty; }; var instance=new SubType(); alert(instance.getSuperValue());
上面代碼中,我們沒有使用SubType默認(rèn)提供的原型,而是給它換了一個新原型(SuperType實(shí)例)。于是,新原型不僅具有作為SuperType的實(shí)例所擁有的全部屬性和方法,而且其內(nèi)部還擁有一個指針,指向了SuperType的原型。最終結(jié)果如下:
根據(jù)上面,需要說明一點(diǎn)的是所有函數(shù)的默認(rèn)原型都是Object的實(shí)例,因此默認(rèn)原型都會包含一個內(nèi)部指針指向Object.prototype。
在我們使用原型鏈的過程會有一個問題就是確定原型和實(shí)例之間的關(guān)系。這里我們有兩種方式,我們接著上面代碼繼續(xù)看。
第一種:instanceof操作符,測試實(shí)例與原型中出現(xiàn)過的構(gòu)造函數(shù)
alert(instance instanceof Object);//true alert(instance instanceof SuperType);//true alert(instance instanceof SubType);//true
第二種:方法isPrototypeOf(),測試原型鏈中出現(xiàn)過的原型
alert(Object.prototype.isPrototypeOf(instance));//true alert(SuperType.prototype.isPrototypeOf(instance));//true alert(SubType.prototype.isPrototypeOf(instance));//true
如果子類型需要覆蓋超類型中的某個方法,或者需要添加超類型中不存在的某個方法,我們要遵循一個原則,給原型添加方法的代碼一定要放在替換原型的語句之后。如下所示:
function SuperType() { this.property=true; } SuperType.prototype.getSuperValue=function () { return this.property; }; function SubType() { this.subproperty=false; } //繼承SuperType SubType.prototype=new SuperType(); //添加新方法 SubType.prototype.getSubValue=function () { return this.subproperty; }; //重寫超類型中的方法 SubType.prototype.getSuperValue=function () { return false; }; var instance=new SubType(); alert(instance.getSuperValue());
另外我們還需要注意在添加方法時候,不能使用對象字面量創(chuàng)建原型方法。如下所示:
function SuperType() { this.property=true; } SuperType.prototype.getSuperValue=function () { return this.property; }; function SubType() { this.subproperty=false; } //繼承SuperType SubType.prototype=new SuperType(); //使用字面量添加新方法,會導(dǎo)致上一行代碼無效 SubType.prototype={ getSubValue:function () { return this.subproperty; } }; var instance=new SubType(); alert(instance.getSuperValue()); //Uncaught TypeError: instance.getSuperValue is not a function
說到這里我們,我來總結(jié)一下原型鏈的優(yōu)缺點(diǎn):
優(yōu)點(diǎn):功能很強(qiáng)大,可以連續(xù)繼承多個原型的全部屬性和方法。
缺點(diǎn):
1.原型的通用問題就是屬性被共用,修改原型的屬性將會動態(tài)映射到所有指向該原型的實(shí)例。 2.鑒于屬性是共用的,我們無法給超類型的構(gòu)造函數(shù)傳遞參數(shù)。借用構(gòu)造函數(shù)
function SuperType() { this.colors=["red","blue","green"]; } function SubType() { //繼承了SuperType SuperType.call(this); } var instance1=new SubType(); instance1.colors.push("black"); console.log(instance1.colors);//["red", "blue", "green", "black"] var instance2=new SubType(); console.log(instance2.colors);//["red", "blue", "green"]
通過使用call()方法(或apply()方法),在新建的SubType實(shí)例的環(huán)境下條用了SuperType構(gòu)造函數(shù)。這樣一來,就會在新的SubType對象上執(zhí)行SuperType()函數(shù)中定義的所有對象初始化代碼。結(jié)果,SubType的每個實(shí)例就都會具有自己的colors屬性的副本了。
相對于原型鏈而言,借用構(gòu)造函數(shù)有一個很大的優(yōu)勢,即可以在子類型構(gòu)造函數(shù)中向超類型構(gòu)造函數(shù)傳遞參數(shù)。如下所示:
function SuperType(name) { this.name=name; } function SubType() { //繼承了SuperType,同時還傳遞了參數(shù) SuperType.call(this,"張三"); //實(shí)例屬性 this.age=22; } var instance=new SubType(); alert(instance.name);//張三 alert(instance.age);//22
優(yōu)點(diǎn):彌補(bǔ)原型鏈的共用屬性和不能傳遞參數(shù)的缺點(diǎn)。
缺點(diǎn):函數(shù)不能復(fù)用,超類型的原型中定義的方法在子類型中是不可見的。
function SuperType(name) { this.name=name; this.colors=["red","blue","green"]; } SuperType.prototype.sayName=function () { alert(this.name); }; function SubType(name,age) { SuperType.call(this,name);//第二次調(diào)用SuperType() this.age=age; } //繼承方法 SubType.prototype=new SuperType(); SubType.prototype.constructor=SubType; SubType.prototype.sayAge=function () { alert(this.age); }; var instance1=new SubType("張三",22);//第一次調(diào)用SuperType() instance1.colors.push("black"); console.log(instance1.colors);//["red", "blue", "green", "black"] instance1.sayName();//張三 instance1.sayAge();//22 var instance2=new SubType("李四",25); console.log(instance2.colors);//["red", "blue", "green"] instance2.sayName();//李四 instance2.sayAge();//25
缺點(diǎn):創(chuàng)建對象時都會調(diào)用兩次超類型構(gòu)造函數(shù)。
優(yōu)點(diǎn):融合了原型鏈和借助構(gòu)造函數(shù)的優(yōu)點(diǎn),避免了他們的缺陷。Javascript中最常用的繼承模式。
var person={ name:"張三", friends:["李四","王五"] }; var person1=Object(person);//或者Object.create(person) person1.name="趙六"; person1.friends.push("孫七"); var person2=Object.create(person); person2.name="周八"; person2.friends.push("吳九"); console.log(person.friends);//["李四", "王五", "孫七", "吳九"]
原型式繼承實(shí)際上是把實(shí)例的__proto__屬性指向了person。
優(yōu)點(diǎn):只想讓一個對象跟另一個對象保持相似的情況下,代碼變得很簡單。
缺點(diǎn):共享了相應(yīng)的值,原型的通病。
function createPerson(obj) { var clone=Object(obj); clone.sayMyfriends=function () { console.log(this.friends); }; return clone; } var person={ name:"張三", friends:["李四","王五","趙六"] }; var anotherPerson= createPerson(person); anotherPerson.sayMyfriends();//["李四", "王五", "趙六"]
優(yōu)點(diǎn):可以為任意對象添加指定屬性,代碼量很少。
缺點(diǎn): 在為對象添加函數(shù),由于函數(shù)不能復(fù)用。每次添加都會新建一個函數(shù)對象,降低了效率。這一點(diǎn)與構(gòu)造函數(shù)模式類似。
function inheritPrototype(subType,superType) { var prototype=Object(superType.prototype);//創(chuàng)建對象 prototype.constructor=subType;//增強(qiáng)對象 subType.prototype=prototype;//指定對象 } function SuperType(name) { this.name=name; this.colors=["red","blue","green"]; } SuperType.prototype.sayName=function () { alert(this.name); }; function SubType(name,age) { SuperType.call(this,name); this.age=age; } inheritPrototype(SubType,SuperType); SubType.prototype.sayAge=function () { alert(this.age); }; var instance1=new SubType("張三",22); instance1.colors.push("yellow"); instance1.sayName();//張三 instance1.sayAge();//22 var instance2=new SubType("李四",25); console.log(instance2.colors);// ["red", "blue", "green"] instance2.sayName();//李四 instance2.sayAge();//25
上面的inheritPrototype()函數(shù)接收兩個參數(shù):子類型構(gòu)造函數(shù)和超類型構(gòu)造函數(shù)。在函數(shù)內(nèi)部,第一部是創(chuàng)建超類型原型的一個副本。第二步是為創(chuàng)建的副本添加constructor屬性,從而彌補(bǔ)因重寫原型而失去的默認(rèn)的constructor屬性。最后一步,將新創(chuàng)建的對象(即副本)賦值給子類型的原型。這樣,我們就可以用調(diào)用inheritPrototype()函數(shù)的語句,去替換前面例子中為子類型原型賦值的語句。
優(yōu)點(diǎn):集寄生式繼承和組合繼承的優(yōu)點(diǎn)于一身,是實(shí)現(xiàn)基于類型繼承的最有效方式。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/83374.html
摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍(lán)圖或原型。在中,對象通過對類的實(shí)體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實(shí)例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍(lán)圖或原型。在中,對象通過對類的實(shí)體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實(shí)例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍(lán)圖或原型。在中,對象通過對類的實(shí)體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實(shí)例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:是完全的面向?qū)ο笳Z言,它們通過類的形式組織函數(shù)和變量,使之不能脫離對象存在。而在基于原型的面向?qū)ο蠓绞街?,對象則是依靠構(gòu)造器利用原型構(gòu)造出來的。 JavaScript 函數(shù)式腳本語言特性以及其看似隨意的編寫風(fēng)格,導(dǎo)致長期以來人們對這一門語言的誤解,即認(rèn)為 JavaScript 不是一門面向?qū)ο蟮恼Z言,或者只是部分具備一些面向?qū)ο蟮奶卣?。本文將回歸面向?qū)ο蟊疽?,從對語言感悟的角度闡述為什...
摘要:用代碼可以這樣描述安全到達(dá)國外面向過程既然說了面向?qū)ο?,那么與之對應(yīng)的就是面向過程。小結(jié)在這篇文章中,介紹了什么是面向?qū)ο蠛兔嫦蜻^程,以及中對象的含義。 這是 javascript 面向?qū)ο蟀鎵K的第一篇文章,主要講解對面向?qū)ο笏枷氲囊粋€理解。先說說什么是對象,其實(shí)這個還真的不好說。我們可以把自己當(dāng)成一個對象,或者過年的時候相親,找對象,那么你未來的老婆也是一個對象。我們就要一些屬性,比...
摘要:對象重新認(rèn)識面向?qū)ο竺嫦驅(qū)ο髲脑O(shè)計模式上看,對象是計算機(jī)抽象現(xiàn)實(shí)世界的一種方式。除了字面式聲明方式之外,允許通過構(gòu)造器創(chuàng)建對象。每個構(gòu)造器實(shí)際上是一個函數(shù)對象該函數(shù)對象含有一個屬性用于實(shí)現(xiàn)基于原型的繼承和共享屬性。 title: JS對象(1)重新認(rèn)識面向?qū)ο? date: 2016-10-05 tags: JavaScript 0x00 面向?qū)ο?從設(shè)計模式上看,對象是...
閱讀 2126·2021-11-24 10:28
閱讀 1150·2021-10-12 10:12
閱讀 3359·2021-09-22 15:21
閱讀 698·2021-08-30 09:44
閱讀 1914·2021-07-23 11:20
閱讀 1159·2019-08-30 15:56
閱讀 1774·2019-08-30 15:44
閱讀 1495·2019-08-30 13:55