1

鉴于:

var x = function () {
};

x.prototype = {
    y: {
        z: function () {
            console.log(this);
        }
    }
};

var foo = new x();
foo.y.z();

为什么this登录consoleasy而不是,x以及如何给定y一个没有构造函数的文字对象?

4

3 回答 3

2

“为什么这在控制台中记录为 y 而不是 x...”

因为这就是 JavaScript 的工作方式。该this值被设置为调用该方法的对象。一般来说,你应该让物体远离.prototype. 它们将在使用构造函数创建的所有实例之间共享。


“......鉴于 y 是一个没有构造函数的文字对象,这怎么可能?”

这很简单。该this值不与任何构造函数绑定。它是根据您调用函数或方法的方式设置的动态值。


有一些实用程序可让您手动覆盖this调用中设置的自然值。使用 的.call.apply方法Function.prototype来调用方法就是一个例子

var foo = new x();
foo.y.z.call(foo);

现在方法this中将zfoo对象,因为我们通过将其作为第一个参数传递给.call.

.call方法看到它被称为方法的z方法,因此它z为您调用,但将thisz设置为您作为第一个参数提供的任何内容......在这种情况下是foo对象。


但通常你不会使用对象作为.prototype. 原因是从构造函数创建的所有实例都获得对构造函数的隐式引用,因此从所有实例中都会观察到.prototype对属性的任何对象的更新。.prototype

于 2013-02-06T01:40:42.370 回答
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

.on左边z()this. 在您的问题中,y返回对象文字:{z:function(){...}}

于 2013-02-06T01:44:17.177 回答
0
var y=Object.create({z: function () { console.log(this); }});
var x=Object.create(y);
y.z();
x.z();

您可以使用 Object.create 来创建对象,而不是使用构造函数。

于 2013-02-06T03:20:29.463 回答