美文网首页
原型链__proto__和prototype关系

原型链__proto__和prototype关系

作者: keknei | 来源:发表于2019-05-21 17:43 被阅读0次
一般对象的属性规则
  1. 对象有__proto__属性,函数有prototype属性;
  2. 对象由函数生成
  3. 生成对象时,对象的__proto__属性指向函数的prototype属性
  4. 对象一般分为两种,一种是普通的对象{}或者new Fn()出来的对象,这种对象没有prototype,另一种就是函数对象,这种对象有__proto__prototype

一般对象

创建空对象时,实际上我们是用Object函数来生成对象的,对象o的__proto__属性就是Object.prototype,并且o.prototype==undefined,所以这种对象时没有prototype

{
   let o={};
   o.__proto__==Object.prototype;//true
   o.prototype//undefined
}

我们也可以显式的使用Object函数来创建对象,对象o的__proto__属性就是Object.prototype,并且o.prototype==undefined,所以这种对象时没有prototype

{
   let o = Object()
   o.__proto__ === Object.prototype//true
   o.prototype//undefined
}

当我们使用函数来创建自定义的对象时,对象mo的__proto__属性就是MyObj.prototype,并且mo.prototype==undefined,所以这种对象时没有prototype

  function MyObj(){}
  let mo = new MyObj();
  mo.__proto__ === MyObj.prototype//true
  mo.prototype//undefined

函数对象的__proto__

一般函数对象都是由Function函数生成的,所以他们的__proto__属性,都会指向Functionprototype

{
  function fn(){};
  fn.__proto__==Function.prototype//true
}
{
  //Function函数本身
  Function.__proto__==Function.prototype//true
}
{
  //Object函数本身
  Object.__proto__==Function.prototype//true
}
一般函数对象的prototype

一般函数默认的prototype是一个类型为"object"的对象,它有两个属性:constructor__proto__。其中constructor属性指向这个函数自身,__proto__属性指向Object.prototype,这说明一般函数的prototype属性是由Object函数生成的。

{
  function fn(){};
  console.log(fn.prototype)//object
  //{constructor: ƒ}
    //constructor: ƒ fn()
    //__proto__: Object
  fn.prototype.constructor==fn//true
  fn.prototype.__proto__==Object.prototype;//true
}

特殊函数的prototype

如果Object.prototype.__proto__ === Object.prototype
那么,问题出现了,Object.prototype.__proto__属性指向了它自身,这样以__proto__属性构成的原型链就再也没有终点了!所以为了让原型链有终点,在原型链的最顶端,JavaScript规定了Object.prototype.__proto__ === null

{
  console.log(Object.prototype);
  Object.prototype.constructor==Object//true
  Object.prototype.__proto__==null;//true
}

按照我们最开始提出的通用规则,一个"function"类型的对象,应该是由Function函数生成的,那它的prototype属性应该指向Function.prototype,也就是Function.prototype.__proto__ === Function.prototype。和Object函数同样的问题出现了:循环引用。所以JavaScript规定Function.prototype.__proto__ === Object.prototype,这样既避免了出现循环引用,又让__proto__构成的原型链指向了唯一的终点:Object.prototype.__proto__ === null

{
  console.log(Function.prototype);
  Function.prototype.constructor==Function//true
  Function.prototype.__proto__==Object.prototype;//true
}

下面一张图描述了javaScript原型链之间的关系

javascript原型链

相关文章

网友评论

      本文标题:原型链__proto__和prototype关系

      本文链接:https://www.haomeiwen.com/subject/rkbjzqtx.html