js 原型链的理解

  • 什么是原型

    原型是一个对象

    就我的理解原型就是 实例上的 __proto__ 属性和构造函数的 prototype 属性 指向的对象

    • new 操作符生成对象时就干了3件事

      var obj = {}						//1.创建一个空对象 obj
      //2.我们将这个空对象的__proto__成员指向Foo函数对象prototypt
      obj.__proto__ = Foo.prototype		
      //3.将Foo构造函数的this指针换为obj,然后再调用Base函数
      Foo.call(obj)
      
  • 构造函数、原型和实例之间的关系

  • 原型链

    什么是原型链?说白了,其实就是有限的实例对象和原型之间组成有限链,就是用来实现共享属性和继承的。

    var arr = [];
    //arr -> Array.prototype ->Object.prototype -> null
    var o = new Object();
    //o -> Object.prototype -> null;
    

    但原型之间是如何实现继承的呢?

    如果直接用Array.prototype = Object.prototype,那么所有对象就都指向一个原型了,修改一个对象的原型就会修改所有对象的原型,这显然是不行的。

    所以我们会通过一个新的对象来实现过渡 Array.prototype = new Object() ,这样Array既继承了Object原型的所有属性,也拥有了自己独立的原型,修改自己的原型也不会对其他对象构成影响。

  • 关于对象 constructor 的指向错误

    顾名思义,constructor是指向对象构造函数,但在面对继承的时候却不是这样的

    function Father() {
    
    }
    var father = new Father();
    function Son(){
    
    }
    Son.prototype = father
    var son = new Son();
    
    console.log(son.constructor)    //Father
    

    很明显son的构造函数是Son,但却指向了Father

    这主要是因为son的原型上有了 constructor属性,son继承到了该属性,如果没有继承,那么son的constructor 就指向构造函数

    但我们还是习惯实例的constructor指向构造函数

    constructor属性不影响任何JavaScript的内部属性。constructor其实没有什么用处,只是JavaScript语言设计的历史遗留物。由于constructor属性是可以变更的,所以未必真的指向对象的构造函数,只是一个提示。不过,从编程习惯上,我们应该尽量让对象的constructor指向其构造函数,以维持这个惯例。

    function Father() {
    
    }
    var father = new Father();
    function Son(){
    
    }
    Son.prototype = father
    Son.prototype.constructor = Son		//让实例及原型的constructor都指向构造函数
    var son = new Son();
    
    console.log(son.constructor)    //Father
    

    虽然这里 son 的 constructor指向了它的构造函数,但 father 的构造函数也指向了 Son 。但这并不重要,因为在实际继承中,我们并不知道这个 father 对象的存在。我们通过Father创建出来的实例的constructor仍然指向 Father

原文地址:https://www.cnblogs.com/angle-yan/p/12777207.html