摘要:高程第六章繼承理解與實(shí)踐昨日細(xì)細(xì)的讀了一遍高程現(xiàn)在寫篇文章來(lái)鞏固下認(rèn)知吧讀首先是從中讀到了什么我自己也在讀書(shū)的時(shí)候用筆記下了各個(gè)部分的點(diǎn)現(xiàn)在等于閱讀筆記回憶下書(shū)本理解基礎(chǔ)第五版中規(guī)定了兩種屬性數(shù)據(jù)屬性訪問(wèn)器屬性數(shù)據(jù)屬性包含一個(gè)數(shù)據(jù)值的位
JavaScript高程第六章:繼承-理解與實(shí)踐
昨日細(xì)細(xì)的讀了一遍JavaScript高程,現(xiàn)在寫篇文章來(lái)鞏固下認(rèn)知吧.
首先是從中讀到了什么,我自己也在讀書(shū)的時(shí)候用筆記下了各個(gè)部分的點(diǎn),現(xiàn)在等于閱讀筆記回憶下書(shū)本.
理解基礎(chǔ)ECMA-262(第五版)
ECMA中規(guī)定了兩種屬性:數(shù)據(jù)屬性 and 訪問(wèn)器屬性
包含一個(gè)數(shù)據(jù)值的位置(讀取和寫入)
4個(gè)描述行為的特性
[[Configurable]] 默認(rèn)值為true,描述了可否delete,可否修改其特性(變更為訪問(wèn)器屬性)
[[Enumerable]] 默認(rèn)值為true,描述了能否通過(guò)for-in循環(huán)返回屬性.
[[Writable]] 默認(rèn)為true,能否修改屬性的值
[[Value]] 默認(rèn)為undefined,就是屬性的值
相關(guān)函數(shù) Object.defineProperty(屬性所在對(duì)象,屬性名,描述符對(duì)象(可多個(gè),{}))
注!修改configurable為false,則對(duì)后續(xù)調(diào)用該方法有限制,變得只能修改Writable和Value特性.
不包含屬性值,包含一對(duì)getter和setter函數(shù)(非必需),同樣有4個(gè)特性,相同功能不多加解釋.
[[Configurable]] 默認(rèn)值為true
[[Enumerable]] 默認(rèn)值為true
[[Get]] default:undefined getter函數(shù)
[[Set]] default:undefined setter函數(shù)
注!訪問(wèn)器屬性不能直接定義,必須使用Object.defineProperty()定義,在嚴(yán)格模式中,嘗試寫入只指定了getter函數(shù)的屬性會(huì)拋出錯(cuò)誤,嘗試讀取只指定了setter函數(shù)的屬性同理.
非嚴(yán)格模式中,則會(huì)忽略/返回undefined
相關(guān)函數(shù)和兼容Object.defineProperty(屬性所在對(duì)象,屬性名,描述符對(duì)象(可多個(gè),{}))
支持:IE9+(IE8部分實(shí)現(xiàn)),Firefox4+,Safari5+,Opera 12+和Chrome
不兼容解決方案:__defineGetter__(屬性名,函數(shù)),__defineSetter__(屬性名,函數(shù))
但是無(wú)法解決對(duì)[[Configurable]]和[[Enumerable]]的修改
Object.defineProperties(對(duì)象,{屬性1:{描述符},屬性2:{}...})
支持:IE9+(IE8部分實(shí)現(xiàn)),Firefox4+,Safari5+,Opera 12+和Chrome
Object.getOwnPropertyDescriptor(對(duì)象,屬性名)
返回:對(duì)象(訪問(wèn)器/格式)
可以對(duì)JS中任何對(duì)象,包括BOM,DOM使用.
工廠模式
構(gòu)造函數(shù)模式
原型模式 - 引申出原型對(duì)象的理解
組合模式 解決原型模式問(wèn)題
動(dòng)態(tài)原型模式
寄生構(gòu)造函數(shù)模式
穩(wěn)妥構(gòu)造函數(shù)模式
工廠模式缺點(diǎn):未解決識(shí)別問(wèn)題(怎么知道一個(gè)對(duì)象的類型)
示例:function makePerson(name,age,job){ var o =new Object(); o.name = name; o.age = age; o.job = job; o.arr = ["a","b"]; o.sayName = function(){ alert(this.name); } return o; } var a = makePerson("jack",18,"programmer"); var b = makePerson("james",20,"designer"); a.arr.push("c"); console.log("a:"+a.arr); //a:a,b,c console.log("b:"+b.arr); //b:a,b console.log(a instanceof makePerson);//false console.log(b instanceof makePerson);//false console.log(a.prototype); //undefined console.log(b.prototype); //undefined console.log(a.prototype); //undefined console.log(b.prototype); //undefined構(gòu)造函數(shù)模式
應(yīng)該值得注意的是構(gòu)造函數(shù)我們是大寫字母開(kāi)頭,這是約定俗成的.創(chuàng)建一個(gè)Person示例我們會(huì)有如下步驟.
創(chuàng)建一個(gè)新對(duì)象
將構(gòu)造函數(shù)作用域賦給新對(duì)象(this指向)
執(zhí)行構(gòu)造函數(shù)中的代碼(為新對(duì)象添加屬性)
返回新對(duì)象
而instanceof操作符和constructor屬性都能讓我們分辨出這是一種特定的類型,這也是構(gòu)造函數(shù)模式勝過(guò)工廠模式的地方.
如果直接作為普通函數(shù)調(diào)用,則會(huì)將屬性賦值給window對(duì)象(Global)
問(wèn)題:函數(shù)不復(fù)用問(wèn)題,實(shí)例中的方法不是同一個(gè)Function的實(shí)例,鑒定方法.
console.log(a.sayName == b.sayName)
解決:放到全局定義,構(gòu)造函數(shù)中設(shè)置即可
導(dǎo)致新問(wèn)題:毫無(wú)封裝性,而為了解決這些問(wèn)題,我們可以使用后續(xù)的原型模式來(lái)解決.
注!所有對(duì)象都繼承自Object,所以a,b使用instanceof操作符判斷是否為Object的實(shí)例是true.
示例:function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.arr = ["a","b"]; this.sayName = function(){ alert(this.name); }; } var a = new Person("jack",18,"programmer"); var b = new Person("james",20,"designer"); a.arr.push("c"); console.log("a:"+a.arr); //a:a,b,c console.log("b:"+b.arr); //b:a,b console.log(a instanceof Person);//true console.log(b instanceof Person);//true console.log(a.prototype); //undefined console.log(b.prototype); //undefined console.log(a.constructor); //[Function: Person] console.log(b.constructor); //[Function: Person]原型模式
每一個(gè)function都有一個(gè)prototype(原型)屬性,為一個(gè)指針,指向一個(gè)對(duì)象(用途:包含可以由特定類型的所有實(shí)例共享的屬性和方法).
通過(guò)prototype設(shè)置的屬性和方法都是共享的,接下來(lái)讓我們理解一下原型對(duì)象.
理解原型對(duì)象在任何時(shí)候,我們創(chuàng)建一個(gè)新函數(shù)都意味著我們會(huì)根據(jù)一個(gè)特定規(guī)則創(chuàng)建prototype屬性,該屬性指向函數(shù)的原型對(duì)象.
在默認(rèn)情況下,所有原型對(duì)象都會(huì)自動(dòng)獲得一個(gè)constructor(構(gòu)造函數(shù))屬性,這個(gè)屬性包含一個(gè)指向prototype屬性所在函數(shù)的指針.
調(diào)用構(gòu)造函數(shù)創(chuàng)建一個(gè)實(shí)例后,實(shí)例內(nèi)部包含一個(gè)指針[[Prototype]] (Firefox,Safari,Chrome訪問(wèn)使用__proto__),
對(duì)于判斷可以使用Person.prototype.isPrototypeOf(a)函數(shù).Person的prototype為a的prototype
Object.getPrototypeOf可以訪問(wèn)[[Prototype]]的值.
值得注意的是,我們可以通過(guò)對(duì)象實(shí)例來(lái)訪問(wèn)保存在原型的值,但是我們不能通過(guò)對(duì)象實(shí)例重寫原型的值(對(duì)象.屬性 = 值,這樣是添加屬性到實(shí)例,覆蓋屏蔽了原型的值而已,并沒(méi)有重寫,但是對(duì)于引用類型不同,即使設(shè)置對(duì)象.屬性=null也是不會(huì)恢復(fù)其指向,只是在實(shí)例中寫入屬性.對(duì)象為null而已,要想恢復(fù),可以使用delete操作符)
原型與in操作符方式一:for-in循環(huán)中使用
方式二:多帶帶使用,會(huì)在能訪問(wèn)(不管通過(guò)對(duì)象還是原型)給定屬性時(shí)返回true(所有能通過(guò)對(duì)象訪問(wèn),可枚舉的屬性)
所有開(kāi)發(fā)人員定義的屬性都是可枚舉的(IE8以及更早例外,其中屏蔽的不可枚舉屬性的實(shí)例屬性不會(huì)出現(xiàn)在for-in循環(huán)中)
相關(guān)函數(shù):
a.hasOwnProperty(屬性名),可以確定屬性是否存在于實(shí)例中,是則返回true
var keys = Object.keys(Person.prototype)
變量中保存一個(gè)數(shù)組,Object.keys返回的是一個(gè)包含所有可枚舉屬性的字符串?dāng)?shù)組.
Object.getWenPropertyNames()可以獲取所有實(shí)例屬性(無(wú)論是否可枚舉)
Person.prototype = { name : "Nicholas", age: 29, job: "software engineer", sayName:fuinction(){ alert("this.name"); } }
在上面代碼中,我們相當(dāng)于完全重寫了prototype對(duì)象,同時(shí)其constructor不再指向Person(指向Object構(gòu)造函數(shù)),盡管instanceof操作符能返回正確結(jié)果,但是constructor已經(jīng)無(wú)法確定對(duì)象類型了.當(dāng)然我們可以自己在新建對(duì)象時(shí)候設(shè)置constructor: Person,但是這樣做會(huì)導(dǎo)致它變?yōu)?strong>可枚舉屬性(原生不可枚舉,解決方法:Object.defineProperty()).
原型的動(dòng)態(tài)性使用上述原型語(yǔ)法,會(huì)切斷構(gòu)造函數(shù)與最初原型的聯(lián)系.
如var friend = new Person()出現(xiàn)在完全重寫之前,則我們無(wú)法通過(guò)friend訪問(wèn)重寫的原型.
function Person(){ } var friend = new Person(); Person.prototype = { constructor: Person, name: "Jack", age: 29, job: "programmer", sayName:function(){ console.log(this.name); } } console.log(friend.age); // undefined friend.sayName(); //報(bào)錯(cuò)
friend中的[[Prototype]]指向的仍然是原來(lái)的空無(wú)一物的Prototype,而不是我們后來(lái)重寫的原型對(duì)象.
原生對(duì)象的原型原生引用類型(Object,Array,String等)都采用原型模式創(chuàng)建
注!不推薦修改原生對(duì)象的原型,可能導(dǎo)致命名沖突/重寫原生方法.
共享引用類型值的屬性,如Array,修改則會(huì)共享
示例:function Person(){ } Person.prototype.name = "Jack"; Person.prototype.age = 18; Person.prototype.job = "Software Engineer"; Person.prototype.arr = ["a","b"];//引用類型 Person.prototype.sayName = function(){ console.log(this.name); } var a = new Person(); a.sayName(); //Jack var b = new Person(); b.name = "James";//創(chuàng)建值,屏蔽了原型的值 console.log(b.age);//18 console.log(b);//Person { name: "James" } b.sayName();//James console.log(a.sayName == b.sayName);//true a.arr.push("c");//修改引用類型 console.log("a:"+a.arr); //a:a,b,c console.log("b:"+b.arr); //b:a,b,c console.log(a instanceof Person);//true console.log(b instanceof Person);//true console.log(a.prototype); //undefined console.log(b.prototype); //undefined console.log(a.constructor); //[Function: Person] console.log(b.constructor); //[Function: Person]組合使用構(gòu)造函數(shù)模式和原型模式
解決原型模式的問(wèn)題-共享引用類型值的屬性
其中特點(diǎn)在于,實(shí)例屬性在構(gòu)造函數(shù)中定義,共享的constructor與方法在原型中定義,如下.
目前來(lái)說(shuō)最廣泛,認(rèn)同度最高的一種方式來(lái)創(chuàng)建自定義類型.
示例:function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.friends = ["a", "b"]; } Person.prototype = { constructor:Person, sayName:function(){ console.log(this.name); } } var a = new Person("jack",18,"programmer"); var b = new Person("james",20,"designer"); a.friends.push("c"); console.log(a.friends);//a,b,c console.log(b.friends);//a,b console.log(a.friends === b.friends); //false console.log(a.sayName === b.sayName); //true動(dòng)態(tài)原型模式
在構(gòu)造函數(shù)中,if檢查初始化后應(yīng)存在的任何屬性或方法.從而對(duì)構(gòu)造函數(shù)和原型方法進(jìn)行封裝.
示例:function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.friends = ["a","b"]; //注意不要使用對(duì)象字面量重寫原型 if(typeof this.sayName != "function"){ Person.prototype.sayName = function(){ alert(this.name); }; } } var a = new Person("jack",18,"programmer"); var b = new Person("james",20,"designer"); a.friends.push("c"); console.log(a.friends);//a,b,c console.log(b.friends);//a,b console.log(a.friends === b.friends);//false console.log(a.sayName === b.sayName);//true console.log(a instanceof Person);//true console.log(b instanceof Person);//true寄生構(gòu)造函數(shù)模式(不推薦
相當(dāng)于工廠模式,通常用于在特殊情況下為對(duì)象創(chuàng)建構(gòu)造函數(shù),如我們要?jiǎng)?chuàng)建一個(gè)具有額外方法的特殊數(shù)組,又不能直接修改Array構(gòu)造函數(shù),就可以使用該模式.
注!返回對(duì)象和構(gòu)造函數(shù)外部創(chuàng)建對(duì)象沒(méi)有不同,所以無(wú)法確定對(duì)象類型.不推薦使用
function SpecialArray(){ var values = new Array(); //添加值 values.push.apply(values,arguments); //添加方法 values.toPipedString = function(){ return this.join("|"); }; return values; }穩(wěn)妥構(gòu)造函數(shù)模式(不推薦
穩(wěn)妥對(duì)象:沒(méi)有公共屬性,方法都不引用this的對(duì)象
和寄生構(gòu)造函數(shù)模式的相似點(diǎn):
創(chuàng)建對(duì)象實(shí)例不引用this
不使用new操作符調(diào)用構(gòu)造函數(shù)
instanceof無(wú)效
注意,穩(wěn)妥對(duì)象中,除了定義的方法之外沒(méi)有其他方法訪問(wèn)某值.
注!和寄生構(gòu)造函數(shù)模式一樣,不推薦使用
function Person(name,age,job){ var o = new Object(); o.sayName = function(){ alert(name); }; return 0; } var friend =Person("Jack",18,"Software Enginner"); friend.sayName();繼承
在ECMAScript中支持的是實(shí)現(xiàn)繼承,并且其實(shí)現(xiàn)繼承主要依靠原型鏈實(shí)現(xiàn),所以明白原型鏈就很重要了.
原型鏈
借用構(gòu)造函數(shù)
組合繼承
原型式繼承
寄生式繼承
寄生組合式繼承
原型鏈基本思想:利用原型鏈讓一個(gè)引用類型繼承另一個(gè)引用類型的屬性和方法.
注!和我們之前提到的一樣,所有函數(shù)的默認(rèn)原型都是Object的實(shí)例.內(nèi)部指針->Object.prototype
instanceof操作符,可以測(cè)試實(shí)例與原型鏈中的構(gòu)造函數(shù).
isPrototypeOf()方法 ,與instanceof操作符返回效果相同.
子類重寫超類/父類中某個(gè)方法,或者添加父類/超類不存在的某個(gè)方法時(shí),要放在替換原型語(yǔ)句后.
注!不要使用對(duì)象字面量創(chuàng)建原型方法,這會(huì)重寫原型鏈
引用類型問(wèn)題
創(chuàng)建子類型實(shí)例時(shí)不能(或者說(shuō)沒(méi)辦法在不影響所有對(duì)象實(shí)例的情況下)向超類型的構(gòu)造函數(shù)傳遞參數(shù).
根據(jù)上述問(wèn)題,實(shí)踐中很少多帶帶使用原型鏈.
示例:function SuperType(){//父類/超類 this.property = true; } SuperType.prototype.getSuperValue = function(){ return this.property; }; function SubType(){//子類 this.subproperty = false; } SubType.prototype = new SuperType(); SubType.prototype.getSubValue = function(){ return this.subproperty; } // 謹(jǐn)慎定義方法 //SubType.prototype.getSuperValue=function(){ // return false; //}該方法會(huì)屏蔽原來(lái)的方法,即通過(guò)SuperType的實(shí)例調(diào)用getSuperValue時(shí)依然調(diào)用原來(lái)的方法,而通過(guò)SubType的實(shí)例調(diào)用時(shí),會(huì)執(zhí)行這個(gè)重新定義的方法.必須在SubType.prototype = new SuperType();之后,再定義getSubValue和該方法. var a = new SubType(); console.log(a.getSubValue());//false console.log(a.getSuperValue());//true //原型與實(shí)例的關(guān)系 console.log(a instanceof Object);//true console.log(a instanceof SuperType);//true console.log(a instanceof SubType);//true借用構(gòu)造函數(shù)
偽造對(duì)象/經(jīng)典繼承.
目的:解決引用類型問(wèn)題->借用構(gòu)造函數(shù)(constructor stealing)
基本思想:子類型構(gòu)造函數(shù)內(nèi)部調(diào)用超類/父類構(gòu)造函數(shù)
缺點(diǎn):無(wú)法避免構(gòu)造函數(shù)模式存在的問(wèn)題(函數(shù)無(wú)法復(fù)用)
所以該方式很少多帶帶使用.
function SuperType(name){ this.name = name; this.arr = ["a","b","c"]; } function SubType(){ SuperType.call(this,"jack");//傳遞參數(shù) this.age = 18;//實(shí)例屬性 } var a = new SubType(); a.arr.push("d"); var b = new SubType(); console.log(a.arr);//a,b,c,d console.log(b.arr);//a,b,c組合繼承
combination inheritance
也稱偽經(jīng)典繼承,將原型鏈和借用構(gòu)造函數(shù)技術(shù)結(jié)合一起的繼承模式.
基本思想:使用原型鏈實(shí)現(xiàn)對(duì)原型屬性和方法的繼承,借用構(gòu)造函數(shù)實(shí)現(xiàn)對(duì)實(shí)例屬性的繼承.constructor重指向
相當(dāng)于:屬性繼承(借用構(gòu)造函數(shù)),函數(shù)外定義方法,constructor重新指向
組合繼承避免了原型鏈和借用構(gòu)造函數(shù)的缺陷,融合了優(yōu)點(diǎn),成為了JS中最常用的繼承模式,而且instanceof和isPrototypeOf()都能夠識(shí)別
示例:function SuperType(name){ this.name = name; this.arr = ["a","b"]; } SuperType.prototype.sayName =function(){ console.log(this.name); }; function SubType(name,age){ SuperType.call(this,name); this.age = age; } //inherit SubType.prototype = new SuperType(); SubType.prototype.constructor = SubType; SubType.prototype.sayAge = function(){ console.log(this.age); }; var a = new SubType("Jack",18); a.arr.push("c"); console.log(a.arr);//a,b,c a.sayName();//Jack a.sayAge();//18 var b = new SubType("James",20); console.log(b.arr);//a,b b.sayName();//James b.sayAge();//20原型式繼承
Prototypal inheritance
將傳入的對(duì)象作為函數(shù)內(nèi)定義的構(gòu)造函數(shù)的原型(要求必須有一個(gè)對(duì)象可以作為另一個(gè)對(duì)象的基礎(chǔ)),在ECMAScript5中新增Object.create()方法規(guī)范了原型式繼承,它接收兩個(gè)參數(shù),一個(gè)用作新對(duì)象原型的對(duì)象和(可選)一個(gè)為新對(duì)象定義額外屬性的對(duì)象.
單個(gè)參數(shù)情況下Object.create()和Object()行為相同
兼容性:IE9+,Firefox4+,Safari5+,Opera12+,Chrome
缺點(diǎn):和原型模式一樣,引用類型共享.
function object(o){ function F(){}; F.prototype = o; return new F(); } var person = { name: "Jack", arr: ["a","b"] }; var a = object(person); var b = object(person); a.name = "James"; a.arr.push("c"); b.name = "Ansem"; b.arr.push("d"); console.log(person.arr);//a,b,c,d console.log(a.arr);//a,b,c,d console.log(b.arr);//a,b,c,d //Object.create var person2 = { name: "Jack", arr: ["a","b"] }; var c = Object.create(person2,{ name:{ value: "James" } }); var d = Object.create(person2,{ name:{ value: "Ansem" } }); c.arr.push("c"); d.arr.push("d"); console.log(c.name);//James console.log(d.name);//Ansem console.log(person.arr);//a,b,c,d console.log(c.arr);//a,b,c,d console.log(d.arr);//a,b,c,d寄生式繼承
parasitic inherit
思路與寄生構(gòu)造函數(shù)和工廠模式類似,創(chuàng)建新對(duì)象,增強(qiáng)對(duì)象,返回對(duì)象.
缺點(diǎn):函數(shù)復(fù)用不了,對(duì)于引用類型為共享.
function createAnother(original){ var clone = object(original); clone.sayHi = function(){ console.log("HI"); }; return clone; }寄生組合式繼承(重點(diǎn))
組合繼承的問(wèn)題:無(wú)論什么情況都會(huì)兩次調(diào)用超類型構(gòu)造函數(shù)
第一次:SubType.prototype = new SuperType()時(shí)
第二次:new SuperType()內(nèi)->SuperType.call(this,name);
這造成的結(jié)果是,第一次時(shí):SuperType的實(shí)例(SubType的原型)初始化屬性.第二次時(shí):新對(duì)象上又新創(chuàng)建了相同的屬性,于是這兩個(gè)屬性就屏蔽了原型中兩個(gè)同名屬性.
解決方法就是寄生組合式繼承.通過(guò)借用構(gòu)造函數(shù)來(lái)繼承屬性,通過(guò)原型鏈的混成形式來(lái)繼承方式.
基本思路:不必為了指定子類型的原型而調(diào)用超類/父類的構(gòu)造函數(shù),我們需要的知識(shí)超類/父類原型的一個(gè)副本.在這點(diǎn)上使用寄生式繼承來(lái)繼承超類/父類的原型,再將結(jié)果指定給子類的原型.
高效率體現(xiàn)在避免了創(chuàng)建多余不必要的屬性,原型鏈還能保持不變.instanceof和isPrototypeOf()都能正常使用.
可以說(shuō)寄生組合式繼承是引用類型最理想的繼承范式,這也被YUI庫(kù)所采用.
示例://基本模式 function inheritPrototype(subType,superType){ var prototype = Object(superType.prototype); prototype.constructor = subType; subType.prototype = prototype; } function SuperType(name){ this.name = name; this.arr = ["a","b"]; } SuperType.prototype.sayName =function(){ console.log(this.name); }; function SubType(name,age){ SuperType.call(this,name); this.age = age; }; inheritPrototype(SubType,SuperType);//避免了多次執(zhí)行,提高了效率 SubType.prototype.sayAge = function(){ console.log(this.age); }; var c = new SubType("Jack",18); var d = new SubType("Ansem",25); c.arr.push("c"); d.arr.push("d"); console.log(c.name);//Jack console.log(d.name);//Ansem console.log(c.arr);//a,b,c console.log(d.arr);//a,b,d
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/80455.html
摘要:高程讀書(shū)筆記第六章理解對(duì)象創(chuàng)建自定義對(duì)象的方式有創(chuàng)建一個(gè)實(shí)例,然后為它添加屬性和方法。創(chuàng)建了自定義的構(gòu)造函數(shù)之后,其原型對(duì)象默認(rèn)只會(huì)取得屬性至于其他方法都是從繼承而來(lái)的。 JS高程讀書(shū)筆記--第六章 理解對(duì)象 創(chuàng)建自定義對(duì)象的方式有創(chuàng)建一個(gè)Object實(shí)例,然后為它添加屬性和方法。還可用創(chuàng)建對(duì)象字面量的方式 屬性類型 ECMAScript在定義只有內(nèi)部采用的特性時(shí),描述了屬性的各種特征...
摘要:創(chuàng)建一個(gè)新對(duì)象將構(gòu)造函數(shù)的作用域賦給新對(duì)象因此就指向了這個(gè)新對(duì)象執(zhí)行構(gòu)造函數(shù)中的代碼為這個(gè)新對(duì)象添加屬性返回新對(duì)象。 本章內(nèi)容 理解對(duì)象屬性 理解并創(chuàng)建對(duì)象 理解繼承 ECMA-262把對(duì)象定義為:無(wú)序?qū)傩缘募?,其屬性可以包含基本值、?duì)象或者函數(shù) 理解對(duì)象 創(chuàng)建對(duì)象 創(chuàng)建自定義對(duì)象的最簡(jiǎn)單方式就是創(chuàng)建一個(gè)Object的實(shí)例,再為它添加屬性和方法。 var person = new...
摘要:對(duì)于采用這種模式的對(duì)象,還可以使用操作符確定它的類型寄生構(gòu)造函數(shù)模式通常,在前述的幾種模式都不適用的情況下,可以使用寄生構(gòu)造函數(shù)模式。這個(gè)模式可以在特殊的情況下用來(lái)為對(duì)象創(chuàng)建構(gòu)造函數(shù)。 ECMA-262把對(duì)象定義為:無(wú)序?qū)傩缘募?,其屬性可以包含基本值、?duì)象或者函數(shù)。嚴(yán)格來(lái)講,這就相當(dāng)于說(shuō)對(duì)象是一組沒(méi)有特定順序的值。 1 理解對(duì)象 創(chuàng)建對(duì)象: var person = new Obje...
摘要:繼承的是超類型中構(gòu)造函數(shù)中的屬性,如上繼承了屬性,但沒(méi)有繼承原型中的方法。上述造成的結(jié)果是子類型實(shí)例中有兩組超類型的構(gòu)造函數(shù)中定義的屬性,一組在子類型的實(shí)例中,一組在子類型實(shí)例的原型中。 ECMAScript只支持實(shí)現(xiàn)繼承,主要依靠原型鏈來(lái)實(shí)現(xiàn)。與實(shí)現(xiàn)繼承對(duì)應(yīng)的是接口繼承,由于script中函數(shù)沒(méi)有簽名,所以無(wú)法實(shí)現(xiàn)接口繼承。 一、原型鏈 基本思想:利用原型讓一個(gè)引用類型繼承另一個(gè)引用...
摘要:把原型修改為另外一個(gè)對(duì)象就等于切斷了構(gòu)造函數(shù)與最初原型之間的聯(lián)系。組合使用構(gòu)造函數(shù)模式動(dòng)態(tài)原型模式通過(guò)檢查某個(gè)應(yīng)該存在的方法是否有效,來(lái)決定是否需要初始化原型。 理解對(duì)象 屬性類型 數(shù)據(jù)屬性 數(shù)據(jù)屬性包含一個(gè)數(shù)據(jù)值的位置。在這個(gè)位置可以讀取和寫入值。數(shù)據(jù)屬性有 4 個(gè)描述其行為的特性。 [[Configurable]] :表示能否通過(guò) delete 刪除屬性從而重新定義屬性,能否修...
閱讀 1417·2021-11-24 09:39
閱讀 3698·2021-11-24 09:39
閱讀 1883·2021-11-16 11:54
閱讀 1473·2021-09-30 09:47
閱讀 1728·2021-09-26 10:16
閱讀 2355·2021-09-22 15:33
閱讀 1466·2021-09-14 18:01
閱讀 2453·2021-09-07 09:59