原型:
每一個js 對象(null除外)都會和另一個對象相關聯,“另一個”對象就被我們稱之爲‘原型’,
而每一個原型擁有一個prototype 屬性指向原型對象(就是原型的實例)的引用,
原型就是通過該prototype將自身的屬性和方法共享給繼承他的子對象;
子對象通過__proto__
指向原型的prototype進行屬性方法繼承;這種方式稱之爲‘原型鏈’
如圖
- 其實Function 最特殊(函數界一等公民) 它是它自己的一個實例 ;
如:
Function(){}
let F = new Function();
Function.prototype = F;
Function.__proto__ = F;
就是說 Funciton 的原型就是F , 即Function.__proto__ === Function.prototype
,
所 Function.constructor === Function
而 Function.prototype.__proto__ === {}
,沒有再指向F而是{}避免了無意義的死循環
- 而Object 也是new Function()來的,
即Object.__proto__=F
,
所Object.__proto__ === Function.prototype
而
Object.prototype ==={}
此處同Function.prototype.__proto__
同理最終他的原型對象並沒有再指向F; 而是指向了最上層的{} 一個空對象,
簡單分析不難得出 要是他的原型對象和原型都指向同一個那就成死循環了
即會出現Object.__proto__ = F ; F = new Object();
- 而自定義函數默認原型爲 F ,即
CustFn.__proto__ === Function.prototype
以此類推他的構造函數就是Function了 即CustFn.constructor === Function
到這裏 CustFn 與 其實例的關係也就好理解了,
如
let FC = new CustFn();
CustFn.prototype = FC;
而 var custfn = new CustFn(); 就如 custfn = FC;
所以 custfn.__proto__ === FC
即 custfn.__proto__ === CustFn.prototype
而CustFn.prototype 是 new CustFn();
來的那麼 他的constructor 當然是 CustFn了
CustFn.prototype 是通過newCustFn() 這個普通函數來的,所以他的原型是一個{}空對象
CustFn.prototype.__proto__ === {}
到此不難理解 ‘只有new Function()來的函數 的原型纔是Function 其的都是普通對象’,如同 new Object()一樣
個人能力有限,如理解有誤的地方還望指點謝謝