av一区二区在线观看_亚洲男人的天堂网站_日韩亚洲视频_在线成人免费_欧美日韩精品免费观看视频_久草视

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

淺談 JS 創(chuàng)建對(duì)象的 8 種模式

瀏覽:150日期:2024-05-24 11:32:41

1.Object 模式

var o1 = {};//字面量的表現(xiàn)形式var o2 = new Object;var o3 = new Object();var o4 = new Object(null);var o5 = new Object(undefined);var o6 = Object.create(Object.prototype);//等價(jià)于 var o = {};//即以 Object.prototype 對(duì)象為一個(gè)原型模板,新建一個(gè)以這個(gè)原型模板為原型的對(duì)象//區(qū)別var o7 = Object.create(null);//創(chuàng)建一個(gè)原型為 null 的對(duì)象

在 chrome 里查看各個(gè)新建對(duì)象的區(qū)別:淺談 JS 創(chuàng)建對(duì)象的 8 種模式

可以看出前6種模式創(chuàng)建出來(lái)的對(duì)象都是一樣的,第七種不同點(diǎn)在于其雖然也為 Object 對(duì)象但其無(wú)任何屬性(包括沒(méi)有任何可以繼承的屬性,因?yàn)閯?chuàng)建的時(shí)候沒(méi)有指定其原型)

2.工廠模式

//工廠方法1 通過(guò)一個(gè)方法來(lái)創(chuàng)建對(duì)象 利用 arguments 對(duì)象獲取參數(shù)設(shè)置屬性(參數(shù)不直觀,容易出現(xiàn)問(wèn)題)function createCar(){ var oTemp = new Object(); oTemp.name = arguments[0];//直接給對(duì)象添加屬性,每個(gè)對(duì)象都有直接的屬性 oTemp.age = arguments[1]; oTemp.showName = function () {alert(this.name); };//每個(gè)對(duì)象都有一個(gè) showName 方法版本 return oTemp;}createCar('tom').showName();//在 JS 中沒(méi)有傳遞的實(shí)參,實(shí)際形參值為 undefined(這里的 age 為 undefined)createCar('tim',80).showName();alert(createCar('tom') instanceof Object);//true 判斷對(duì)象是否 Object 類(lèi)或子類(lèi)

//工廠方法2 通過(guò)傳參設(shè)置屬性(參數(shù)直觀明了)function createCar(name,age){ var oTemp = new Object(); oTemp.name = name;//直接給對(duì)象添加屬性,每個(gè)對(duì)象都有直接的屬性 oTemp.age = age; oTemp.showName = function () {alert(this.name); };//每個(gè)對(duì)象都有一個(gè) showName 方法版本 return oTemp;}createCar('tom').showName();createCar('tim',80).showName();alert(createCar('tom') instanceof Object);//true 判斷對(duì)象是否 Object 類(lèi)或子類(lèi)

3.構(gòu)造器模式

//構(gòu)造器方法1function Car(sColor,iDoors){ //聲明為構(gòu)造器時(shí)需要將函數(shù)名首字母大寫(xiě) this.color = sColor; //構(gòu)造器內(nèi)直接聲明屬性 this.doors = iDoors; this.showColor = function(){return this.color; };//每個(gè) Car 對(duì)象都有自己的 showColor方法版本 this.showDoor = function () {return this.doors; }}

使用方法1的問(wèn)題很明顯,沒(méi)辦法是 showDoor 方法重用,每次新建一個(gè)對(duì)象就要在堆里新開(kāi)辟一篇空間.改進(jìn)如下

//構(gòu)造器方法2function showDoor(){ //定義一個(gè)全局的 Function 對(duì)象 return this.doors;}function Car(sColor,iDoors){//構(gòu)造器 this.color = sColor; //構(gòu)造器內(nèi)直接聲明屬性 this.doors = iDoors; this.showColor = function(){return this.color; }; this.showDoor = showDoor();//每個(gè) Car 對(duì)象共享同一個(gè) showDoor 方法版本(方法有自己的作用域,不用擔(dān)心變量被共享)}alert(new Car('red',2).showColor());//通過(guò)構(gòu)造器創(chuàng)建一個(gè)對(duì)象并調(diào)用其對(duì)象方法

