【问题标题】:Does JavaScript have a variable for items declared in the function's scope? [duplicate]JavaScript 是否有一个用于在函数范围内声明的项目的变量? [复制]
【发布时间】:2013-05-16 03:33:56
【问题描述】:

JavaScript 是否有一个用于在函数范围内声明的项目的变量?我想访问使用关联数组在函数内声明的项目。

例如,我可以对全局范围内的项目执行以下操作

    var globalVar = "hi";
    var myFunction = function () {
        alert(window["globalVar"]);
    };

但我想对函数内声明的变量做类似的事情

    var myFunction = function () {
        var funcVar = "hi";
        alert(func["funcVar"]);
    };

我意识到做这样的事情不一定是一件好事,我正在做下面的事情,但我仍然对 JavaScript 是否有这样的变量感兴趣。

    var myFunction = function () {
        var func = {funcVar : "hi" };
        alert(func["funcVar"]);
    };

【问题讨论】:

    标签: javascript


    【解决方案1】:

    这个问题已经被问过很多次了。 不,在 JavaScript 中没有包含局部变量作为属性的局部对象(例如,在浏览器环境中,window 对象包含全局变量作为属性)。

    根据您要完成的任务,可能有许多替代方法可以攻击它,包括您现在使用的方法。

    Javascript: Get access to local variable or variable in closure by its nameHow can I access local scope dynamically in javascript?Javascript local variable declare 的重复。

    【讨论】:

    • 那么请将其标记为重复。我确实搜索过它,但在一堆谈论函数范围的话题中迷失了。
    【解决方案2】:

    也许您可以将属性分配给函数对象本身,并引用它们?

    var myFunction = function() {
        myFunction.funcVar = 'hi';
        alert(myFunction['funcVar']);
    };
    

    这并不完全是您问题的答案,但这是我能想到的将局部变量作为对象属性访问的最佳方式。请注意,在此方法中,这些变量将以相同的方式在函数外部可见(即查找函数的属性)。

    如果您确实需要隐藏这些属性,可以将它们隐藏在闭包中,如下所示:

    var myFunction = function() {
        (function hidden() {
            hidden.funcVar = 'hi';
            alert(hidden['funcVar']);
        })();
    };
    

    【讨论】:

      【解决方案3】:

      函数只是可以调用的特殊对象。您可以设置函数的属性,并在以后获取它们。

      var a = function () {
          alert(a.testingVar);
      };
      
      a.testingVar = "asdf";
      
      a();
      

      演示: http://jsfiddle.net/gEM7W/

      虽然我没有看到理由/需要这样做。您始终可以使用闭包来保留特定于函数的局部变量。例如:

      var a = (function () {
          var obj = {
              testingVar: "asdf"
          };
          return function () {
              alert(obj.testingVar);
          };
      })();
      
      a();
      

      演示: http://jsfiddle.net/gEM7W/1/

      【讨论】:

        【解决方案4】:

        您实际上并没有关联数组。你有索引数组,你有对象。

        将来,会有一个迭代器可以愉快地遍历两者,没有任何副作用。到那时,也许人们会忘记其中的区别。

        但是,这些属性仍然不是基于顺序的:

        $arr = array(0, 1, "name"=>"Bob", 3);
        

        在另一种语言中,您可能会得到一个键所在的数组:0, 1, "name", 3
        在 JS 中,你会得到0, 1, 2, "name"(或"name", 0, 1, 2)。

        所以坚持使用索引数组和具有属性的对象。

        也就是说,您有多种选择。

        var myFunc = function () {
            var private_data = {
                name : "Bob",
                age : 32
            };
        
            return {
                getName : function () { return private_data.name; /* or private_data["name"] if that's really what your heart longs for */ },
                get : function (key) { return private_data[key] || null; },
                set : function (key, val) { private_data[key] = val; }
            };
        };
        

        现在一切都是私有的,您可以通过属性名称、使用点或括号表示法来访问它们。

        如果它们可以是公共的,并且函数总是会被调用相同的东西(即:不是创建实例的构造函数),那么您可以将自己附加到实际函数:

        var myFunc = function () {
            myFunc.name = "Bob";
            myFunc["age"] = 32;
        
        
            return {
                get : function (key) { return (myFunc.hasOwnProperty(key)) ? myFunc[key] : null; }
            };
        };
        

        缺点(或优点)是myFunc 是公共名称。因此,这些属性是可公开访问的。

        走第一条路,你甚至不需要声明一个变量。您可以只使用传递给函数的对象。

        var myFunc = function (dataObj) {
            return {
                getName : function () { return dataObj.name; },
                setAge  : function (val) { dataObj["age"] = val; }
            };
        };
        
        var bob = myFunc({ name : "Bob" });
        bob.setAge(32);
        

        现在一切都是私密的,我什至不必声明任何内容。
        只要返回了一个可公开访问的函数,闭包就会使对象保持运行,该函数仍然可以访问该函数调用的特定实例。

        一旦你弄清楚了闭包,这就不是问题了。

        【讨论】:

        • 我很欣赏这个答案所付出的努力,但我不确定它如何回答我的问题。
        • @row1 好吧,除了“否”之外,还有其他选择,具体取决于您实际尝试做什么价值观。您是否尝试复制 OO 封装?您是否尝试遍历当前范围内的变量?您是否尝试通过闭包从外部范围迭代/访问它们?你关心这个显然是有原因的,而不仅仅是:“它是否存在”。虽然将属性附加到对象是解决该问题的第一步,但您的第二步或第三步是什么?无论如何,如果你什么也没做,那为什么还要问呢?
        • 我的问题几乎包含了我想要做的事情,也包含了一个我很满意的解决方案。我只是想知道是否有我可能缺少的函数的特殊内置变量(比如有参数)。
        • 有/有。我们只是无法从语言中访问它们,就像我们无法访问允许冻结/不变性或枚举等属性的属性一样,尽管它们是来自 JS 引擎实现的语言的一部分看法。消费者方面... ...不。但这就是不同模式的用途。
        猜你喜欢
        • 1970-01-01
        • 2018-07-12
        • 2010-11-23
        • 2020-07-31
        • 2014-08-22
        • 2022-11-30
        • 1970-01-01
        • 2021-04-12
        • 1970-01-01
        相关资源
        最近更新 更多