摘要:構(gòu)造函數(shù)與原型組合利用構(gòu)造函數(shù)都是實(shí)例屬性和原型的共享特性,分別定義對(duì)應(yīng)的內(nèi)容,組合共同完成對(duì)象創(chuàng)建,而且該模式還支持想構(gòu)造函數(shù)傳遞參數(shù)。引用類(lèi)型為實(shí)例屬性寄生構(gòu)造模式構(gòu)造函數(shù)在不反回值的情況下,默認(rèn)會(huì)返回新對(duì)象實(shí)例。
創(chuàng)建對(duì)象 1.1 通過(guò)Object對(duì)象創(chuàng)建
var person = new Object(); person.name = "Albert"; person.sayName = function(){ console.log(this.name); };1.2 通過(guò)字面量創(chuàng)建
var person = { name : "Albert", sayName : function(){ console.log(this.name) } };Object和字面量創(chuàng)建的問(wèn)題:
創(chuàng)建很多對(duì)象的時(shí)候會(huì)產(chǎn)生大量重復(fù)代碼。
1.3 工廠模式function createPerson(name){ var o = new Object(); o.name = name; o.sayName = function(){ console.log(this.name) } return o; } var person = createPerson("Albert");工廠模式的問(wèn)題:
無(wú)法識(shí)別對(duì)象類(lèi)型,即無(wú)法通過(guò)instanceof和constructor來(lái)識(shí)別對(duì)象類(lèi)型:
person instanceof ???; person.constructor == ???;1.4 構(gòu)造函數(shù)
function Person(name){ this.name = name; this.sayName = function(){ console.log(this.name) } } var person = new Person("Albert"); console.log(person.constructor == Person)//true console.log(person instanceof Person)//true構(gòu)造函數(shù)的問(wèn)題:
每個(gè)方法都要在每個(gè)實(shí)例上重新創(chuàng)建一次,尤其是函數(shù),這樣每個(gè)Person的實(shí)例都包含了一個(gè)不同的sayName的函數(shù)實(shí)例。
注意1
構(gòu)造函數(shù)沒(méi)有return語(yǔ)句。要?jiǎng)?chuàng)建Person的新實(shí)例,必須采用new操作符,new操作符大體上完成了一下4件事情:
創(chuàng)建一個(gè)新的對(duì)象(本例中Person創(chuàng)建的新對(duì)象,記為person);
將構(gòu)造函數(shù)的作用域賦給新對(duì)象(this=>person);
執(zhí)行構(gòu)造函數(shù)中的代碼(Person中的this.name=name;this.say.....);
返回新對(duì)象
注意2
構(gòu)造函數(shù)也是函數(shù),如果不通過(guò)new操作符調(diào)用,則作用環(huán)境為全局(瀏覽器中為windows,node環(huán)境中為global)
function Person(name){ this.name = name; this.sayName = function(){ console.log(this.name) } } Person("BB"); global.sayName()//BB console.log(global.name)//BB1.5 原型模式
function Person(name){} Person.prototype.name = "Albert"; Person.prototype.sayName = function(){ console.log(this.name) } var person = new Person(); console.log(Object.getPrototypeOf(person)==Person.prototype);//true
瀏覽器支持:IE9+,這樣所有的Person實(shí)例共享name屬性及sayName函數(shù)
注意1
對(duì)象的某個(gè)屬性是否來(lái)自實(shí)例,可通過(guò)hasOwnProperty()來(lái)確定,如果是在原型中,則返回false。
判斷對(duì)象是否具備屬性,可以通過(guò)in操作符,例如console.log("name" in person)//true來(lái)判斷,不論是在原型還是實(shí)例中,都返回true,通過(guò)for-in循環(huán)時(shí),實(shí)例及原型中均會(huì)被枚舉。
注意2
在定義原型時(shí),如果用字面量代替為prototype屬性定義,則原型的constructor屬性不會(huì)指向Person。因?yàn)橥ㄟ^(guò)字面量定義,完全重寫(xiě)了默認(rèn)的prototype對(duì)象。但是此時(shí)instanceof還是能夠返回正確的結(jié)果。
function Person(name){}; Person.prototype={ name : "Albert", sayName : function(){ console.log(this.name); } }; var person = new Person(); console.log(person instanceof Person);//true console.log(person.constructor == Person);//false console.log(person.constructor == Object);//true
所以可以再補(bǔ)充定義:
Object.defineProperty(Person.prototype,"constructor",{ enumerable:false, value:Person })
注意3
在重定義原型前,不能創(chuàng)建對(duì)象實(shí)例,否則會(huì)造成實(shí)例的原型指向錯(cuò)誤
function Person(name){}; var person = new Person(); Person.prototype={ name : "Albert", sayName : function(){ console.log(this.name); } }; person.sayName(); //error
此例中person的原型被指向了Person的默認(rèn)原型,固調(diào)用sayName函數(shù)會(huì)發(fā)生錯(cuò)誤。
原型模式的問(wèn)題:小問(wèn)題:為了省略構(gòu)造函數(shù)傳遞初始化參數(shù),所有的實(shí)例在默認(rèn)情況下都會(huì)去的想通的屬性值
原型屬性被所有實(shí)例共享(適合function類(lèi)型的值),而通常情況下,引用類(lèi)型(Array、Object)屬性值一般不希望對(duì)所有實(shí)例共享。
1.6 構(gòu)造函數(shù)與原型組合利用構(gòu)造函數(shù)都是實(shí)例屬性和原型的共享特性,分別定義對(duì)應(yīng)的內(nèi)容,組合共同完成對(duì)象創(chuàng)建,而且該模式還支持想構(gòu)造函數(shù)傳遞參數(shù)。
function Person(name){ this.name = name; this.friends = ["Bob","Harry"];//引用類(lèi)型為實(shí)例屬性 }; Person.prototype.sayName = function(){ console.log(this.name); };1.7 動(dòng)態(tài)原型模式
將1.6中的組合封裝在一個(gè)構(gòu)造函數(shù)中的模式。具體方法為:檢查某個(gè)應(yīng)該存在的方法是否有效來(lái)決定是否需要初始化原型。
function Person(name){ this.name = name; this.friends = ["Bob","Harry"];//引用類(lèi)型為實(shí)例屬性 //****ProtoType**** if(typeof this.sayName != "function"){ Person.prototype.sayName = function(){ console.log(this.name); }; } };1.8 寄生構(gòu)造模式
構(gòu)造函數(shù)在不反回值的情況下,默認(rèn)會(huì)返回新對(duì)象實(shí)例。
而通過(guò)在函數(shù)末尾添加return語(yǔ)句,可以重寫(xiě)new后調(diào)用函數(shù)時(shí)的返回值。
function Person(name){ var o = new Object(); o.name = name; o.sayName = function(){ console.log(this.name); }; return o; }; var person = new Person("Albert"); console.log(person instanceof Person);//false
該函數(shù)除了使用new操作符和把包裝函數(shù)取名叫“構(gòu)造函數(shù)”以外,和工廠模式其實(shí)是一模一樣的。
該模式屬于比較特殊的構(gòu)造模式,可用于不允許修改原對(duì)象的情況。
function SpecialArray(){ var values = new Array(); values.push.apply(values,arguments); values.toPipedString = function(){ return this.join("|"); }; return values }1.9 穩(wěn)妥(durable)構(gòu)造函數(shù)模式
該模式構(gòu)造出來(lái)的對(duì)象沒(méi)有公共屬性,不適用this對(duì)象,不適用new操作符,適用于在一些安全環(huán)境中,可防止數(shù)據(jù)被其它應(yīng)用(如Mashup)改動(dòng)(利用閉包特性),類(lèi)似于寄生構(gòu)造函數(shù)模式,單不適用this和new。
function Person(name){ var o = new Object(); //****定義私有變量和函數(shù)**** var _name = name; o.sayName = function(){ console.log(_name); }; return o; }; var person = Person("Albert");
這種模式中,除了sayName()方法以外,沒(méi)有其它辦法訪問(wèn)_name的值。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/86914.html
摘要:對(duì)象的分類(lèi)內(nèi)置對(duì)象原生對(duì)象就是語(yǔ)言預(yù)定義的對(duì)象,在標(biāo)準(zhǔn)定義,有解釋器引擎提供具體實(shí)現(xiàn)宿主對(duì)象指的是運(yùn)行環(huán)境提供的對(duì)象。不過(guò)類(lèi)型是中所有類(lèi)型的父級(jí)所有類(lèi)型的對(duì)象都可以使用的屬性和方法,可以通過(guò)的構(gòu)造函數(shù)來(lái)創(chuàng)建自定義對(duì)象。 對(duì)象 javaScript中的對(duì)象,和其它編程語(yǔ)言中的對(duì)象一樣,可以比照現(xiàn)實(shí)生活中的對(duì)象來(lái)理解。在JavaScript中,一個(gè)對(duì)象可以是一個(gè)單獨(dú)擁有屬性和類(lèi)型的實(shí)體。和...
摘要:對(duì)象對(duì)象是什么中的對(duì)象和其他編程語(yǔ)言中的對(duì)象一樣可以比照現(xiàn)實(shí)上活中的對(duì)象來(lái)理解它中對(duì)象的概念可以比照現(xiàn)實(shí)生活中實(shí)實(shí)在在的物體來(lái)理解在中一個(gè)對(duì)象可以是一個(gè)單獨(dú)的擁有屬性和類(lèi)型的實(shí)體拿它和一個(gè)杯子做下類(lèi)比一個(gè)杯子是一個(gè)對(duì)象擁有屬性杯子有顏色圖案 對(duì)象 對(duì)象是什么 JavaScript中的對(duì)象 和其他編程語(yǔ)言中的對(duì)象一樣 可以比照現(xiàn)實(shí)上活中的對(duì)象來(lái)理解它JavaScript中對(duì)象的概念可以比...
摘要:張無(wú)忌對(duì)象的屬性存在對(duì)象的屬性不存在使用進(jìn)行判斷。張無(wú)忌對(duì)象的屬性存在請(qǐng)先定義對(duì)象的屬性使用語(yǔ)句進(jìn)行判斷張無(wú)忌對(duì)象的屬性存在刪除對(duì)象的屬性可以用操作符刪除一個(gè)不是繼承而來(lái)的屬性。 對(duì)象 對(duì)象的概述 對(duì)象是什么 JavaScript中的對(duì)象,和其他編程語(yǔ)言中的對(duì)象一樣。可以對(duì)比現(xiàn)實(shí)生活中的一些東西來(lái)理解他。在JavaScript中,一個(gè)對(duì)象可以使一個(gè)單純的擁有屬性和類(lèi)型的實(shí)體。假如和一個(gè)...
摘要:屬性名可以是包含空字符串在內(nèi)的任意字符串,但對(duì)象中不能存在兩個(gè)同名的屬性。客戶端中表示網(wǎng)頁(yè)結(jié)構(gòu)的對(duì)象均是宿主對(duì)象。這里的函數(shù)稱做構(gòu)造函數(shù),構(gòu)造函數(shù)用以初始化一個(gè)新創(chuàng)建的對(duì)象。通過(guò)關(guān)鍵字和構(gòu)造函數(shù)調(diào)用創(chuàng)建的對(duì)象的原型就是構(gòu)造函數(shù)的屬性的值。 對(duì)象是 JavaScript 的數(shù)據(jù)類(lèi)型。它將很多值(原始值或者其他對(duì)象)聚合在一起,可通過(guò)名字訪問(wèn)這些值,因此我們可以把它看成是從字符串到值的映射...
摘要:都是構(gòu)造函數(shù)模式創(chuàng)建的原生構(gòu)造函數(shù)。使用構(gòu)造函數(shù)創(chuàng)建對(duì)象經(jīng)歷了以下四個(gè)過(guò)程創(chuàng)建一個(gè)新對(duì)象構(gòu)造函數(shù)的作用域交給新對(duì)象。 ??在創(chuàng)建對(duì)象的時(shí)候,使用對(duì)象字面量和 new Object() 構(gòu)造函數(shù)的方式創(chuàng)建一個(gè)對(duì)象是最簡(jiǎn)單最方便的方式。但是凡是處于初級(jí)階段的事物都會(huì)不可避免的存在一個(gè)問(wèn)題,沒(méi)有普適性,意思就是說(shuō)我要為世界上(程序中)的所有使用到的對(duì)象都使用一遍 var xxx = {} ,...
摘要:都是構(gòu)造函數(shù)模式創(chuàng)建的原生構(gòu)造函數(shù)。使用構(gòu)造函數(shù)創(chuàng)建對(duì)象經(jīng)歷了以下四個(gè)過(guò)程創(chuàng)建一個(gè)新對(duì)象構(gòu)造函數(shù)的作用域交給新對(duì)象。 ??在創(chuàng)建對(duì)象的時(shí)候,使用對(duì)象字面量和 new Object() 構(gòu)造函數(shù)的方式創(chuàng)建一個(gè)對(duì)象是最簡(jiǎn)單最方便的方式。但是凡是處于初級(jí)階段的事物都會(huì)不可避免的存在一個(gè)問(wèn)題,沒(méi)有普適性,意思就是說(shuō)我要為世界上(程序中)的所有使用到的對(duì)象都使用一遍 var xxx = {} ,...
閱讀 1378·2021-11-24 10:24
閱讀 4417·2021-11-22 15:29
閱讀 1151·2019-08-30 15:53
閱讀 2861·2019-08-30 10:54
閱讀 2051·2019-08-29 17:26
閱讀 1378·2019-08-29 17:08
閱讀 672·2019-08-28 17:55
閱讀 1670·2019-08-26 14:01