關於prototype和__proto__,最好的一些解釋
阿新 • • 發佈:2020-07-25
更原理性的東西
https://www.cnblogs.com/jyybeam/p/13200403.html
以下是簡單的理解
prototype是函式特有的屬性,是Function的靜態屬性;__proto__是物件特有的屬性。
因為函式本身是一種物件,所以函式既有prototype屬性也有__proto__屬性。
當函式使用prototype屬性時,是作為建構函式使用;
當函式使用__proto__屬性時,是作為一個物件使用。
另外,__proto__屬性內部屬性,儘量不要使用。可以用setPrototypeOf()和getPrototypeOf()代替。
1)普通函式分別取值
function C() {} console.log(C.prototype); /*{ constructor: function C(){},__proto__: Object }*/ // 使用__proto__時,是普通函式物件,原型物件指向Funtion的prototype屬性 console.log(C.__proto__ === Function.prototype);
對於普通函式來說,prototype屬性和__proto__屬性都是可讀寫屬性。
給prototype賦值,會改變函式的原型物件和上面的建構函式。
function C() {} function D() {} C.prototype = new D(); console.log(Object.getOwnPropertyDescriptor(C, 'prototype')); /* {value: D, writable: true, enumerable: false, configurable: false} //可寫 */ console.log(C.prototype.constructor === D); // true
2)class類分別取值,和普通函式一樣
class A{}
console.log(A.prototype);
// {constructor: ƒ, __proto__: Object}
console.log(A.__proto__ === Function.prototype);// true
但是,在class中,prototype屬性是隻讀的
class A{} class B{ add(){console.log('add')} static add(){console.log('static add')} } const a = new A(); const b= new B(); console.log(Object.getOwnPropertyDescriptor(A, 'prototype')); // {value: {…}, writable: false, enumerable: false, configurable: false}; // 只讀 A.__proto__ = B; // 靜態屬性方法繼承 b.add(); // add // a.add(); ❌ 不存在 A.add(); // static add A.prototype.__proto__ = B.prototype; // 例項屬性方法繼承 a.add(); // add