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

constructor属性解析的更多相关文章

  1. 【Spring源码深度解析学习系列】复杂标签属性解析(四)

    一.创建用于属性承载的BeanDefinition BeanDefiniton是一个接口,在Spring中存在三种实现:RootBeanDefinition.ChildBeanDefinition.G ...

  2. 揭开js之constructor属性的神秘面纱

    揭开 constructor 在 Javascript 语言中,constructor 属性是专门为 function 而设计的,它存在于每一个 function 的prototype 属性中.这个 ...

  3. CAGradientLayer的一些属性解析

    CAGradientLayer的一些属性解析 iOS中Layer的坐标系统: 效果: - (void)viewDidLoad { [super viewDidLoad]; CAGradientLaye ...

  4. 对象的constructor属性

    对象的constructor属性, 最初是用来标识对象类型的. 比如 ,我们定义一个 Person类,然后实例化两个对象. function Person(name, age, job){this.n ...

  5. JavaScript类型检测, typeof操作符与constructor属性的异同

    *#type.js function Person(name, age) { this.name = name; this.age = age; } var d = {an: 'object'}; v ...

  6. CAGradientLayer的一些属性解析-b

    CAGradientLayer的一些属性解析 iOS中Layer的坐标系统: 效果: - (void)viewDidLoad { [super viewDidLoad]; CAGradientLaye ...

  7. JavaScript 构造函数 prototype属性和_proto_和原型链 constructor属性 apply(),call()和bind() 关键字this

    1.构造函数: 通常构造函数首字母需要大写,主要是为了区别ECMAScript的其它函数.(高程三 P145) 构造函数与其他函数的唯一区别,就在于调用它们的方式不同.只要通过new来调用,任何函数都 ...

  8. Activity设置全屏显示的两种方式及系统自带theme属性解析

    转载说明:原贴地址:http://blog.csdn.net/a_running_wolf/article/details/50480386 设置Activity隐藏标题栏.设置Activity全屏显 ...

  9. constructor 属性,判断是否为数组

    <!--你可以使用 constructor 属性来查看是对象是否为数组 (包含字符串 "Array"):--><p>constructor属性返回变量或对象 ...

随机推荐

  1. powershell脚本找修改的文件

    $sourcedir="D:\workspace" $targetdir="E:\newf" $lastdate="2017-05-19" ...

  2. 爬取baidu的明星的名称及头像

    #!/1111111111usr/bin/env python# -*- encoding: utf-8 -*-# Created on 2018-11-15 15:24:12# Project: d ...

  3. Android中 实现队列方式处理优先级信息

    需求:当界面在处理消息A时,突然接收到消息B,需要立马显示B的信息,然后再继续显示消息A,或者接收到消息C,再显示完消息A后再显示消息C: 原理很简单 在一个轮询中,查询消息列表中的元素,先处理优先级 ...

  4. Python 打印矩形、直角三角形、等腰三角形、菱形

    # 1)打印一个星号 print('*') #2)打印一行6个星号 * * * * * * for i in range(6): print('*',end=' ') #3)打印6列星号 * * * ...

  5. js生成tree形组织机构下拉框

    1.首先我们正常数据是如下所示: [ { id: 1, pid: 0, name: '公司组织' }, { id: 2, pid: 1, name: '总经办' }, { id: 3, pid: 1, ...

  6. excel日期拾取插件(支持Excel 2007 - 2016)

    插件安装完毕后示意图如下: 插件安装说明请查看附件里面的安装说明. 插件下载

  7. String常用类

    一.String类String类在java.lang包中,java使用String类创建一个字符串变量,字符串变量属于对象.java把String类声明的final类,不能有类.String类对象创建 ...

  8. mount的几个选项

    一.mount -o noatime表示在读文件时不去更改文件的access time属性了,所以该选项会提升mount操作的执行效率. 二.mount --bind:等同于 -o bind可用于挂载 ...

  9. Oracle去除重复(某一列的值重复),取最新(日期字段最新)的一条数据

    转自 : http://blog.csdn.net/nux_123/article/details/45037719 问题:在项目中有一张设备检测信息表DEVICE_INFO_TBL, 每个设备每天都 ...

  10. 20155205 郝博雅 Exp9 Web安全基础

    20155205 郝博雅 Exp9 Web安全基础 一.实验内容 一共做了13个题目. 1.WebGoat 输入java -jar webgoat-container-7.1-exec.jar 在浏览 ...