JavaScript中每个对象都有其构造器函数,constructor属性指向其构造器函数,但constructor并不总是能找到其构造器,为什么?。
constructor是什么?
看下面:
var log=console.log.bind(console);
//创建构造器函数
var F=function(name){
this.name=name;
};
var obj=new F("li");//new 一个对象
log(obj.constructor);//指向F本身
//false,constructor并非自身属性
log(obj.hasOwnProperty("constructor"))
//true,而是obj.constructor.prototype属性,也就是F.prototype的属性,由obj继承而来 log(obj.constructor.prototype.hasOwnProperty("constructor"));
等同于
log(F.prototype.hasOwnProperty("constructor"));
在创建构造器函数的时候会自动创建一个空的原型对象,constructor是其原型对象的属性,指向函数本身。
由此,此构造器函数new的对象都继承constructor属性,并以此找到其构造器。
但为什么说constructor并不总是可靠的呢?
看下面的例子:
<script>
//创建一个构造器
var F=function(name){
this.name=name;
};
//为构造器添加公共的属性、方法
F.prototype.category="human";
F.prototype.say= function () {
alert("Hello "+this.name+ " you are a "+this.category)
}
var myobj=new F('liux');
myobj.say();//Hello liux you are a human
log(myobj.constructor);//指向F本身
</script>
或者直接使用对象覆盖的方法添加原型
//创建一个构造器
var F=function(name){
this.name=name;
};
//为构造器添加公共的属性、方法
var obj={
category:"human",
say: function () {
alert("Hello "+this.name+ " you are a "+this.category)
}
};
F.prototype=obj;//直接将F的原型覆盖
var myobj=new F('liux');
myobj.say();//Hello liux you are a human
//结果没有变化
log(myobj.constructor);//猜猜是什么
是function Object,为什么功能一样,constructor会变化呢,聪明的你已经想到,obj是我们创建的对象直接量,所以obj继承了内置构造器Function Object函数的原型对象,也就是Object对象的constructor的属性,指向Function Object,当我们执行F.prototype=obj;的时候F的原型对象整个被覆盖了,所以此时myobj的constructor的指向就不正确了。
怎么解决?
重置constructor,
当使用对象覆盖的方法添加原型的时候,需要重置constructor
//创建一个构造器
var F=function(name){
this.name=name;
};
//为构造器添加公共的属性、方法
var obj={
category:"human",
say: function () {
alert("Hello "+this.name+ " you are a "+this.category)
}
};
F.prototype=obj;//直接将F的原型覆盖
//增加的部分
F.prototype.constructor=F;
//或者obj.constructor=F;
var myobj=new F('liux');
myobj.say();//Hello liux you are a human
//结果没有变化
log(myobj.constructor);//F本身
至此constructor是什么,在哪里,怎么用,弊端,如何修正已经解决