学习JavaScript变量范围和对象实例化

时间:2009-12-18 00:10:10

标签: javascript scope instantiation anonymous-function

var foo = (function() {
    var proxy = {},
        warning = false;

    proxy.warn = function(msg) {
        if (!warning) {
            warning = true;
            alert(msg);
        }
        return this; //For the purpose of method chaining we return proxy object.
    }

    function func() {
        alert(warning); //This is a private function relative to foo.
    }

    return proxy;
}());

foo.warn(); //will alert
foo.warn(); //will not alert since warning has been set to true

我对这里的实例化感到困惑,因为没有使用持有警告值的新关键字?在范围警告的存在方面是否有任何泄漏。

谢谢。

4 个答案:

答案 0 :(得分:2)

a位于顶部闭包函数function() {...

foo持有您要返回的代理对象,这意味着不在此代理对象中的所有内容都是私有的,无法从foo访问。如果您想获得a的值,可以添加一个返回a =>

的新函数
proxy.getValueOfA=function(){return a}

然后你可以拨打foo.getValueOfA()

作为评论:

var proxy={}

var proxy=new Object()的缩写形式,因此存在异化。

答案 1 :(得分:1)

这个对另一个问题的回答确实帮助我扩展了对javascript对象如何工作的理解:

JavaScript function aliasing doesn't seem to work

至于你的代码片段,让我们分解它。首先看一下高级结构:var foo = ( exrpession );。您可以轻松地说:var foo = expression;,但IIRC需要使用括号来处理特定于IE的怪癖。

现在,在这种情况下,表达式是一个匿名函数。定义一个没有名字的函数,Javascript非常好。除非你在某处保存一个引用,否则不要指望它。您也可以在声明后立即调用匿名函数,如下所示:

function() {
     alert('test');
     return 42;
}();

这应该看起来与您的代码段中用于表达式的基本结构有些相似。希望你可以很容易地看到我的样本中的42可以很容易地成为一个对象。

所以问题仍然存在,你为什么要这样做?请记住,在javascript中,函数也是对象。作为OOP的优秀学生,您可能希望将对象的某些成员设为私有。但是,javascript没有任何内置支持这一点。幸运的是,如果从该内部函数返回一个对象,它将会访问该函数中定义的其他变量,但外部代码将无法访问它们。实际上,您已经创建了一个包含私有成员的对象。

答案 2 :(得分:1)

proxy.methodfunc都可以通过closure property访问a。有关范围和对象的更多信息,请查看最近浮出水面的这篇文章: A Concise, Executable Guide to JavaScript Objects, Variables, Functions, and Prototypes

您发布的代码符合所谓的“module pattern”,并且正在成为一种在JavaScript中定义对象的非常流行的方式,因为它使私有变量和方法易于创建(通过利用关闭属性,如前所述)。

答案 3 :(得分:1)

    return proxy;
}());

应该是这个

    return proxy;
})();

和这个

function() {
     alert('test');
     return 42;
}();

不起作用...语法错误。你应该在把它放在这里之前尝试你的代码。很确定你的意思是:

(function() {
     alert('test');
     return 42;
})();

另外,你回归私人会员的那种事实会破坏范围关闭的全部内容,但它会起作用......

var foo = (function() {
    var proxy = {}, // private
    proxy.warn = function(msg) {
    ...
    return proxy; // publicly accessible

相同
var foo = { warn: function(){ /* code */ } };