__proto__ 和 prototype 区别

链接:https://www.zhihu.com/question/34183746/answer/124279182

__proto__ 、prototype傻傻分不清楚? 记住以下两点:

1. __proto__是每个对象都有的一个属性,而prototype是函数才会有的属性。

2. __proto__指向的是当前对象的原型对象,而prototype指向的,是以当前函数作为构造函数构造出来的对象的原型对象。看起来有点绕,我 show you the code,下面我们用右手作为原型来给自己构造一个女朋友:

//在JavaScript的世界中,所有的函数都能作为构造函数,构造出一个对象
   //下面我给自己构造一个女朋友
   function GirlFriend () {
     this.name = "Alice";
   }
   //现在我设置GirlFriend()这个函数的prototype属性
   //一般来说直接用匿名的对象就行,我这里是为了方便理解,
   //先定义一个hand对象再把hand赋值给GirlFriend()的prototype
   var hand = {
     whichOne: "right hand",
     someFunction: function(){
       console.log("not safe for work.");
     }
   };
   GirlFriend.prototype = hand; 

   //这个时候,我们可以用GirlFriend()作为构造函数,构造出myObject对象
   var myObject = new GirlFriend();
   console.log(myObject.__proto__ === GirlFriend.prototype) //true

好了,通过上面的代码,我们构建了一个女神对象myObject,而 myObject 的原型是 hand 对象,而刚好 myObject 的构造函数GirlFriend()的 prototype 属性也指向 hand 对象。现在我们知道,prototype 与__proto__ 的关系就是:你的__proto__来自你构造函数的prototype

还有,上面的例子中,myObject 是通过 new GirlFriend()创建的,而 hand 对象,则是赋值语句创建的,这有什么不同?

其实hand这种直接用赋值语句加花括号来创建的对象,叫做对象字面量,你可以想象JavaScript内置了一个叫Object()的构造函数,这个函数的prototype属性指向的是一个空对象:

console.log(Object.prototype) //输出{}

而所有对象字面量都是通过Object()构造出来的,换言之,对象字面量__proto__ 属性都指向Object.prototype, which is 一个空对象。

所以我们可以知道, hand.__proto__ 指向的是Object.prototype

再附送你一个fun fact:

Object.prototype这个对象,它的__proto__指向的是null,然后就没有然后了。

console.log(Object.prototype.__proto__);//输出null
经验分享 程序员 微信小程序 职场和发展