prototype: 对象的原形的属性 对象设置对外的属性(可以理解为构造函数中私有和对外的属性而 prototype 就是对外的属性)

__proto__: 可称为隐式原型,一个对象的隐式原型指向构造该对象的构造函数的原型,这也保证了实例能够访问在构造函数原型中定义的属性和方法

.__proto__ : 获取和设置当前对象prototype的方法

最好不要通过 .__proto__ 读出和设置对象的 prototype,因为 __proto__ 是 JS 中的内置方法是不对外公开的,只有浏览器设置了这个属性才可以使用,最好使用 Object.getPrototypeOf(fn) 和 Object.setPrototypeOf 读取和设置对象的 prototype

1. 对象例子

let obj1 = {
    a: 1,
    b: 2
};

let obj2 = {};
console.log(obj2.__proto__);  // {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}

obj2.__proto__ = obj1;
console.log(obj2);  // {}
console.log(obj2.a);  // 1
console.log(obj2.__proto__);  // {a: 1, b: 2}

2. 构造函数例子

let Apple = function (name) {
    this.name = name;
};
Apple.prototype.namefn = function () {
    return this.name;
};

let Banana = function (age) {
    this.age = age;
};
Banana.prototype.agefn = function () {
    return this.age;
};

console.log(Banana.__proto__);  // 读取 prototype -> ƒ () { [native code] }

Banana.__proto__ = Apple.prototype;  // 设置 prototype

console.log(Banana.__proto__);  // {namefn: ƒ, constructor: ƒ}

3. 获取和设置对象prototype

  • Object.getPrototypeOf(fn) -> 获取对象prototype
  • Object.setPrototypeOf(fn1, fn2.prototype) -> 设置对象prototype 和继承不一样设置会把原有的prototype覆盖掉

let Cat = function (name) {
    this.name = name;
};
Cat.prototype.showname = function () {
    return this.name;
};

let Dog = function (age) {
    this.age = age;
};
Dog.prototype.showage = function () {
    return this.age;
};

let c = new Cat('Kevin');
let d = new Dog(18);

console.log(Object.getPrototypeOf(c));  //获取对象prototype

Object.setPrototypeOf(d, Cat.prototype);  //设置对象prototype 和继承不一样设置会把原有的prototype覆盖掉

console.log(Object.getPrototypeOf(d));