鉴于:
var x = function () {
};
x.prototype = {
y: {
z: function () {
console.log(this);
}
}
};
var foo = new x();
foo.y.z();
为什么this
登录console
asy
而不是,x
以及如何给定y
一个没有构造函数的文字对象?
鉴于:
var x = function () {
};
x.prototype = {
y: {
z: function () {
console.log(this);
}
}
};
var foo = new x();
foo.y.z();
为什么this
登录console
asy
而不是,x
以及如何给定y
一个没有构造函数的文字对象?
“为什么这在控制台中记录为 y 而不是 x...”
因为这就是 JavaScript 的工作方式。该this
值被设置为调用该方法的对象。一般来说,你应该让物体远离.prototype
. 它们将在使用构造函数创建的所有实例之间共享。
“......鉴于 y 是一个没有构造函数的文字对象,这怎么可能?”
这很简单。该this
值不与任何构造函数绑定。它是根据您调用函数或方法的方式设置的动态值。
有一些实用程序可让您手动覆盖this
调用中设置的自然值。使用 的.call
或.apply
方法Function.prototype
来调用方法就是一个例子
var foo = new x();
foo.y.z.call(foo);
现在方法this
中将z
是foo
对象,因为我们通过将其作为第一个参数传递给.call
.
该.call
方法看到它被称为方法的z
方法,因此它z
为您调用,但将this
值z
设置为您作为第一个参数提供的任何内容......在这种情况下是foo
对象。
但通常你不会使用对象作为.prototype
. 原因是从构造函数创建的所有实例都获得对构造函数的隐式引用,因此从所有实例中都会观察到.prototype
对属性的任何对象的更新。.prototype
要完成这项工作,您需要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
.
on左边z()
是this
. 在您的问题中,y
返回对象文字:{z:function(){...}}
。
var y=Object.create({z: function () { console.log(this); }});
var x=Object.create(y);
y.z();
x.z();
您可以使用 Object.create 来创建对象,而不是使用构造函数。