首先:聲明的函數,是有prototype屬性的。但是對象是沒有prototype的。
一、函數
console.dir(Foo)
可以看到,有prototype屬性和__proto__
屬性。- Foo.prototype裏的constructor指向Foo自己 ,
__proto__
指向Object.prototype。 - 而Foo.
__proto__
指向Function.prototype
二、Object
console.dir(Object)
可以看到,有prototype屬性和__proto__
屬性。- Object.prototype裏的constructor指向Object,
__proto__
指向null - Object.
__proto__
指向Function.prototype。
三、Function 構造函數
console.dir(Function)
可以看到,有prototype屬性和__proto__
屬性。- Function.prototype裏的constructor指向Function,
__proto__
指向Object.prototype - Function.
__proto__
指向Function.prototype。
四、對象
1、字面量創建對象
- 字面量創建的對象
__proto__
的默認指向Object.prototype。 - 沒有prototype屬性。
console.log(b.prototype)
結果undefined
2、構造函數創建對象
function F () {}
// 方法一:重寫prototype
F.prototype = {
//constructor: F,
name: 'liu',
method: function () {}
}
// 方法二:拓展prototype
F.prototype.name = 'yong';
F.prototype.method = function () {};
var f = new F();
console.log(f);
- 構造函數創建對象:
__proto__
下有constructor和__proto__
和Foo的prototype定義的屬性及方法。 __proto__
下的constructor指向Foo本身。__proto__
下的__proto__
指向Object.prototype。
注意:
方法一:直接重寫prototype,如果我不指定constructor,將導致如下圖,沒有了constructor。
方法二:拓展prototype,保證了constructor的正確指向。
五、附一張圖對上面總結
作圖工具採用processOn
六、附示例一份和圖解
該示例原出處: Dmitry Soshnikov
參考翻譯出處: 魏志峯(@JeremyWei)翻譯+投稿
function Foo(y) {
this.y = y;
}
Foo.prototype.x = 10;
Foo.prototype.calculate = function (z) {
return this.x + this.y + z;
};
var b = new Foo(20);
var c = new Foo(30);
b.calculate(30); // 60
c.calculate(40);