上面出現(xiàn)的問(wèn)題就是語(yǔ)義不夠清除,體現(xiàn)不出類(lèi)的封裝性,改進(jìn)為 prototype 模式

4.通過(guò)Function對(duì)象實(shí)現(xiàn)創(chuàng)建對(duì)象

我們知道每聲明一個(gè)函數(shù)實(shí)際是創(chuàng)建了一個(gè)Function 實(shí)例 JS 函數(shù).

function function_name(param1,param2){alert(param1);}//等價(jià)于var function_name = new Function('param1','pram2','alert(param1);');

var Car2 = new Function('sColor','iDoors', 'this.color = sColor;'+ 'this.doors = iDoors;'+ 'this.showColor = function(){ return this.color; }');alert(new Car2('blue',3).showColor());

5.prototype模式

類(lèi)通過(guò) prototype 屬性添加的屬性與方法都是綁定在這個(gè)類(lèi)的 prototype 域(實(shí)際為一個(gè) Prototype 對(duì)象)中,綁定到這個(gè)域中的屬性與方法只有一個(gè)版本,只會(huì)創(chuàng)建一次.類(lèi)的實(shí)例對(duì)象可以直接像調(diào)用自己的屬性一樣調(diào)用該類(lèi)的 prototype 域中的屬性與方法,類(lèi)可以通過(guò)調(diào)用 prototype 屬性來(lái)間接調(diào)用prototype 域內(nèi)的屬性與方法.注意:通過(guò)類(lèi)實(shí)例化出對(duì)象后對(duì)象內(nèi)無(wú) prototype 屬性,但對(duì)象可直接像訪問(wèn)屬性一樣的訪問(wèn)類(lèi)的 prototype 域的內(nèi)容,實(shí)例對(duì)象有個(gè)私有屬性proto,proto屬性內(nèi)含有類(lèi)的 prototype 域內(nèi)的屬性與方法

