tangyuxian
文章79
标签37
分类5
js-prototype和__proto__

js-prototype和__proto__

prototype是函数才有的属性;__proto__是每个对象都有的属性

1、背景

JavaScript的原型是一个很让人头疼的事情,一来prototype容易与__proto__混淆,二来它们之间的各种指向实在有些复杂,(关键Function和Object的关系复杂,他们的关系,可以阅读一下这篇文章这篇文章)。
原型是一个对象,其他对象可以通过它实现属性继承。

 let obj = Object.create(Object.prototype);
console.log(obj);

img

2、prototype和__proto__的区别

prototype是函数才有的属性,切记,切记

具体原因,可以看看阮一峰大神的这篇文章Javascript继承机制的设计思想,里面介绍了prototype的设计由来。

__proto__是每个对象都有的属性

它不是一个规范属性,该特性已经从 Web 标准中删除,虽然一些浏览器目前仍然支持它。__proto__属性已在ECMAScript 6语言规范中标准化,用于确保Web浏览器的兼容性,因此它未来将被支持。它已被不推荐使用, 现在更推荐使用Object.getPrototypeOf/Reflect.getPrototypeOfObject.setPrototypeOf/Reflect.setPrototypeOf
注意:大多数情况下,__proto__可以理解为“构造器的原型”,即__proto__===constructor.prototype,但是通过 Object.create()创建的对象有可能不是, Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__,下面会有实例解释

      let obj ={};
      console.log("obj:", obj);
      console.log("obj.prototype:", obj.prototype);
      console.log("obj.__proto__:", obj.__proto__);
      console.log("====================================");
      function myFunc() {}
      console.log("myFunc.prototype:",myFunc.prototype);
      console.log("myFunc.__proto__:",myFunc.__proto__);

img

打印出的结果很容易就证明上面的结论了。([native code] 指的是底层代码)

3、__proto__指向

__proto__是每个对象有的属性,那我们就从对象下手,我们列举几种常见创建对象的方式,来看看他们的__proto__指向。

1、字面量方式
    let obj = {};
    console.log("obj.__proto__:", obj.__proto__);
    console.log( obj.__proto__===obj.constructor.prototype);

img

2、构造器
      let objP = function() {};
      let obj = new objP();
      console.log("obj.__proto__:", obj.__proto__);
      console.log(obj.__proto__ === obj.constructor.prototype);

      let objO = new Object();
      console.log("objO.__proto__:", objO.__proto__);
      console.log(objO.__proto__ === objO.constructor.prototype);

img

3、 Object.create()
      let a1 = { a: 1 };
      let a2 = Object.create(a1);
      console.log("a2.__proto__:",a2.__proto__); //Object {a: 1}
      console.log(a2.__proto__ === a1.constructor.prototype); //false
      let a3 = Object.create(a1.__proto__);
      console.log("a3.__proto__",a3.__proto__); 
      console.log(a3.__proto__ === a1.constructor.prototype); //true

img

从结果可以看到,第二部分中的结论,大多数情况下,__proto__可以理解为“构造器的原型”,即__proto__===constructor.prototype,但是通过 Object.create()创建的对象有可能不是, Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__


参考文档:简书文章:prototype和__proto__

本文作者:tangyuxian
本文链接:https://www.tangyuxian.com/2021/02/24/%E5%89%8D%E7%AB%AF/JavaScript/js-prototype%E5%92%8C__proto__/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可