原型链之__proto__和prototype

原型链每隔一段时间就容易忘记,所以整理一下,便于回顾。

用下面的代码 demo 来帮助理解:


   function Person(name, age, job) {  
    this.name = name;  
    this.age  = age;  
    this.job = job;  
    this.sayName = function() {    
      console.log(this.name);  
      }
    } 
    
    let person1 = new Person('nick', 29, '程序员')
    let person2 = new Person('tom', 28, '摄影师') 
    
    person1.sayName();    //nick
    person2.sayName();    // tom

image

先看图,有个大体印象:

构造函数原型链 (4)

定义

prototype

  • 是个对象,并且有个 [[constructor]] 方法
  • 函数和类(es6)才有,箭头函数、普通对象都没有prototype,例如:

普通对象:__proto__函数:__proto__、prototype// 箭头函数没有let a = () => {}> a.prototype < undefined > a.__proto__< ƒ () { [native code] } > a.__proto__.constructor< ƒ Function() { [native code] }

es6 的 class 具有 prototype:

image

__proto__

这个属性是用来标识自己所继承的原型,用来读取或设置当前对象的prototype对象,他本质是一个内部属性,不是一个正式对外的api,由于浏览器的广泛支持,才加入了es6,__proto__调用的是Object.prototype.proto。

对象__proto__属性的值就是它所对应的原型对象。

image

结论:
1.所有对象都有__proto__属性。
2.只有函数对象才有prototype属性。
3.protoype对象默认有两个属性:constructor 和 proto
4.实例对象的__proto__指向的是函数的protoype
5.函数对象的prototype属性是外部共享的,而__proto__是隐式的。
6.函数和Object的__proto__的顶端是null

参考:
https://segmentfault.com/a/1190000011801127
https://juejin.cn/post/6844903790345191437