方法1function Car3(){}//用空構(gòu)造函數(shù)設(shè)置類(lèi)名Car3.prototype.color = 'blue';//每個(gè)對(duì)象都共享相同屬性Car3.prototype.doors = 3;Car3.prototype.drivers = new Array('Mike','John');Car3.prototype.showColor = function(){ alert(this.color);};//每個(gè)對(duì)象共享一個(gè)方法版本,省內(nèi)存。var car3_1 = new Car3();var car3_2 = new Car3();alert(car3_1.color);//bluealert(car3_2.color);//bluealert(Car3.prototype.color);//bluecar3_1.drivers.push('Bill');alert(car3_1.drivers);//'Mike','John','Bill'alert(car3_2.drivers);//'Mike','John','Bill'alert(Car3.prototype.drivers);//'Mike','John','Bill'//直接修改實(shí)例對(duì)象的屬性,解析器會(huì)先去找實(shí)例對(duì)象是否有這個(gè)屬性(不會(huì)去找實(shí)例對(duì)象的 _proto_ 屬性內(nèi)的那些類(lèi)的 prototype 屬性,而是直接查看這個(gè)實(shí)例是否有對(duì)應(yīng)的屬性(與_proto_同級(jí)))//如果沒(méi)有則直接給這個(gè)實(shí)例對(duì)象添加該屬性,但不會(huì)修改類(lèi)的prototype域的同名屬性,既實(shí)例對(duì)象的_proto_屬性內(nèi)的那些類(lèi) prototype 域?qū)傩圆粫?huì)被修改car3_1.color = 'red';//car3_1對(duì)象內(nèi)無(wú)名為 color 的對(duì)象屬性,故將該屬性添加到該對(duì)象上//解析器對(duì)實(shí)例對(duì)象讀取屬性值的時(shí)候會(huì)先查找該實(shí)例有無(wú)同名的直接屬性//如果沒(méi)有,則查找__proto__屬性內(nèi)保存的那些 當(dāng)前類(lèi)的 prototype 域的屬性//有就返回,無(wú)則繼續(xù)查找是否有原型鏈中的對(duì)應(yīng)的方法屬性//有就返回,無(wú)則返回undefinedalert(car3_1.color);//redalert(car3_2.color);//bluealert(car3_2.color2);//undefined//直接修改類(lèi)的 prototype 域內(nèi)的屬性,不會(huì)影響該類(lèi)的實(shí)例對(duì)象的對(duì)象屬性,但會(huì)影響實(shí)例對(duì)象的_proto_屬性(_proto_屬性內(nèi)存放的是類(lèi)的 prototype 域的內(nèi)容)Car3.prototype.color = 'black';alert(car3_1.color);//red 該對(duì)象有同名的直接屬性,故不會(huì)去_proto_屬性內(nèi)查找類(lèi)的 prototype 域的屬性alert(car3_2.color);//black 受影響//直接修改實(shí)例對(duì)象的方法,解析器會(huì)先去找實(shí)例對(duì)象是否有這個(gè)方法(不會(huì)去找實(shí)例對(duì)象的 _proto_ 屬性內(nèi)的那些類(lèi)的 prototype 域的方法,而是直接查看這個(gè)實(shí)例是否有對(duì)應(yīng)的方法(與_proto_同級(jí)))//如果沒(méi)有則直接給這個(gè)實(shí)例對(duì)象添加該方法,但不會(huì)修改類(lèi)的prototype域的同名方法,既實(shí)例對(duì)象的_proto_屬性內(nèi)的那些類(lèi) prototype 域方法不會(huì)被修改//car3_1對(duì)象內(nèi)無(wú)名為 showColor 的對(duì)象方法屬性,故將該方法屬性添加到該對(duì)象上car3_1.showColor = function () { alert('new function');}//解析器對(duì)實(shí)例對(duì)象調(diào)用方法屬性的時(shí)候會(huì)先查找該實(shí)例有無(wú)同名的直接方法屬性//如果沒(méi)有,則查找_proto_屬性內(nèi)保存的那些 當(dāng)前類(lèi)的 prototype 域的方法屬性//有就返回,無(wú)則繼續(xù)查找是否有原型鏈中的對(duì)應(yīng)的方法屬性//找到就返回,無(wú)則報(bào)錯(cuò)car3_1.showColor();//new functioncar3_2.showColor();//bluecar3_1.abcd();//直接報(bào)錯(cuò)//直接修改類(lèi)的 prototype 域內(nèi)的方法屬性,不會(huì)影響該類(lèi)的實(shí)例對(duì)象的方法屬性,但會(huì)影響實(shí)例對(duì)象的_proto_屬性(_proto_屬性內(nèi)存放的是類(lèi)的 prototype 域的內(nèi)容)Car3.prototype.showColor = function () { alert('second function');}car3_1.showColor();//new function 該對(duì)象有同名的方法屬性,故不會(huì)去_proto_屬性內(nèi)查找類(lèi)的 prototype 域的方法屬性car3_2.showColor();//second function 受影響

可以看出使用該方法雖然說(shuō)打打減少了內(nèi)存的浪費(fèi),但依舊有問(wèn)題,某個(gè)對(duì)象的屬性一旦改變,所有由該類(lèi)實(shí)例化得到的對(duì)象的proto內(nèi)屬性值也會(huì)跟著變(實(shí)為引用),改進(jìn)如下

6.構(gòu)造器方式與原型方式的混合模式

