js建立物件的方式

lerryteng發表於2018-05-15

建立物件的方式

  1. 物件字面量
  2. 建構函式
  3. 工廠模式
  4. 建構函式模式
  5. 原型模式
  6. 組合模式
  7. 動態原型模式
  8. 寄生建構函式模式
  9. 穩妥建構函式模式

逐項說明

一、物件字面量

var obj = {};
複製程式碼

例項特性:物件之間相互獨立

  • 優勢:程式碼簡潔
  • 劣勢:使用同一個介面建立多個物件會產生很多重複程式碼

二、建構函式

var obj = new Object();
複製程式碼

例項特性:物件之間相互獨立

  • 優勢:程式碼簡潔
  • 劣勢:使用同一個介面建立多個物件會產生很多重複程式碼

三、工廠模式

function createObj(name, list) {
    var o = new Object();
    o.name = name;
    o.list = list;
    o.sayName = function() {
        alert(this.name);
    }
    return o;
}
var obj1 = createObj('obj1Name', [1]);
var obj2 = createObj('obj2Name', [1, 2]);
obj2.list.push(3);
console.log(obj1.list, obj2.list);      // [1] [1, 2, 3]
console.log(obj1.sayName === obj2.sayName);     // false
複製程式碼

例項特徵:物件之間相互獨立,不共享屬性和方法

  • 優勢:抽象建立物件的流程
  • 劣勢:無法識別物件的型別

四、建構函式模式

function Obj(name, list) {
    this.name = name;
    this.list = list;
    this.sayName = sayName;
}
function sayName() {
    alert(this.name);
}
var obj1 = new Obj('obj1Name', [1]);
var obj2 = new Obj('obj2Name', [1, 2]);
obj2.list.push(3);
console.log(obj1.list, obj2.list);      // [1] [1, 2, 3]
console.log(obj1.sayName === obj2.sayName);     // true
複製程式碼

例項特徵:物件之間相互獨立,但可有共享的方法(全域性中)

  • 優勢:避免顯式地建立物件,直接將屬性和方法賦給this物件,避免了return
  • 劣勢:全域性作用域下定義多個物件的函式並不合理
建構函式與函式的區別:
建構函式:大寫字母開頭,new操作符呼叫
普通函式:小寫字母開頭,正常呼叫(this物件指向當前作用域所屬的物件)
複製程式碼
使用new操作符建立特定型別的物件:
1. 建立一個新物件
2. 將建構函式的作用域賦給新物件(this指向的新物件)
3. 執行建構函式中的程式碼(新增屬性)
4. 返回新物件
複製程式碼

五、原型模式(所有原生的引用型別均採用此模式建立的)

function Obj() {}
Obj.prototype = {
    constructor: Obj,
    name: 'obj1Name',
    list: [1, 2],
    sayName: function() {
        alert(this.name);
    }
}
var obj1 = new Obj();
var obj2 = new Obj();
obj2.list.push(3);
console.log(obj1.list, obj2.list);      // [1, 2, 3] [1, 2, 3]
console.log(obj1.sayName === obj2.sayName);     // true
複製程式碼

例項特性:物件間共享屬性和方法,失去獨立性

  • 優勢:原型中所有屬性和方法均共享,不必在建構函式中定義物件資訊
  • 劣勢:屬性共享造成物件間失去獨立性

六、組合模式(建構函式模式+原型模式,建立自定義型別最常見的方式)

function Obj(name) {
    this.name = name;
    this.list = [1, 2];
}
Obj.prototype = {
    constructor: Obj,
    sayName: function() {
        alert(this.name);
    }
}
var obj1 = new Obj('obj1Name');
var obj2 = new Obj('obj2Name');
obj2.list.push(3);
console.log(obj1.list, obj2.list);      // [1, 2] [1, 2, 3]
console.log(obj1.sayName === obj2.sayName);     // true
複製程式碼

例項特性:物件間既有共享的方法或屬性,又有獨立的方法或屬性。

  • 優勢:利用建構函式模式定義屬性(支援傳參),利用原型模式定義共享的方法和屬性
  • 劣勢:每次建立物件都要初始化原型物件,缺乏封裝性

七、動態原型模式(個人認為最佳)

function Obj(name) {
    this.name = name;
    this.list = [1, 2];
    if(typeof this.sayName !== 'function') {
        Obj.prototype.sayName = function() {
            alert(this.name);
        }
    }
}
var obj1 = new Obj('obj1Name');
var obj2 = new Obj('obj2Name');
obj2.list.push(3);
console.log(obj1.list, obj2.list);      //  [1, 2] [1, 2, 3]
console.log(obj1.sayName === obj2.sayName);     // true
複製程式碼

例項特性:物件間既有共享的方法或屬性,又有獨立的方法或屬性。

  • 優勢:程式碼封裝性較好,同時避免多次初始化原型物件

八、寄生建構函式模式(不推薦)

function Obj(name) {
    var o = new Object();
    o.name = name;
    o.sayName = function() {
        alert(this.name);
    };
    return o;
}
var obj1 = new Obj('obj1Name');
var obj2 = new Obj('obj2Name');
console.log(obj1.sayName === obj2.sayName);     // false
console.log(obj1 instanceof Obj);       // false
複製程式碼

例項特性:物件間相互獨立,沒有共享方法或屬性

  • 優勢:可在特殊情況下為物件建立建構函式(如建立一個具有特殊方法的陣列,由於不能直接修改Array建構函式,則可使用此模式)
  • 劣勢:不能通過instanceof來確定物件的型別

九、穩妥建構函式模式(在安全環境下)

function Obj(name) {
    var o = new Object();
    o.sayName = function() {
        alert(name);
    }
}
var obj1 = Obj('obj1Name');
obj1.sayName();
複製程式碼
  • 優勢:適合在某些安全執行環境中(禁止使用this、new)或防止被其他應用程式改動時使用,只能通過特定的方法訪問屬性。

相關文章