1. 程式人生 > >js建立物件的7種方法

js建立物件的7種方法

ECMAScript5以及之前沒有類的概念,js中每個物件都是基於引用型別建立的

1. 建立物件—工廠模式

使用一個工廠函式來建立物件,該工廠函式接收引數構建物件必要資訊,並返回一個物件,每一次呼叫該工廠函式就返回一個物件
例如:

function createPerson(name, age, sex) {
    var o = {};
    o.name = name;
    o.age = age;
    o.sex = sex;
    o.sayName = function() {
        alert(this.name)
    }
    return
o; } var p1 = createPerson('limi', 20, 'man'); conosle.log(p1.name) // 'limi' p1.sayName() //彈窗'limi'

createPreson函式就像一個工廠源源不斷的生產物件;
缺點就是無法判斷產生的是什麼物件。

2. 建立物件—建構函式模式

有一些原生的建構函式,如Array, Object,可以通過new產生一個新的物件。也可以自定義建構函式,並定義自定義物件的屬性和方法。
例如:

function Person(name, age, sex) {
    this.name = name;
    this
.age = age; this.sex = sex; this.sayName = function() { alert(this.name) } }

再通過new Person('limi', 30, 'woman')生成物件;
缺點是

  • 沒有顯示地建立物件
  • 並直接將屬性和方法賦值給this物件
  • 沒有return語句

通過該方法建立的物件都是Person和Object的例項(instanceOf), 通過該方法可以建立特定型別的物件。

3. 建立物件—原型模式

每個函式都有prototype屬性,該屬性指向一個物件,在原型物件中包含物件例項共享的所以屬性與方法。用該方法可以不必在建構函式中定義物件例項資訊。如下:

function Person() {}
Person.prototype.name = 'tete';
Person.prototype.age = 22;
Person.prototype.job = 'teacher';
Person.prototype.sayName = function() {
    alert(this.name)
}
var person1 = new Person();
var person2 = new Person();

person1.sayName() //'tete';
person1.sayName === person2.sayName

我們將一些屬性和sayName()函式直接新增到Person的prototype屬性中,聲明瞭一個空的建構函式。通過該建構函式建立的例項都共享原型上的屬性與方法,不同例項物件的屬性和方法完全相同。
建構函式的原型是一個物件,上面的例子可改寫如下:

function Person(){}
Person.prototype = {
    constructor: Person,
    name: 'tete',
    age: 33,
    job: 'teacher',
    sayName: function() {
        alert(this.name)
    }
}

因為完全重寫了原型物件,將原型物件中的constructor屬性重新指向Person
可以看的通過原型模式建立物件,物件例項共享屬性與方法,當某一例項修改其屬性或方法時,其他例項再呼叫該屬性或方法時,屬性與方法也會是修改後的,這顯然不合理。

4. 建立物件—-組合使用建構函式模式和原型模式

這種方法集兩種模式之長,使用建構函式模式定義例項屬性,原型模式定義方法和共享的屬性。因此每個例項都會有一個例項屬性的副本還有著共享的方法。例子:

function Person(name, age, job) {
    this.name = name;
    this.job = job;
    this.age = age;
    this.friends = ['te1', te2];
}
Person.prototype = {
    constructor: Person,
    sayName: function() {
        alert(this.name);
    }
}
var p1 = new Person('tete1', 22, 'teaher');
var p2 = new Person('tete2', 14, 'student');

此時p1和p2都有自己的屬性和共享的方法(原型中),p1和p2都有共同的好友[‘te1’, te2],但是他們都是自己獨立的陣列副本,當p1新增friend時,不會影響p2的this.friends;

5. 建立物件—-動態原型模式

動態原型模式通過在建構函式中初始化原型,同時保持建構函式和原型的優點。動態的通過檢測判斷來新增方法。例子:

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);
        }
    }
}
Person.prototype = {
    constructor: Person,
    sayName: function() {
        alert(this.name);
    }
}

這樣在呼叫建構函式的時候會進行初始化,當不存在sayName函式時會在原型上新增。

6. 寄生建構函式模式

該模式主要是使用一個函式封裝建立物件的程式碼,在返回該物件。例子:

function Person(name, age, job) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function() {
        alert(this.name);
    }
    return o;
}

可以看出返回的物件與建構函式或與建構函式的原型之間沒有關係。

7. 穩妥建構函式模式

該模式沒有公共屬性,其方法也不引用this的物件。例子:

function Person(name, age, job) {
    var o = new Object();
    //定義私有變數和函式
    // 新增方法
    o.sayName = function() {
        alert(name);
    }
    return o;
} 
var p1 = Person('tete', 11, 'engineer');
p1.sayName() //'tete'

這樣只有呼叫sayName()才可以訪問其資料成員。

來源javascript高階程式設計