//每個(gè)對(duì)象有專(zhuān)屬的屬性不會(huì)與其他對(duì)象共享function Car4(sColor,iDoors){ this._color = sColor;//私有屬性變量名稱(chēng)頭加下劃線標(biāo)識(shí) this._doors = iDoors; this.drivers = new Array('Mike','John');//公有屬性標(biāo)識(shí)}//所有對(duì)象共享一個(gè)方法版本,減少內(nèi)存浪費(fèi)Car4.prototype.showColor = function () { alert(this._color);};var car4_1 = new Car4('red',4);var car4_2 = new Car4('blue',3);car4_1.drivers.push('Bill');alert(car4_1.drivers);//'Mike','John','Bill'alert(car4_2.drivers);//'Mike','John'

這也是常用的創(chuàng)建對(duì)象方式之一

7.動(dòng)態(tài)原型模式

function Car5(sColor,iDoors,iMpg){ this.color = sColor; this.doors = iDoors; this.mpg = iMpg; this.drivers = new Array('Mike','John'); //使用標(biāo)志(_initialized)來(lái)判斷是否已給原型賦予了任何方法,保證方法永遠(yuǎn)只被創(chuàng)建并賦值一次 if(typeof Car5._initialized == 'undefined'){//因?yàn)檫@里的標(biāo)記是附加在類(lèi)上,故如果后期直接對(duì)其進(jìn)行修改,還是有可能出現(xiàn)再次創(chuàng)建的情況Car5.prototype.showColor = function () {//為Car5添加一個(gè)存放在 prototype 域的方法 alert(this.color);};Car5._initialized = true;//設(shè)置一個(gè)靜態(tài)屬性 }}var car5_1 = new Car5('red',3,25);var car5_2 = new Car5('red',3,25);

這種模式使得定義類(lèi)像強(qiáng)類(lèi)型語(yǔ)言例如 java 等語(yǔ)言的定義模式

8.混合工廠模式

function Car6(){ var oTempCar = new Object; oTempCar.color = 'blue'; oTempCar.doors = 4; oTempCar.showColor = function () {alert(this.color); }; return oTempCar;}var car6 = new Car6();

由于在 Car6()構(gòu)造函數(shù)內(nèi)部調(diào)用了 new 運(yùn)算符,所以將忽略第二個(gè) new 運(yùn)算符(位于構(gòu)造函數(shù)之外),在構(gòu)造函數(shù)內(nèi)部創(chuàng)建的對(duì)象被傳遞回變量car6,這種方式在對(duì)象方法的內(nèi)部管理方面與經(jīng)典方式(工廠方法)有著相同的問(wèn)題.應(yīng)盡量避免

作者:Tomson原文地址:http://segmentfault.com/a/1190000003862596

標(biāo)簽: JavaScript
相關(guān)文章:
主站蜘蛛池模板: 欧美www | 亚洲精品第一页 | 国产探花视频在线观看 | 国产成人午夜高潮毛片 | 少妇视频在线观看 | 黄色片中文字幕 | 日韩香蕉视频 | 久热99 | 午夜视频在线免费观看 | a在线免费观看 | 在线观看91| www.久久久久 | 日韩视频在线播放 | 国产精品欧美激情 | 狠狠干免费视频 | 午夜视频一区 | 九九热在线观看 | 一级片免费在线观看 | 黄色a一级片 | 成人欧美在线 | 人人干人人爽 | 免费特级毛片 | 高潮毛片无遮挡免费看 | 免费的黄色小视频 | 久久夜色精品国产欧美乱极品 | 日本黄色中文字幕 | av片免费看 | 亚洲一二区 | 免费的黄色网 | 久久九九精品 | 久久国产精品一区二区 | 国产精品久久久久久久久久久久午夜片 | 日韩在线视频观看 | 欧美成人精品欧美一级乱黄 | 国产三级在线免费观看 | 国产黄色av网站 | 欧美福利在线观看 | 日韩一级片在线观看 | 欧美黄色一区二区 | 日韩一级免费 | 蜜臀av性久久久久av蜜臀妖精 |