prototype和__proto__的关系是什么?

  咱们建立的每一个函数都有一个prototype(原型)属性,这个属性是一个对象,它的用途是包含能够由特定类型的全部实例共享的属性和方法。(这个对象下面有个属性,这个属性是另一个对象的应用 ,这个属性就是一个对象。)函数

  -  prototypespa

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

  funcition这个特殊的对象,除了和其余对象同样有_proto_属性以外,还有本身特有的属性——原型属性(prototype),这个属性是一个指针,指向一个对象,这个对象的用途就是包含全部实例共享的属性和方法(咱们把这个对象叫作原型对象)。prototype是经过调用构造函数而建立的那个对象实例的原型对象。原型对象也有一个属性,叫作constructor,这个属性包含了一个指针,指回原构造函数。指针

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

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

  -  __proto__blog

  隐式原型,它所指向的是建立这个对象的函数(constructor)的prototype ,能够经过 object.setPrototypeOf();来得到一个对象的proto属性继承

 

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

 

  一、隐式原型的做用:构成原型链,一样用于实现基于原型的继承。举个例子,当咱们访问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()标准方法访问该属性),指向构造函数的原型对象。

相关文章
相关标签/搜索