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