JavaScript对象字面量 - 嵌套函数和"this"关键字

11
在下面的示例中,当调用 functionA() 时,this 关键字指向包含它的对象,因此我可以访问其属性(例如 theValue)。 我的问题:我如何从嵌套的 functionB() 中引用 myObj 的属性?
var myObj = {
    theValue: "The rain in Spain", 
    functionA: function() {
        alert(this.theValue);
    },
    moreFunctions: {
        functionB: function() {
            alert(????.theValue);
        }
    }
}

myObj.functionA(); 
myObj.moreFunctions.functionB();  

提前致谢。

3个回答

10

立即调用来拯救!

var myObj = (function () {
    var that = {
        theValue: "The rain in Spain", 
        functionA: function() {
            alert(this.theValue); // or that.theValue, both work here
        },
        moreFunctions: {
            functionB: function() {
                alert(that.theValue);
            }
        }
    };
    return that;
}()); // <-- immediate invocation !!

你甚至可以将它进一步分解:

var myObj = (function () {
    function functionA() {
        alert(that.theValue);
    }
    function functionB() {
        alert(that.theValue);
    }
    var that = {
        theValue: "The rain in Spain", 
        functionA: functionA,
        moreFunctions: {
            functionB: functionB
        }
    }
    return that;
}());
如果您熟悉面向对象编程(OOP),您可以使用它来创建私有变量。

如果您熟悉面向对象编程(OOP),您可以使用它来创建私有变量。


我对应该接受哪个答案感到困惑。elclanrs的建议(alert(myObj.theValue);)可以工作(无需重构),但是Frits的解决方案(以及更多的研究)提供了关于闭包、立即调用和如何使用它来创建私有变量的信息,因此我基于这个原因接受了这个答案。谢谢大家。 - Bumpy

6

3

一种常见的做法是定义一个 "self" 变量并使用它,而不是使用 "this" 关键字。这在您希望添加作用域或创建类时非常有帮助。

var myObj = new function(){
    var self = this;
    this.theValue = "The rain in Spain";
    this.functionA = function() {
        alert(self.theValue);
    },
    this.moreFunctions = {
        functionB: function() {
            alert(self.theValue);
        }
    }
   }();

   myObj.functionA();
   myObj.moreFunctions.functionB();

另一种可能性是使用ECMA5 Function.prototype.bind方法。简单来说,您可以绑定方法的“this”关键字。请参考链接以获取更多详细信息。如果您使用此方法,请注意它不兼容旧版浏览器,但提供的链接显示了您可以在旧版浏览器中使用的替代实现方式。
var myObj = new function(){
    this.theValue = "The rain in Spain";
    this.functionA = function() {
        alert(this.theValue);
    }.bind(this);
    this.moreFunctions = {
        functionB: function() {
            alert(this.theValue);
        }.bind(this)
    };
}();

myObj.functionA();
myObj.moreFunctions.functionB();

Nop: http://jsbin.com/ofehap/1/edit,其中的`this`是`window`。`this`在函数内部适用,并且上下文取决于你如何调用该函数。 - elclanrs
1
我认为你没有理解重点。在你的编辑之后它可以工作,但是你只是改变了数据结构。另外,使用bind选项将不起作用,因为this仍然是window - elclanrs
你说得对,当我最初阅读时,我想到的是一个函数,而不是一个简单干净的JSON结构。我修复了代码,使其按照我最初的意图工作,但如果你想保持干净的JSON,我不建议将其作为答案。然而,作用域确实使它更具吸引力。 - andrewjsaid
我会取消对你的点踩,因为你已经尽力了,但是这并不是一个好的答案。关于作用域,你可以采用像@FritsvanCampen所提供的模块模式方法。 - elclanrs

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