假设:
var x = function () {
};
x.prototype = {
y: {
z: function () {
console.log(this);
}
}
};
var foo = new x();
foo.y.z();
为什么this
以console
而不是y
登录x
,如果y
是没有构造函数的文字对象,那怎么可能?
答案 0 :(得分:2)
“为什么在控制台中将其记录为y而不是x ...”
因为这就是JavaScript的工作原理。 this
值设置为从中调用方法的对象。通常,您应该将对象保留在.prototype
之外。它们将在使用构造函数创建的所有实例之间共享。
“......如果y是没有构造函数的文字对象,那怎么可能?”
这很容易。 this
值与任何构造函数无关。它是一个动态值,根据您调用函数或方法的方式设置。
有些实用程序可以让您手动覆盖调用中this
设置的自然值。使用.call
的{{1}}或.apply
方法调用该方法就是一个例子
Function.prototype
现在var foo = new x();
foo.y.z.call(foo);
方法中的this
将是z
对象,因为我们通过将其作为第一个参数传递给foo
来手动设置它。
.call
方法看到它被称为.call
方法的方法,因此它会为您调用z
,但设置z
的{{1}}值{1}}作为第一个参数提供的任何内容......在本例中为this
对象。
但通常你不会将对象用作z
的值。原因是从构造函数创建的所有实例都获得了对构造函数的foo
的隐式引用,因此将从所有实例中观察到.prototype
属性上任何对象的更新。
答案 1 :(得分:1)
要完成这项工作,您需要y
才能返回封闭的this
。
var x = function () {};
Object.defineProperty(x.prototype, "y", { get: function() { return this; } })
x.prototype.y.z = function () { console.log(this); }
var foo = new x();
foo.y.z(); // x
.
z()
左侧的this
是y
。在您的问题中,{z:function(){...}}
会返回对象字面值:{{1}}。
答案 2 :(得分:0)
var y=Object.create({z: function () { console.log(this); }});
var x=Object.create(y);
y.z();
x.z();
您可以使用Object.create来创建对象,而不是使用构造函数。