在JavaScript对象中访问内部变量

4

考虑以下有错误的代码:

x = {
  y : "why",
  z : function() {
    return y + " zed";
  }
}

函数z无法正常工作:“ReferenceError:y未定义”。

是否有一种方法可以在不完全指定为x.y的情况下从函数z中访问y?

当然,我可以将其重写为

x = function() {
  var self = this;
  this.y = "why";
  this.z = function() {
    return self.y + " zed";
  };
  return this;
}();

... but gosh.

4个回答

3

如果您使用x.z()调用函数,请使用this

var x = {
    y : "why",
    z : function() {
        return this.y + " zed";
    }
};

DEMO: http://jsfiddle.net/hZxVu/


3
这并非绝对可靠——考虑变量 z = x.z; z(); //"undefined zed"。 - meouw
@meouw 的确,除此之外我看不到其他选项,只能采用 OP 的“重写”变体。 - VisioN
@meouw 很好的观点。我也错过了那个。我想你可以通过闭包来复杂化事情,以确保y始终存在:http://jsfiddle.net/YpX3B/ - jatrim
与@meouw相反,我认为你不应该执行var z=x.z; z();,因为你永远不能假设函数可以在脱离其原始拥有对象的情况下被调用。相反,你应该执行varz=x;z.call(x);,所以我认为这不是一个有效的反对意见。 - I-Lin Kuo

0

@VisioN 给出了直截了当的答案。如果您将代码重写为以下形式,可能有助于可视化为什么需要这样做:

var x = {};
x.y = "why";
x.z = function() {return this.y + " zed"; };
alert(x.z());

这里的y和z是对象的属性,但没有函数闭包作用域。您需要使用"this"关键字来访问父对象的属性。

或者,

var x = function () {
    var y = "why";     
    var z = function () { return y + " zed?"; };    
    return z();
};
alert(x());

这展示了通过不使用 this 访问 y 的函数作用域。在 x 内部,y 是已知的。而在外部,则不是。


0
不可以,你需要重写它。 y 是该对象的属性,没有对象就无法访问它 - 不像是从闭包中访问变量(例如在您的重写中的self)。
当然,当您将函数作为x.z()调用时,this关键字也会指向该对象,因此您可以编写如下内容。
return this.y + " zed";

只要您始终在该对象的上下文中调用函数即可。

0
使用揭示模块模式:
    var x = (function () {
        y = "why";
        z = function() {
            return y + " zed";
        };
        return {
            "y": y,
            "z": z
        };
    })();

    //now you can call:
    x.y // "why"
    x.z() // "why zed"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接