淺析創(chuàng)建javascript對象的方法
一、工廠模式
function person (name,age) { var p=new Object(); p.name=name; p.age=age; p.showMessage=function(){ console.log("name:"+this.name+" age:"+this.age); } return p; } var p1=person("k1",28); var p2=person("k2",29); console.log(p1.showMessage==p2.showMessage);//false 不是同一個showMessage方法 console.log(p1.constructor);//[object] 都是object
工廠模式的缺陷是:沒解決對象識別的問題,而且每個對象的showMessage方法都不是同一個方法(每個方法在每個對象實例上都重新創(chuàng)建了一遍),增加了開銷
二、構(gòu)造函數(shù)模式
function Person (name,age) { this.name=name; this.age=age; this.showMessage=function(){ console.log("name:"+this.name+" age:"+this.age); } } var p1=new Person("k1",28); var p2=new Person("k2",29); console.log(p1.showMessage==p2.showMessage);//false 不是同一個showMessage方法 console.log(p1.constructor);//[Person] console.log(p1 instanceof Person);// true
構(gòu)造函數(shù)模式解決了對象識別的問題,但是每個對象的showMessage方法不是同一個方法(每個方法在每個對象實例上都重新創(chuàng)建了一遍),增加了開銷
三、原型模式
function Person () { } Person.prototype.name ="k"; Person.prototype.age =29; Person.prototype.showMessage=function () { console.log("name:"+this.name+" age:"+this.age); }; var p1=new Person(); p1.showMessage();//name:k age:29 var p2=new Person(); p2.showMessage();//name:k age:29 console.log(p1.showMessage==p2.showMessage);// true --引用的是同一函數(shù) console.log(p1.constructor)//[Person] --對象識別 console.log(p1 instanceof Person)//true --對象識別 console.log(Person.prototype.isPrototypeOf(p1));// true console.log(Object.getPrototypeOf(p1)==Person.prototype);// true
原型模式解決了“每個方法在每個對象實例上都重新創(chuàng)建了一遍”的問題,也解決了對象識別的問題
原型模式有個很大的問題是,因為掛載在函數(shù)prototype下面的所有對象、變量、函數(shù)都是被該函數(shù)的所有實例共享的,雖然通過實例p1、p2可以訪問到prototype的屬性,但是卻不能修改屬性值,例如p1.name="k1",只是在p1實例上添加了一個name="k1"的屬性,并沒改到prototype.name。如果是值類型還好,如果是引用類型的話,就會有問題了,看如下的例子
function Person () { }; Person.prototype.age =10; Person.prototype.array=[1,2,3]; var p1=new Person(); var p2=new Person(); console.log(p1.array);// [1,2,3] console.log(p2.array); //[1,2,3] p1.array.push(4); console.log(p1.array);//[1,2,3,4] console.log(p2.array);//[1,2,3,4]
p1往array里面添加了值,在p2也反映出來了,因為他們都是指向同一個array
四、組合使用構(gòu)造函數(shù)模式和原型模式
這是最常見的創(chuàng)建對象的方式,結(jié)合了構(gòu)造函數(shù)和原型模式的優(yōu)點
function Person (name,age) { this.name=name; this.age=age; } Person.prototype.showMessage = function() { console.log("name:"+this.name+" age:"+this.age); }; var p1=new Person("k",30); p1.showMessage();
五、動態(tài)原型模式
主要是解決:把所有的信息都封裝在構(gòu)造函數(shù)中,更符合oo的思想
function Person (name,age) { this.name=name; this.age=age; if(typeof this.showMessage!="function"){ Person.prototype.showMessage=function(){ console.log("name:"+this.name+" age:"+this.age); } } } var p1=new Person("k",30); p1.showMessage();
六、寄生構(gòu)造函數(shù)模式
function Person (name,age) { var o=new Object(); o.name=name; o.age=age; o.sayName=function(){ console.log(this.name); }; return o; } var p1=new Person("k",28); p1.sayName();
寄生構(gòu)造函數(shù)模式和工廠模式是一模一樣的,只不過創(chuàng)建對象的時候使用了new 關(guān)鍵字,上例:var p1=new Person("k",28)。
它的主要作用是:在這個構(gòu)造函數(shù)里面進(jìn)行功能的擴(kuò)展,例如,我想定義一個數(shù)組類型MyArray,它是以Array數(shù)組為基礎(chǔ)的,有一個自己的方法,如下
function MyArray(){ var values=new Array(); values.push.apply(values,arguments); //自己定義的方法 values.toPipedString=function(){ return this.join('|'); }; return values; } var colors=new MyArray("red","blue","green"); console.log(colors.toPipedString()); console.log(colors instanceof Array);
七、穩(wěn)妥構(gòu)造函數(shù)模式
穩(wěn)妥構(gòu)造函數(shù)遵循與寄生構(gòu)造函數(shù)類型的模式,但有兩點不同:一是不使用this,二是不使用new 調(diào)用構(gòu)造函數(shù)
function Person (name,age) { var o=new Object(); var tempAge=age; o.name=name; o.age=age; o.sayName=function(){ console.log(name); } o.sayAge=function(){ console.log(tempAge); } return o; } var p1=Person("k1",28); p1.sayName(); // k1 p1.sayAge(); // 28 p1.name="k2"; p1.age=30; p1.sayName(); // k1 p1.sayAge(); //28
看到如上的輸出就很好理解什么叫穩(wěn)妥對象模式了,就是用這種模式創(chuàng)建的對象,沒有其他辦法能夠改變初始化時候傳入的值,這里是Person("k1",28),這樣的對象就是穩(wěn)妥對象,實際上這里使用到就是javascript的閉包了。
以上這篇淺析創(chuàng)建javascript對象的方法就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
js實現(xiàn)鼠標(biāo)點擊左上角滑動菜單效果代碼
這篇文章主要介紹了js實現(xiàn)鼠標(biāo)點擊左上角滑動菜單效果代碼,涉及JavaScript基于鼠標(biāo)事件動態(tài)變換頁面元素樣式的技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-09-09JS中async/await實現(xiàn)異步調(diào)用的方法
這篇文章主要介紹了async/await實現(xiàn)異步調(diào)用的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-08-08javaScript如何跳出多重循環(huán)break、continue
這篇文章主要為大家詳細(xì)介紹了javaScript如何跳出多重循環(huán)break、continue,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-09-09判斷目標(biāo)是否是window,document,和擁有tagName的Element的代碼
判斷目標(biāo)是否是window,document,和擁有tagName的Element的代碼,需要的朋友可以參考下。2010-05-05