鉴于:
var x = function () {
};
x.prototype = {
y: {
z: function () {
console.log(this);
}
}
};
var foo = new x();
foo.y.z();
为什么this登录consoleasy而不是,x以及如何给定y一个没有构造函数的文字对象?
鉴于:
var x = function () {
};
x.prototype = {
y: {
z: function () {
console.log(this);
}
}
};
var foo = new x();
foo.y.z();
为什么this登录consoleasy而不是,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 来创建对象,而不是使用构造函数。