Javascript关闭混乱

时间:2014-01-10 17:49:56

标签: javascript closures

有人可以解释为什么会出现在Javascript中吗?

var singleton = window.singleton || {};
singleton.methods = (function () {
    var _private = function() {
        console.log('outer private function');
    }

    return {
        _private: function() {
            console.log('inner private');
        },

        public: function() {
            _private();
        }
    }
})();

singleton.methods.public();

我的直觉让我相信调用.public()应该记录'内部私有'。它没有。如果我将public()定义更改为this._private(),我会得到我期望的结果。为什么呢?

4 个答案:

答案 0 :(得分:2)

你有一个范围问题:_private函数中的public指的是构造闭包中定义的一个(闭包是由函数调用定义的,你返回的块没有定义一个范围)。

如果要记录返回的对象的_private方法,请将定义更改为

return {
    _private: function() {
        console.log('inner private');
    },

    public: function() {
        this._private();
    }
}

这是what the MDN says about closures

  

简而言之,闭包的父函数中的变量仍然与父级的范围绑定。

要解决_private功能中的public,您必须按顺序搜索

    {li>在public函数本身中
  1. 在紧邻的外部作用域中,即用于构建methods对象的闭包。该功能在那里找到
  2. 如果未找到,则将依次搜索外部范围(可能是全局范围)

答案 1 :(得分:0)

我的猜测是,你来自Java这样的语言,当引用不合格的成员名称时,this.隐含在对象的方法中。在JavaScript中,它不是,而且这是你问题的根源。

JavaScript中唯一的例外是顶级范围 - 浏览器中的window - 是专门处理的。如果我在顶级声明var foo = "bar",则会创建一个名为window foo的属性,其值为"bar",因此看起来会像您一样期待:

this.foo = "bar";
alert(foo); // shows bar
alert(this.foo); // also shows "bar"

但总的来说,在顶级范围之外,这不是真的。因此,名为public的函数正在查找名为_private的范围变量,并且名为_private - this._private的同一对象的属性不是该范围内的变量或其他任何变量。范围。

答案 2 :(得分:0)

记录inner private的函数是对象中的属性。仅使用其名称无法访问该属性,您必须指定它在对象中。

在像C#和Java这样的面向对象语言中,方法的范围包含来自对象的标识符,但它不像Javascript中那样工作。它只有函数作用域(和全局作用域),因此您无法在不指定它们所属的对象的情况下访问对象成员。

答案 3 :(得分:0)

你拥有的是一个封闭物。当您在闭包中返回一个函数时,该函数会被暴露,因此“公开”。闭包内的每个函数都保留其真正的私有范围。所以当你调用_private();从公共函数,你实际上是在调用内部函数。 你的public _private()属于构造函数,要求你应该为它应用一个合适的链。像这样:

this._private()