JavaScript中的 prototype 和 constructor

  prototype屬性

    任何js函數均可以用做構造函數, 而構造函數須要用到prototype屬性, 所以, 每一個js函數F(除了ES5的Function.bind()方法返回的函數外) 都自動擁有一個prototype屬性. 函數

  F.prototype的值是一個對象 o , o 默認包含惟一一個不可枚舉的屬性: constructor , 值默認指回 F,能夠修改.this

  調用 F 構造的對象繼承 F.prototype 對象.spa

  F.prototype 是類的惟一標識.  當且僅當兩個對象繼承自同一個原型對象時, 它們才屬於同一個類的實例. 而構造函數只是對象建立好以後, 當成是該對象的方法當即調用一次.不能做爲類的標識. 若是兩個構造函數的prototype屬性指向同一個原型對象, 則它們建立的實例屬於同一個類.prototype

function C1(){
    this.y = 1;
}
function C2(){
    this.y = 2;
}
var p = {x:10};
C1.prototype = p;
C2.prototype = p;
var c1 = new C1();
var c2 = new C2();
console.log(c1 instanceof C2); //"true"
console.log(c2 instanceof C1); //"true"

    

  instanceof 運算符檢測對象是否屬於某個類(名字和構造函數 F 同名)時, 其實是檢查是否繼承自 F.prototype.  c1 instanceof C1; // 若是 c1 繼承自 C1.prototype, 則返回true, 而不是檢查c1是否由C1()初始化而來. 而instanceof運算符則強化了構造函數是類的公有標識的概念. code

  js基於原型的繼承機制是動態的,建立對象後, 原型的屬性發生改變, 也會影響到繼承這個原型的全部實例對象.並且也能夠修改內置類的原型對象.對象

 

  constructor屬性

  F.prototype.constructor 的值爲一個函數對象, 默認指向 F 自己.blog

  構造函數 F 是類的 "公共標識",  constructor屬性被對象繼承下去了, 因此  var obj = new F() 後  obj.constructor 就能找到其構造函數, 也能夠說找到了類. 可是修改了  F.prototype  以後, constructor屬性也可能改變了, 能夠手動修改回來.繼承

  

  兩者的關係

var F = function(){};
var p = F.prototype;
var c = p.constructor;
console.log(c === F); // "true"

var F = function(){
};
var G = function(){
    console.log("I am G");
};
F.prototype.constructor = G;
var o = new F();
console.log(o.constructor === G); //constructor 屬性說明是G, 返回: true
console.log(o.constructor === F); // constructor 屬性說明類的構造函數, 如今已經變爲G了. 因此: false
console.log(o instanceof F); // o 繼承自 F.prototype, 因此是: true
console.log(o instanceof G); // o 不是繼承自 G.prototype, 因此是 false

 

  參考: <<JavaScript權威指南: 第6版>>

相關文章
相關標籤/搜索