JS-最全的創(chuàng)建對象方式

JS最全創(chuàng)建對象方式匯總

1.最簡單的方式--創(chuàng)建一個Object實例

var person = new Object();     //創(chuàng)建實例
person.name = "BlueBeginner";  //給實例添加屬性
person.age = 21;               //添加屬性
person.sayName = function(){   //添加方法
    alert(this.name);
}

2.對象字面量

var person = {
    name:'BlueBeginner',
    age:21,
    5:true,
    sayName:function(){
        alert(this.name);
    }
}
以上均為創(chuàng)建單個對象的方法,如果只需要少數(shù)具有不同屬性和方法的對象,以上方法簡單方便,但是當(dāng)我們需要很多具有相似屬性和方法的對象時,使用以上方法顯然不切實際,因為會產(chǎn)生大量的重復(fù)代碼。以下方法,便是為創(chuàng)建一類對象而生。

3.工廠模式

function createPerson(name,age,job){
    var o = new Object();//顯式創(chuàng)建對象
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function(){
        alert(this.name);
    }
    return o;//返回對象
}
var personone = createPerson("BlueBeginner",21,"web Engineer");
var persontwo = createPerson("DJL",23,"web Engineer");

函數(shù)根據(jù)接受的參數(shù)來創(chuàng)建對應(yīng)的對象,可以無數(shù)次的調(diào)用此函數(shù),每次都會返回一個包含3個屬性1個方法的對象。

工廠模式注意:
  • 需要用var顯式地創(chuàng)建對象
  • 有return語句,返回對象
  • 工廠模式?jīng)]有解決對象的識別問題,我的理解是不能確定對象由哪個函數(shù)創(chuàng)建,看以下代碼
alert(personone instanceof createPerson);//false
alert(personone instanceof Object);//true

4.構(gòu)造函數(shù)模式

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function(){
        alert(this.name);
    }
}
var personone = new Person("BlueBeginner",21,"web Engineer");
var persontwo = new Person("DJL",23,"web Engineer");
構(gòu)造函數(shù)模式注意:
  • 沒有顯式地創(chuàng)造對象
  • 直接將屬性和方法賦值給了this對象
  • 沒有return語句
  • 構(gòu)造函數(shù)名首字母大寫
  • 使用new操作符創(chuàng)建實例
    • 創(chuàng)建一個新對象
    • 將構(gòu)造函數(shù)的作用域賦給這個對象(因此this指向這個對象)
    • 執(zhí)行構(gòu)造函數(shù)中的代碼
    • 返回新對象
  • 之所以說構(gòu)造函數(shù)解決了工廠模式不能識別對象類型的問題,看下面的代碼
alert(personone instanceof Object);//true
alert(personone instanceof Person);//true
然而無論是工廠模式還是構(gòu)造函數(shù)模式,都存在一個相同的問題,即--不同實例上的同名函數(shù)是不相等的,看以下代碼:
alert(personone.sayName == persontwo.sayName);//false
這樣的話,以上的兩種模式都創(chuàng)建了兩個完成同樣任務(wù)的Function實例,這樣做完全沒必要。而且,對于構(gòu)造函數(shù)模式,因為有this對象在,根本不用在執(zhí)行代碼前就把函數(shù)方法綁定到特定對象上面,大可像下面代碼所示,將方法寫到構(gòu)造函數(shù)外面:
function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = sayName;
}
function sayName(){
    alert(this.name);
}
這樣的話,所有實例共享了在全局作用域中定義的函數(shù)方法。但是很顯然的是,如果需要很多很多方法呢?以這種方法,豈不是需要定義很多很多全局函數(shù)?在全局中定義的函數(shù),只能被某些對象調(diào)用,這讓全局作用域有點名不副實。好在,這些問題,可以通過原型模式來解決。

5.原型模式

function Person(){};
Person.prototype.name = "BlueBeginner";
Person.prototype.age = 21;
Person.prototype.job = "web Engineer";
Person.prototype.sayName = function(){
    alert(this.name);
};
var personone = new Person();
var persontwo = new Person();
personone.sayName();//'BlueBeginner'
persontwo.sayName();//'BlueBeginner'
alert(personone.sayName == persontwo.sayName);//true
原型模式注意:
  • 所有實例共享相同的屬性和方法
  • 對于方法和基本屬性值,這樣很合適,但是對于引用類型的值,卻出現(xiàn)了問題。在實例中重寫引用類型的值會修改原型中的同名屬性。如下:
function Person(){};
Person.prototype = {
    constructor:Person,
    name:'BlueBeginner',
    age:21,
    friends:['DJL','ZH'],
    sayName:function(){
        alert(this.name);
    }
}
var personone = new Person();
var persontwo = new Person();
personone.friends.push('YR');
alert(personone.friends);//'DJL','ZH','YR'
alert(persontwo.friends);//'DJL','ZH','YR'
alert(personone.friends == persontwo.friends);//true

在第一的實例personone中重寫引用類型值后,第二個實例所得到的原型上的引用類型值也被修改了,這顯然不盡人意。所以很少有人單獨使用原型模式。

關(guān)于原型模式的理解請看

6.組合使用構(gòu)造函數(shù)模式和原型模式

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.friends = ['DJL','ZH']
}
Person.prototype = {
    constructor:Person,
    sayName:function(){
        alert(this.name);
    }
}
var personone = new Person("BlueBeginner",21,"web Engineer");
var persontwo = new Person("DJL",23,"web Engineer");
personone.friends.push('YR');
alert(personone.friends);//'DJL','ZH','YR'
alert(persontwo.friends);//'DJL','ZH'
alert(personone.sayName === persontwo.sayName);//true
alert(personone.friends == persontwo.friends);//false

這種模式將構(gòu)造函數(shù)和原型分開,在構(gòu)造函數(shù)里面寫屬性,在原型里面寫方法,可以說,這是用來定義引用類型的一種默認模式,當(dāng)然,有同學(xué)看到獨立的構(gòu)造函數(shù)和原型時,會感到困惑,下面這個模式,便解決了這個問題。

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

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    if(typeof this.sayName != 'function'){
        Person.prototype.sayName=function(){
            alert(this.name);
        };
    };
}

這種模式方法確實非常完美,if判斷代碼只會在初次調(diào)用構(gòu)造函數(shù)時才會執(zhí)行,此后,原型已經(jīng)初始化,不需要再做什么修改了。

當(dāng)然,第三版中還介紹了寄生構(gòu)造函數(shù)模式和穩(wěn)妥構(gòu)造函數(shù)模式,但這兩種模式用的很少,這里不多做介紹。有興趣的同學(xué)請自行查閱相關(guān)資料。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容