在最开始学习js的时候,我们在讲到原型链和构造函数的时候经常会有一个例子
如果我们定义函数如下:
function Foo() { /* .. */ }
Foo.prototype.bar = function(){};
var a1 = new Foo();
a1.constructor === Foo; // true!
但是如果我们中间改变了Foo.prototype的定义,那么a1.constructor的指向就改变了。
function Foo() { /* .. */ }
Foo.prototype = { /* .. */ }; // 创建一个新原型对象
var a1 = new Foo();
a1.constructor === Foo; // false!
a1.constructor === Object; // true!
对于这个事实,这里通过我的理解来解释一下。
首先js中并没有像java这种面向对象语言一样,Foo并不是作为一个类存在,而是普通的函数。当new操作符执行的时候,Foo函数作为构造函数调用,形成a1的原型链,将a1的__proto__关联到Foo.prototype,也就是说这里并不是复制的关系,只是关联,Foo.prototype改变时,a1.__proto__也会改变。
在第一个例子中a1.constructor === Foo;看起来是a1的constructor指向了Foo,但是事实并非如此。实际上,是在new的时候,a1.constructor被委托给了Foo.prototype.constructor,所以当第二个例子Foo.prototype = {}时,a1.constructor就不再指向Foo了,而是指向了Object。因为如下例子:
var Foo ={};
console.log(Foo.constructor === Object);//true
也就是Foo.prototype的constructor属性只是在Foo函数声明的时候默认生成的。如果替换了Foo.prototype的引用,那么constructor也会随之发生改变。
总结:
1. constructor属性会在函数声明时默认生成。在利用new创建对象实例时,对象实例本身并没有constructor属性,但对象实例的__proto__属性和Foo.prototype属性关联,形成原型链,因此会通过原型链找到Foo.prototype.constructor属性,并以此为值。
2. prototype属性可能会被重写,重写后,原来的constructor会发生改变。如果显示为constructor赋值,可以纠正。
3. 因为constructor的属性很随意,所以慎用。
文摘归档
- 2019年02月(1016)
- 2019年01月(1698)
- 2016年10月(1)
- 2016年09月(11)
- 2016年07月(43)
- 2016年06月(37)
- 2016年05月(77)
- 2016年04月(62)
- 2016年03月(32)
- 2016年02月(4)
- 2016年01月(10)
- 2015年12月(3)
- 2015年11月(6)
- 2015年10月(8)
- 2015年09月(14)
- 2015年08月(453)
- 2015年07月(41)
- 2015年06月(36)
- 2015年05月(44)
- 2015年04月(46)
- 2015年03月(51)
- 2015年02月(24)
- 2015年01月(45)
- 2014年12月(34)
- 2014年11月(40)
- 2014年10月(56)
- 2014年09月(52)
- 2014年08月(66)
- 2014年07月(55)
- 2014年06月(83)
- 2014年05月(79)
- 2014年04月(64)
- 2014年03月(48)
- 2014年02月(46)
- 2014年01月(28)
- 2013年12月(63)
- 2013年11月(77)
- 2013年10月(72)
- 2013年09月(62)
- 2013年08月(83)
- 2013年07月(60)
- 2013年06月(21)
阅读排行榜
- Cocos2D-x之开发环境配置 (4689)
- TLS 协议所定义的严重错误代码是 10。Windows SChannel 错误状态是 1203 (3753)
- UART和RS232、RS485的基础知识 (3493)
- 本地文件数据加载到hive (3261)
- WAS8.0与IHS集群安装与配置指导手册 (3021)
- C/C++常见编译链接错误解决方法 (2419)
- 如何重定向Keepalived日志的输出路径 (2278)
- devstack安装报错解决方法:pkg_resources.DistributionNotFound: pip==1.4.1 (1480)
- HAProxy 研究笔记 -- HTTP请求处理-2-解析 (1206)
- iOS项目开发实战——Swift实现多个TableView的侧滑与切换 (1060)