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;