JavaScript中函数的prototype原型对象的constructor为什么明明已经改过来了,但new出来的对象中的constructor却还是原来的?
具体请看下面的代码和注释:
function CreateObject(pPrototypeClass, pParams)
{
function Temp()
{
pPrototypeClass.Create.apply(this, pParams);
alert('2.Temp.prototype.constructor: ' + Temp.prototype.constructor); //此时Temp.prototype.constructor为Temp函数本身
Temp.prototype = pPrototypeClass;
alert('3.Temp.prototype.constructor: ' + Temp.prototype.constructor); //此时Temp.prototype.constructor已变为Object函数
};
alert('1.Temp.prototype.constructor: ' + Temp.prototype.constructor); //此时Temp.prototype.constructor为Temp函数本身
alert('pPrototypeClass.constructor: ' + pPrototypeClass.constructor); //pPrototypeClass.constructor为Object函数
return new Temp();
};
var PersonPrototypeClass =
{
Create: function(pName, pAge)
{
this.name = pName;
this.age = pAge;
},
SayHello: function()
{
alert("Hello, I'm " + this.name);
},
HowOld: function()
{
alert(this.name + " is " + this.age + " years old.");
}
};
var oPerson = CreateObject(PersonPrototypeClass, ["Bill Gates", 53]);
alert('oPerson.constructor: ' + oPerson.constructor); //这里oPerson.constructor却仍然是Temp函数!为什么?前面Temp.prototype.constructor不是已改为Object函数了吗?
alert(oPerson.constructor == Object); //为false,按道理应该为true
但如果把Temp函数的这一句Temp.prototype = pPrototypeClass;移动到外层函数CreateObject中,如下:
function CreateObject(pPrototypeClass, pParams)
{
function Temp()
{
pPrototypeClass.Create.apply(this, pParams);
alert('3.Temp.prototype.constructor: ' + Temp.prototype.constructor); //此时Temp.prototype.constructor已变为Object函数
};
alert('1.Temp.prototype.constructor: ' + Temp.prototype.constructor); //此时Temp.prototype.constructor为Temp函数本身
Temp.prototype = pPrototypeClass;
alert('2.Temp.prototype.constructor: ' + Temp.prototype.constructor); //此时Temp.prototype.constructor已变为Object函数
alert('pPrototypeClass.constructor: ' + pPrototypeClass.constructor); //pPrototypeClass.constructor为Object函数
return new Temp();
};
var PersonPrototypeClass =
{
Create: function(pName, pAge)
{
this.name = pName;
this.age = pAge;
},
SayHello: function()
{
alert("Hello, I'm " + this.name);
},
HowOld: function()
{
alert(this.name + " is " + this.age + " years old.");
}
};
var oPerson = CreateObject(PersonPrototypeClass, ["Bill Gates", 53]);
alert('oPerson.constructor: ' + oPerson.constructor); //这里oPerson.constructor已变为Object函数
alert(oPerson.constructor == Object); //为true
为什么Temp.prototype = pPrototypeClass;这句语句在Temp函数体内和移动到外层函数体内,结果就不一样呢?
———————————————————————————————————————————
20151209补充:
感谢各位的回答,每位答主都从不同角度部分地解答了我的部分疑惑。现在我的看法是,关键在于new一个构造函数的时候,到底发生了什么?下面总结一下我现在的理解。new一个构造函数的时候,依次发生了如下三个步骤:
1)创建一个空的新对象。
2)将新对象的隐式原型属性__proto__赋值为构造函数的显式原型属性prototype,即新对象.__proto__ = 构造函数.prototype。
3)执行构造函数,并且同时将构造函数中的this指向新对象,即构造函数.call(新对象)。
因此,new一个构造函数时,是先将该构造函数的prototype赋值给新对象的__proto__,然后才执行构造函数;而不是先执行构造函数,然后才赋值prototype。这两个步骤的顺序,才是问题中前后两段代码的运行结果不同的原因。
再次感谢各位的回答!
这个结果不一样这是正常的,你放在里面的时候,在你n做new动作之前你还没有改变Temp.prototype,new 动作在之前,new temp 就是在操作prototype。你这个是没有变化的,另外new 动作之后 做Temp.prototype 只是动态改变了Temp.prototype的属性。constructor 还是Temp。
并且 就算你改变了Temp.prototype,你也没有返回 已经坐更改的Temp,当然此刻按照你的写法返回Temp 的实例 就是一个死循环了。 你可以断点跟踪一下 当你改变了Temp.prototype,然后再new出来的对象 已经发生了变化了