用構造函數創建特定類型的對象,從而可以自定義自定義對象類型的屬性和方法
與工廠模式的區別
- 沒有顯示地創建對象
- 直接將屬性和方法賦給了this對象
- 沒有return語句
- 創建實例時,必須使用
new
操作符
以new創建對象會經歷一下步驟- 創建一個新對象
- 將構造函數的作用域賦給新對象(因此this就指向了這個新對象)
- 執行構造函數中的代碼
- 返回新對象
constructor屬性最初是用來標識對象類型的
示例
var Person = function(name, age) {
this.name = name;
this.age = age;
this.sayName = function() {
return this.name;
};
};
var person1 = new Person('duke', 22);
var person2 = new Person('dome3', 24);
var person3 = Person('no new', 0);
console.log('person1=>', person1);
console.log('person2=>', person2);
console.log('person3=>', person3); // undefined 必須使用new創建對象
console.log('is method equal=>', person1.sayName === person2.sayName); // false
console.log('instance constructor1=>', person1.constructor === Person); // true
console.log('instance constructor2=>', person2.constructor === Person); // true
console.log('instanceof1=>', person1 instanceof Person); // true
console.log('instanceof2=>', person2 instanceof Person); // true
console.log('instanceof2=>', person1 instanceof Object); // true
構造函數也是函數,像普通函數一樣,直接調用,屬性和方法屬于全局對象Global(瀏覽器中為window對象),如示例中的person3
優點
除了工廠模式的特點,主要解決對象類型識別的問題
缺點
對象的方法,在每個實例中都要重新創建一遍,導致不同的作用域鏈和標識符解析,但是創建函數實例的機制相同,因此不同實例上的同名函數相同
為了在示例中共享方法而在全局作用域中定義方法,這樣能解決以上問題,但是同時產生另外一個問題:在全局作用域中定義的函數只能被某個對象調用,這樣全局作用域就有點兒名不副實了,而且若需要定義很多函數,那我們自定義的引用類型就沒有封裝性可言了
由此,[[原型模式]]可以解決該問題