function Tt(){
this.name = "hello";
this.age = 88;
if(typeof this.say != "function"){
Tt.prototype = {
constructor: Tt,
say: function(){
return this.name;
}
};
}
}
var t = new Tt();
**console.log(t.say()); // Uncaught TypeError: Object #<Tt> has no method 'say' 这里为什么访问不到方法???**
// 如果这么做
function Tt(){
this.name = "hello";
this.age = 88;
if(typeof this.say != "function"){
Tt.prototype.say = function(){
return this.name;
}
}
}
var t = new Tt();
**console.log(t.say()); // 这样就没有问题!**
小白,不知道为什么这样??希望帮忙解释一下~
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
It creates a new object.
It sets the constructor property of the object to Vehicle.
It sets up the object to delegate to Vehicle.prototype.
It calls Vehicle() in the context of the new object.
通俗的说,t在实例化的时候,原型是Tt.prototype指向的对象,所以
然后构造函数执行了
但是注意了,Tt.prototype的引用改变了,不代表t原型改变了
例如
@小杰控 说的对!最后才会调用构造器,并以开始创建的空对象当做构造器里面的
this来调用构造器的。如果你在函数定义下面立即调用一下这个函数就不会报错,但是这个
say并不是你赋值的say。@小杰控 说的是正确的啊,为什么把人家的答案忽略了?
你的问题可以分为两个点:
new操作符做了啥对象字面量赋值和对象属性赋值两者的区别
第一点小杰的答案就是了,
new操作符会先生成个继承了这个构造器原型的对象,然后再把这个对象绑定到构造函数的this中,最后再执行构造函数。也就是说你在改变构造函数原型方法之前,你的对象实例实际上就已经生成了。第二点就是 @crp205 所说的了。
形如
obj = {}的对象字面量整体赋值,这是创建个新对象,并把这个新对象的引用交给等式的左值。形如
obj.say = ...的对象属性赋值,这个是给已经存在的对象中添加新的属性。在你的第一个例子中,生成的第一个对象实例之后,这个实例的原型和构造函数的原型实际上已经不是同一个了。
而第二个例子,它们的原型引用的是同一个原型,所以它可以找到
say方法。另外,在你的第一个例子中,你可以再创建第二个实例,看看这个实例能否使用
say方法。