• constructor属性解析


    JavaScript中constructor属性一直不是很清楚,今日终于弄清了其中缘由,下面举例说明。

    首先是一个典型的JavaScript实例声明:

    function Person(){
      this.name = name;
    }
    var p = new Person('Joe');
    console.log(p.constructor === Person); //true
    console.log(p.__proto__ === Person.prototype); //true

    如果此时对Person的prototype中添加属性或函数:

    function Person(){
      this.name = name;
    }
    Person.prototype.getName = function(){
      return this.name;
    }
    var p = new Person('Joe');
    console.log(p.constructor === Person); //true
    console.log(p.__proto__ === Person.prototype); //true

    但是如果对Person的prototype重新定义,将会产生如下结果:

    function Person(){
      this.name = name;
    }
    Person.prototype = {
      getName : function(){
        return this.name;
      }
    }
    var p = new Person('Joe');
    console.log(p.constructor === Person); //false
    console.log(p.__proto__ === Person.prototype); //true

    这里面关系到constructor属性的归属问题,本人试着用下面的代码验证:

    Person.__proto__.constructor===Person.constructor //true
    p.__proto__.constructor === p.constructor; //true

    经过上述验证,可以证明constructor其实是__proto__的属性(此处存疑,因为是个人验证,不清楚上面的验证代码是否精准,如果有误,希望各位指出)。

    根据new的工作原理(详见http://www.cnblogs.com/ihardcoder/p/3667372.html),我们知道

    p.__proto__ = Person.prototype;

    所以

    p.constructor = p.__proto__.constructor = Person.prototype.constructor

    这样就将问题追溯到Person的prototype指向问题。当用Person.prototype = {}的方式重新定义时,同样根据new的工作原理,其实产生如下改变:

    Person.prototype.__proto__ = Object.prototype

    从而

    p.constructor 
    = Person.prototype.constructor 
    = Person.prototype.__proto__.constructor 
    = Object.prototype.constructor

    此时

    p.constructor === Object; //true

    如何避免constructor属性的混乱,归根结底,我们需要做的是保证instance的constructor属性指向Person.prototype.constructor,而不是Person的父类,所以当修改Person.prototype时需要保证Person.prototype.constructor指向自己。

    function Person(){
      this.name = name;
    }
    Person.prototype = {
      getName : function(){
        return this.name;
      }
    }
    Person.prototype.constructor = Person;
    var p = new Person('Joe');
    console.log(p.constructor === Person); //false
    console.log(p.__proto__ === Person.prototype); //true
  • 相关阅读:
    建造者模式的使用场景
    由于losf引起的pxc启动报错处理
    mysql5.6源码自动安装脚本
    mysql5.7.16二进制安装
    Maven入门
    数据链路层
    图-拓扑排序
    线性表-队列
    线性表-链表
    Java基本概念(未完)
  • 原文地址:https://www.cnblogs.com/ihardcoder/p/3667739.html
Copyright © 2020-2023  润新知