色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

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

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

瀏覽:122日期: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)建出來的對(duì)象都是一樣的,第七種不同點(diǎn)在于其雖然也為 Object 對(duì)象但其無任何屬性(包括沒有任何可以繼承的屬性,因?yàn)閯?chuàng)建的時(shí)候沒有指定其原型)

2.工廠模式

//工廠方法1 通過一個(gè)方法來創(chuàng)建對(duì)象 利用 arguments 對(duì)象獲取參數(shù)設(shè)置屬性(參數(shù)不直觀,容易出現(xià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 中沒有傳遞的實(shí)參,實(shí)際形參值為 undefined(這里的 age 為 undefined)createCar('tim',80).showName();alert(createCar('tom') instanceof Object);//true 判斷對(duì)象是否 Object 類或子類

//工廠方法2 通過傳參設(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 類或子類

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

//構(gòu)造器方法1function Car(sColor,iDoors){ //聲明為構(gòu)造器時(shí)需要將函數(shù)名首字母大寫 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的問題很明顯,沒辦法是 showDoor 方法重用,每次新建一個(gè)對(duì)象就要在堆里新開辟一篇空間.改進(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());//通過構(gòu)造器創(chuàng)建一個(gè)對(duì)象并調(diào)用其對(duì)象方法

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

4.通過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模式

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

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

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

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

//每個(gè)對(duì)象有專屬的屬性不會(huì)與其他對(duì)象共享function Car4(sColor,iDoors){ this._color = sColor;//私有屬性變量名稱頭加下劃線標(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)來判斷是否已給原型賦予了任何方法,保證方法永遠(yuǎn)只被創(chuàng)建并賦值一次 if(typeof Car5._initialized == 'undefined'){//因?yàn)檫@里的標(biāo)記是附加在類上,故如果后期直接對(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);

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

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)典方式(工廠方法)有著相同的問題.應(yīng)盡量避免

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

標(biāo)簽: JavaScript
相關(guān)文章:
主站蜘蛛池模板: 亚洲国产福利精品一区二区 | 久久是精品 | 亚洲欧美视频 | 国产精品一区二区在线观看 | 欧美专区视频 | 亚洲一区二区三区精品视频 | 偷拍第1页 | 中文国产成人精品久久96 | 天堂免费在线视频 | 国产成人精品免费视频大 | 一级待一黄aaa大片在线还看 | 一级特黄aaa大片在线观看 | 国产中文字幕免费观看 | 黄网视频在线观看 | 亚洲清纯自偷自拍另类专区 | 久久久久久久国产高清 | 亚洲伊人成人 | 美女图片131亚洲午夜 | 综合爱爱网 | 国产成人综合欧美精品久久 | 国产在线观看网址你懂得 | 亚洲一区二区精品视频 | 欧美成人香蕉网在线观看 | 欧美久草视频 | 亚洲综合美女 | 亚洲国产欧美在线人成精品一区二区 | 国产超薄肉色丝袜足j | 性色欧美xo影院 | 九九国产精品九九 | 欧美精品亚洲精品日韩 | 美女张开腿让男人桶的 视频 | 美国毛片亚洲社区在线观看 | 自拍视频在线观看 | 黄大片日本一级在线a | 久操视频免费在线观看 | www.午夜精品| 亚洲国产第一区二区香蕉日日 | 久久久久久久99视频 | 亚洲国产天堂久久精品网 | 欧美国产日韩在线播放 | 国产三级在线观看播放 |