prototype和__proto__的关系是什么?

  我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个对象,它的用途是包含可以由特定类型的所有实例共享的属性和方法。(这个对象下面有个属性,这个属性是另外一个对象的应用 ,这个属性就是一个对象。)

  -  prototype

  是显式原型,它是指向函数的原型对象。(函数创建之后就会产生prototype属性)

  funcition这个特殊的对象,除了和其他对象一样有_proto_属性之外,还有自己特有的属性——原型属性(prototype),这个属性是一个指针,指向一个对象,这个对象的用途就是包含所有实例共享的属性和方法(我们把这个对象叫做原型对象)。prototype是通过调用构造函数而创建的那个对象实例的原型对象。原型对象也有一个属性,叫做constructor,这个属性包含了一个指针,指回原构造函数。

  1、显式原型的作用:用来实现基于原型的继承与属性的共享

  2、使用原型对象的好处:是可以让所有对象实例共享它所包含的属性和方法,不必在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中。

  -  __proto__

  隐式原型,它所指向的是创建这个对象的函数(constructor)的prototype ,可以通过 object.setPrototypeOf();来获得一个对象的proto属性

  function是对象,function的原型prototype也是对象,它们都会具有对象共有的特点。即:对象具有属性__proto__,每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性 时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样 一直找下去,也就是我们平时所说的原型链的概念。__proto__可称为隐式原型,一个对象的隐式原型指向构造该对象的构造函数的原型,这也保证了实例能够访问在构造函数原型中定义的属性和方法。

  1、隐式原型的作用:构成原型链,同样用于实现基于原型的继承。举个例子,当我们访问obj这个对象中的x属性时,如果在obj中找不到,那么就会沿着__proto__依次查找。

  

function a() { }
a.prototype.name = "1"
var b = new a()

//这个并不是构造函数专有,每个函数都会有一个prototype属性,这个属性是一个指针,指向一个对象,记住只有函数才有,并且通过bind()绑定的也没有。
console.log(b.name)// 1

console.log(a.prototype) // {constructor: ƒ}
console.log(a.__proto__) // ƒ () { [native code] }

//a作为构造函数时的prototype属性与a作为普通函数时的__proto__属性并不相等
console.log(a.prototype === a.__proto__);//false

//a作为一个普通函数调用时,它的构造函数是内置对象Function,所以它指向的原型对象,就是Function.prototype,其实这个和console.log(b.__proto__ == a.prototype)是一样的道理
console.log(b.__proto__) // {constructor: ƒ}
console.log(Function.prototype) //ƒ () { [native code] }
console.log(a.__proto__ === Function.prototype);//true
console.log(b.__proto__ === a.prototype) // true

//a作为构造函数时,它的原型,和它的原型的原型
console.log(a.prototype); //a{}
console.log(a.prototype.__proto__);  // {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ,ƒ…}

//a作为普通函数时,它原型的原型
console.log(a.__proto__.__proto__); // {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ,ƒ…}

console.log(a.__proto__.__proto__ === a.prototype.__proto__); //true

  - 总结

  所有对象都有__proto__属性,函数这个特殊对象除了具有__proto__属性,还有特有的原型属性prototype。prototype对象默认有两个属性,constructor属性和__proto__属性。prototype属性可以给函数和对象添加可共享(继承)的方法、属性,而__proto__是查找某函数或对象的原型链方式。constructor,这个属性包含了一个指针,指回原构造函数。

  prototype和__proto__都指向原型对象,任意一个函数(包括构造函数)都有一个prototype属性,指向该函数的原型对象,同样任意一个构造函数实例化的对象,都有一个__proto__属性(__proto__并非标准属性,ECMA-262第5版将该属性或指针称为[[Prototype]],可通过Object.getPrototypeOf()标准方法访问该属性),指向构造函数的原型对象。

原文地址:https://www.cnblogs.com/Ann-web-1/p/11262886.html