原型链的冷知识,看一遍就会了~

·  阅读 159

你应该知道的冷知识

  1. 每一个函数都有一个prototype(原型)属性,属性值是一个普通的对象
  2. 每一个对象都有一个__proto__(隐式原型)属性,指向他构造函数的(原型prototype) ,即会从原型“继承”属性
  3. 函数也是一个对象,所有的函数都来自于构造函数Function
  4. 所有的对象都可以从原型链追溯到Object,并且Object也是一个构造函数
  5. 每个原型都有一个constructor属性,指向该关联的构造函数。

原型链的小概念

当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的prototype的__proto__中查找,这样一层一层向上查找就会形成一个链式结构,我们称为原型链

例子1、原型链

    //构造函数
    function Parent(name,age){
        this.name = name
        this.age = age
    }
    
    var child = new Parent('张三',30)
    console.log(child)
    console.log(child.__proto__)
    console.log(Parent.prototype)
    console.log(child.__proto__ === Parent.prototype) //true
    //打印数据展示
复制代码

image.png

由此可以看出,新的child对象在生成的时候会自带一个隐式原型 __proto__ 指向构造函数Parent 的 prototype,而且prototype下面存在一个constructor指向构造函数函数本身,如果Parent函数再根据原型链往下寻找,会找到Object()函数,如下图

image.png

    Parent.prototype.height = '180cm'
    //这里会打印180cm,就是child通过原型链找到的属性值
    console.log(child.height) // 180cm
复制代码

本次创建child对象的原型链可如下图所示:

image.png

new对象干了什么坏事?

  1. 创建(或者说构造)一个全新的对象
  2. 这个全新的对象会被执行[[prototype]]连接:当前对象的__proto__ 指向构造函数的 prototype
  3. 这个新对象会被绑定到函数调用的this
  4. 如果函数没有返回其他对象,那么new表达式中的函数会自动返回一个新对象
   function Foo(name){
       this.name = name
   }
   var foo = new Foo('小明')
   //解析new执行步骤
   //1、创建新对象
   var obj = {}
   //2、[[prototype]]连接
   obj.__proto__ = Foo.prototype
   //3、this指向转换
   var foo = Foo.call(obj, '小明');
   // 返回对象(前提是构造函数为返回其他对象)
   return foo
复制代码

Function 与 Object 的恩怨!

    //你中有我,我中有你
    console.log(Function instanceof Object) //true
    console.log(Object instanceof Function) //true
复制代码

先根据顶部冷知识思考 1、Function,Object 都是构造函数,所以既有 __proto__ 又有 prototype,只是指向问题,所以打印一下

    //Function的原型对象
    console.log(Function.prototype);
    //Object的原型对象
    console.log(Object.prototype);
    //Function的原型对象的原型对象
    console.log(Function.prototype.__proto__);
    console.log(Object.prototype === Function.prototype.__proto__);
复制代码

image.png

Function 与 Object 错综复杂的关系。

image.png

小结一下: 可以说是Function自己生了对象,生了函数,还生了自己....
Object作为他生的函数有了
Object.__proto__ === Function.prototype
但是又有
Function.__proto__===Function.prototype
这里形成了环形结构,即所谓的原型链。导致Object.prototype成为了没人要的野孩子,所以为null了

转一张别个绘制的图,看一看突然就懂了:

原型链.png

分类:
前端
标签: