2009-12-18 59 views
0
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 

因为没有使用new关键字,所以我对这里的实例化感到困惑,谁持有警告的值?根据警示生命的范围,是否有任何泄漏。学习JavaScript变量作用域和对象实例

谢谢。

回答

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中,函数也是对象。作为面向对象的优秀学生,您可能希望让对象的某些成员变为私有。不过,JavaScript没有内置任何内容来支持这一点。幸运的是,如果您从该内部函数返回一个对象,它就会访问该函数中定义的其他变量,但是外部代码将无法访问它们。所以你实际上已经创建了一个包含私有成员的对象。

+0

@Joel:我已经更新了代码,以显示为什么我需要这样的私有变量。谢谢。 – Jeff 2009-12-18 00:57:45

2

好吧a住顶部封闭功能function() {...

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

proxy.getValueOfA=function(){return a} 

,那么你可以调用foo.getValueOfA()

这样一句话:

var proxy={} 

是短期形式var proxy=new Object()所以有一个instanciation。

+0

'var proxy = {}'代码使用了一种称为紧凑对象符号的东西。这是一个捷径,不需要在任何地方创建一个对象。 – 2009-12-18 00:43:37

+0

因为Joel Coehoorn说{}等价于新的Object(),因为[]等同于新的Array() – Patrick 2009-12-18 00:49:33

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 */ } }; 
+0

@Dan:为什么你说“打破了范围关闭的整个观点”,我想持有一个专用开关该警报应该被解雇或没有。 – Jeff 2009-12-18 01:23:47

+0

是的,你是对的,这会做到这一点。也许我没有看看你想做什么,只是你怎么做。无论哪种方式,匿名函数中的var都是私有的,所以它只能被公共或受保护的成员访问。我习惯于在退货声明中返回我的公共成员(这样,您可以在视觉上/逻辑上将您的私有/受保护成员分开) window.foo =(function(){ var warning = true; return({warn :function(msg){return(warning?alert(msg):this);}}); })(); – 2009-12-18 10:52:14