關於 prototype 與__proto__
- js中全部的函數都有一個 prototype 屬性,該屬性引用了一個對象,即原型對象,也簡稱原型
- js對象有一個__proto__屬性,指向它的構造函數的prototype屬性
- 對象.__proto__===函數.prototype;
var a = new A; //a 類型:對象 //A 類型:函數 var Object = new Function(); //var 對象 = new 函數; Object.__proto__ === Function.prototype; //對象.__proto__ === 函數.prototype; Function.__proto__ === Function.prototype; //由於 Function 也是 Object
//建立構造函數 function demo(name){ this.name= name; } demo.prototype = { alert(){ alert(this.name); } } //建立實例 var a = new demo("ming"); a.print = function(){ console.log(this.name); console.log(this); //Person對象 } a.print(); //控制檯內容以下
a.alert(); //彈出ming
print()方法是a實例自己具備的方法,因此 a.print() 打印 ming數組
alert()不屬於a實例的方法,屬於構造函數的方法,a.alert() 也會打印 ming,由於實例繼承構造函數的方法函數
實例a的隱式原型指向它構造函數的顯式原型,指向的意思是恆等於this
a.__proto__ === demo.prototype
Function.prototype.a = "a"; Object.prototype.b = "b"; function Person(){} console.log(Person); //function Person() let p = new Person(); console.log(p); //Person {} 對象 console.log(p.a); //undefined console.log(p.b); //b
因爲 p 是 Person() 的實例,是一個 Person 對象,它擁有一個屬性值__proto__,而且__proto__是一個對象,包含兩個屬性值 constructor 和__proto__spa
console.log(p.__proto__.constructor); //function Person(){} console.log(p.__proto__.__proto__); //對象{},擁有不少屬性值
p.__proto__.constructor 返回的結果爲構造函數自己,p.__proto__.__proto__有不少參數 prototype
咱們調用 constructor 屬性,code
p.__proto__.__proto __.constructor 獲得擁有多個參數的Object()函數,orm
Person.prototype 的隱式原型的 constructor 指向Object(),即 Person.prototype.__proto__.constructor == Object()對象
從 p.__proto__.constructor 返回的結果爲構造函數自己獲得 Person.prototype.constructor == Person()blog
因此 p.__proto__.__proto__== Object.prototype繼承
即 p.b 打印結果爲b,p沒有b屬性,會一直經過__proto__向上查找,最後當查找到 Object.prototype 時找到,最後打印出b,
向上查找過程當中,獲得的是 Object.prototype,而不是 Function.prototype,找不到a屬性,
因此結果爲 undefined,這就是原型鏈,經過__proto__向上進行查找,最終到null結束
console.log(p.__proto__.__proto__.__proto__); //null console.log(Object.prototype.__proto__); //null
同理,得出如下結果
//Function function Function(){} console.log(Function); //Function() console.log(Function.prototype.constructor); //Function() console.log(Function.prototype.__proto__); //Object.prototype console.log(Function.prototype.__proto__.__proto__); //NULL console.log(Function.prototype.__proto__.constructor); //Object() console.log(Function.prototype.__proto__ === Object.prototype); //true