1. 程式人生 > 實用技巧 >關於prototype和__proto__,最好的一些解釋

關於prototype和__proto__,最好的一些解釋

更原理性的東西

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