天天看點

JavaScript類和繼承:constructor屬性

constructor屬性始終指向建立目前對象的構造函數。比如下面例子:

// 等價于 var foo = new array(1, 56, 34, 12);  

var arr = [1, 56, 34, 12];  

console.log(arr.constructor === array); // true  

// 等價于 var foo = new function();  

var foo = function() { };  

console.log(foo.constructor === function); // true  

// 由構造函數執行個體化一個obj對象  

var obj = new foo();  

console.log(obj.constructor === foo); // true  

// 将上面兩段代碼合起來,就得到下面的結論  

console.log(obj.constructor.constructor === function); // true 

但是當constructor遇到prototype時,有趣的事情就發生了。

我們知道每個函數都有一個預設的屬性prototype,而這個prototype的constructor預設指向這個函數。如下例所示:

function person(name) {  

    this.name = name;  

};  

person.prototype.getname = function() {  

    return this.name;  

var p = new person("zhangsan");  

console.log(p.constructor === person);  // true  

console.log(person.prototype.constructor === person); // true  

// 将上兩行代碼合并就得到如下結果  

console.log(p.constructor.prototype.constructor === person); // true 

當時當我們重新定義函數的prototype時(注意:和上例的差別,這裡不是修改而是覆寫),constructor屬性的行為就有點奇怪了,如下示例:

person.prototype = {  

    getname: function() {  

        return this.name;  

    }  

console.log(p.constructor === person);  // false  

console.log(person.prototype.constructor === person); // false  

console.log(p.constructor.prototype.constructor === person); // false 

為什麼呢?

原來是因為覆寫person.prototype時,等價于進行如下代碼操作:

person.prototype = new object({  

}); 

而constructor屬性始終指向建立自身的構造函數,是以此時person.prototype.constructor === object,即是:

console.log(p.constructor === object);  // true  

console.log(person.prototype.constructor === object); // true  

console.log(p.constructor.prototype.constructor === object); // true 

怎麼修正這種問題呢?方法也很簡單,重新覆寫person.prototype.constructor即可:

});  

person.prototype.constructor = person;  

繼續閱讀