【JS】創建對象的6種方式總結


一、new 操作符 + Object 創建對象

1 var person = new Object();
2     person.name = "lisi";
3     person.age = 21;
4     person.family = ["lida","lier","wangwu"];
5     person.say = function(){
6         alert(this.name);
7     }

二、字面式創建對象

1 var person ={
2         name: "lisi",
3         age: 21,
4         family: ["lida","lier","wangwu"],
5         say: function(){
6             alert(this.name);
7         }
8     };

 

以上兩種方法在使用同一接口創建多個對象時,會產生大量重復代碼,為了解決此問題,工廠模式被開發。

三、工廠模式

 

function createPerson(name,age,family) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.family = family;
    o.say = function(){
        alert(this.name);
    }
    return o;
}

var person1 =  createPerson("lisi",21,["lida","lier","wangwu"]);   //instanceof無法判斷它是誰的實例,只能判斷他是對象,構造函數都可以判斷出 var person2 =  createPerson("wangwu",18,["lida","lier","lisi"]);
console.log(person1 instanceof Object); //true

 

 

工廠模式解決了重復實例化多個對象的問題,但沒有解決對象識別的問題(但是工廠模式卻無從識別對象的類型,因為全部都是Object,不像Date、Array等,本例中,得到的都是o對象,對象的類型都是Object,因此出現了構造函數模式)。

 

四、構造函數模式

function Person(name,age,family) {
    this.name = name;
    this.age = age;
    this.family = family;
    this.say = function(){
        alert(this.name);
    }
}
var person1 = new Person("lisi",21,["lida","lier","wangwu"]);
var person2 = new Person("lisi",21,["lida","lier","lisi"]);
console.log(person1 instanceof Object); //true
console.log(person1 instanceof Person); //true
console.log(person2 instanceof Object); //true
console.log(person2 instanceof Person); //true
console.log(person1.constructor); //constructor 屬性返回對創建此對象的數組、函數的引用

對比工廠模式有以下不同之處:

1、沒有顯式地創建對象

2、直接將屬性和方法賦給了 this 對象

3、沒有 return 語句

 

以此方法調用構造函數步驟 {

1、創建一個新對象

2、將構造函數的作用域賦給新對象(將this指向這個新對象)

3、執行構造函數代碼(為這個新對象添加屬性)

4、返回新對象 ( 指針賦給變量person ??? )

}

 

可以看出,構造函數知道自己從哪里來(通過 instanceof 可以看出其既是Object的實例,又是Person的實例)

 

構造函數也有其缺陷,每個實例都包含不同的Function實例( 構造函數內的方法在做同一件事,但是實例化后卻產生了不同的對象,方法是函數 ,函數也是對象)詳情見構造函數詳解

因此產生了原型模式

五、原型模式

 1 function Person() {
 2 }
 3 
 4 Person.prototype.name = "lisi";
 5 Person.prototype.age = 21;
 6 Person.prototype.family = ["lida","lier","wangwu"];
 7 Person.prototype.say = function(){
 8     alert(this.name);
 9 };
10 console.log(Person.prototype);   //Object{name: 'lisi', age: 21, family: Array[3]}
11 
12 var person1 = new Person();        //創建一個實例person1
13 console.log(person1.name);        //lisi
14 
15 var person2 = new Person();        //創建實例person2
16 person2.name = "wangwu";
17 person2.family = ["lida","lier","lisi"];
18 console.log(person2);            //Person {name: "wangwu", family: Array[3]}
19 // console.log(person2.prototype.name);         //報錯
20 console.log(person2.age);              //21

原型模式的好處是所有對象實例共享它的屬性和方法(即所謂的共有屬性),此外還可以如代碼第16,17行那樣設置實例自己的屬性(方法)(即所謂的私有屬性),可以覆蓋原型對象上的同名屬性(方法)。具體參見原型模式詳解

 

六、混合模式(構造函數模式+原型模式)

構造函數模式用於定義實例屬性,原型模式用於定義方法和共享的屬性

 1 function Person(name,age,family){
 2     this.name = name;
 3     this.age = age;
 4     this.family = family;
 5 }
 6 
 7 Person.prototype = {
 8     constructor: Person,  //每個函數都有prototype屬性,指向該函數原型對象,原型對象都有constructor屬性,這是一個指向prototype屬性所在函數的指針
 9     say: function(){
10         alert(this.name);
11     }
12 }
13 
14 var person1 = new Person("lisi",21,["lida","lier","wangwu"]);
15 console.log(person1);
16 var person2 = new Person("wangwu",21,["lida","lier","lisi"]);
17 console.log(person2);

可以看出,混合模式共享着對相同方法的引用,又保證了每個實例有自己的私有屬性。最大限度的節省了內存

 

高程中還提到了動態原型模式,寄生構造函數模式,穩妥構造函數模式

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM