原型和原型链也是经常被面试问到的问题,其实原型,原型链涉及问题较多,本文也延展了几个面试中常问的知识点,文章不长,耐心看完肯定会有收获。

创建对象的几种方法

  • 字面量创建
    var n={name:1};
    var n2=new Object({name:1});
  • 构造函数创建
   var M=function(){
       this.name=1
   };
   var n=new M()
  • Object.create创建
    var P={name:1};
    var n=Object.create(P)
  • 打印一下结果
wRLLtJ.png

原型、构造函数、实例、原型链

  • 先看图
w2zC4g.png
  • 再上代码:
    //字面量创建
    var o1={name:'tom'}
    var o2=new Object({name:'bob'});

    //构造函数
    var M=function(name){
        this.name=name
    }
    var o3=new M('tom');

    //object.create
    var p={name:'tom'};
    var o4=Object.create(p)
  • 任何一个函数,只要被new了以后,就是构造函数,而new出来的被称之为实例。任何函数都可以当作构造函数。

  • 函数中都有一个prototype属性,申明一个函数时候就会有个prototype属性,这个属性会初始化一个空对象,也就是原型对象。

  • 原型对象中会有一个构造器:constructor,它默认会指向你申明的那个函数。结合上面写的创建对象的例子以及结合关系图验证一下:

wWp3Zt.png
  • 可以看到结果:M.prototype.constructor==M结果为true,也就验证了上面关系图。

  • 再次验证一下实例与他们的关系:

wW9dfO.png

原型对象存在的作用

  • 先上例子
   function Person(name,age){
       this.name=name;
       this.age=age;
       this.eat=function(){
           console.log(age+"岁的"+name+"在吃饭")
       }
   };
   let Tom=new Person("Tom",24);
   let Bob=new Person("Tom",24);
   console.log(Tom.eat===Bob.eat);  //flase
  • 可以看到对于同一个函数,new出来的实例,都会开出新的一块堆区,所以例子中Tom和Bob的eat是不同的。
    虽然拥有自己的的东西(比如房子,车子)是很好的,但它也有不好的地方,毕竟一共就那么大的地方(内存),你要 一直建立房子,会导致地方不足(内存不足)。

  • 所以要想个方法,建立共享库的的对象(例如把楼房建高),这样就可以在需要的时候调用一个类似共享库的对象(社区),让实例能沿着某个线索找到它的归处。

    function Person(name,age){
        this.name=name;
        this.age=age;
    };
    // 通过构造函数的 Person 的 prototype 属性找到 Person 的原型对象
    Person.prototype.eat=function(){
        console.log("吃饭")
    };

   let Tom=new Person("Tom",24);
   let Bob=new Person("Tom",24);

   console.log(Tom.eat===Bob.eat); //true
  • 当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又 会有自己的原型,于是就这样一直找下去,也就是原型链的概念。原型链的镜头就是Object.prototype

instanceof的原理

  • instanceof 可以正确的判断对象的类型,因为内部机制是通过判断对象的原型链中是不是能找到类型的 prototype
wWAKt1.png
    console.log([] instanceof Array);                    // true
    console.log(function(){} instanceof Function);       // true
    console.log({} instanceof Object);                   // true  

new运算符中都干了什么

  • 创建一个简单空对象

  • 链接该对象到另一个对象(原型链)

  • 将步骤1新创建的对象作为this的上下文

  • 如果该函数没有返回对象,则返回this

  • 如果return则返回return的值

    var new2=function(func){
        var o=Object.create(func.prototype);
        var k=func.call(o);
        if(typeof k =='object'){
            return k
        }else{
            return o
        }
    }

总结

如有错误,欢迎指正,如果对你有帮助,记得点赞收藏!