“这个”里面没有指向实例的嵌套原型

时间:2013-02-06 01:35:51

标签: javascript

假设:

var x = function () {
};

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

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

为什么thisconsole而不是y登录x,如果y是没有构造函数的文字对象,那怎么可能?

3 个答案:

答案 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()左侧的thisy。在您的问题中,{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来创建对象,而不是使用构造函数。