Javascript:如何获取函数内的父键?

时间:2013-06-04 18:36:53

标签: javascript arrays function

我有一些函数,存储在一个集合/数组中,想要获取密钥(函数名)而无需重新输入。有没有简短的方法来访问它?

var functions_collection = {
    "function_x": function() {
        var name = "function_x";
        // name = this.key; <- how to get the key/function-name "function_x"?

        // some more code like:
        $(".function_x .button").val();

        alert(name);
    }
}

编辑:我想避免重新输入函数本身内部的“function_x”,而宁愿像this.key那样调用它。

对于这个奇怪的主题感到抱歉,并提前致谢!

解决方案:很多很好的答案,但我只是在寻找这个剪辑:

Object.keys(this)

5 个答案:

答案 0 :(得分:4)

我不确定这是你想要的,但你可以这样做:

    var functions_collection = {};
    (function(name){
       functions_collection[name] = function(){
           // use name, which is the function
           alert(name);
       };
    })("function_x");

我不确定它会更好。但是根据你的(未指明的)目标,可能有更好的解决方案。

答案 1 :(得分:3)

在我看来,你需要改变你的代码,因为你有匿名的功能没有名字 - 这样的改变应该有效:

var functions_collection = {
  'function_x' : function function_x () {
    var myName = arguments.callee.name;
    alert(myName);
  }
}

请参阅http://jsfiddle.net/9cN5q/1/

答案 2 :(得分:3)

要获取对象键的名称,您可以使用Object.getOwnPropertyNames(this)或更新的浏览器Object.keys(this),这将获得this对象的所有键和任何键的数组有:

var functions_collection = {
    function_x: function() {
        var name = Object.keys(this);
        console.log(name);
    }
}

FIDDLE

答案 3 :(得分:3)

有几种方法可以去这里。有些是好主意,有些则不是。

首先,一些不好的想法

  1. 糟糕的主意: arguments.callee.name

    这最直接地转化为您的要求。 arguments.callee是 对您当前所在职能的引用。但是,it's considered bad practice, 除非你有充分的理由,否则你应该避免使用它。

  2. 糟糕的主意: Currying

    构造函数后,将自己的名称绑定到参数中:

    var functions_collection = {
        "function_x": function(name) {
            alert(name);
        },
        //more functions
    };
    for (var name in functions_collection) {
        if (typeof functions_collection[name] === "function") {
            functions_collection[name] = 
                functions_collection[name].bind(functions_collection, name);
        }
    }
    

    Currying对JavaScript中的很多东西都很有用,在很多情况下它都是个好主意。不过这里,我将在下面解释原因。

  3. 糟糕的主意:使用本地参数并遍历包含对象

    var functions_collection = {
         "function_x": function(name) {
             alert(name);
         },
         //more functions
    };
    for (var name in functions_collection) {
        if (typeof functions_collection[name] === "function") {
            functions_collection[name](name);
        }
    }
    

    当然,这个问题的一个明显问题是您可能不想立即调用集合中的每个函数。更根本的问题是它继续危险紧密耦合的趋势。这是一件坏事,可能是一件非常糟糕的事情,会让你头疼不已。

  4. 现在是“正确”的方式

    改变整个方法。忘记尝试从HTML中回收类名;保持简单。

    1. 好主意:使用本地变量

      谁在乎你的功能?如果您知道要让他们触摸哪些HTML类,只需按照这种方式编写代码即可。

      var functions_collection = {
          "function_x": function() {
               var name = "function_x"; //or "button" or any other class name
               alert(name);
           },
           //more functions
      };
      functions_collection.function_x();
      
    2. 好主意:传递参数

      你已经在调用这个功能吧?所以可能已经有代码可以访问你想要的名称。

      var functions_collection = {
          "function_x": function(name) {
               alert(name);
           },
           //more functions
      };
      
      functions_collection.function_x("function_x"); //or any other class name
      

      现在,您可以在HTML中的任何类上使用function_x,即使它与函数名称不匹配:

      functions_collection.function_x("function_y");
      functions_collection.function_x("class_z");
      functions_collection.function_x("button");
      

      我已经保存了最简单的,因为我觉得你在试图“聪明”时犯了错误,如果这是有道理的话。您的方法存在重大风险,并且收益不值得。

    3. 为什么糟糕的想法是坏的,好的想法是好的

      除了arguments.callee.name选项之外,原因2和3在这种情况下是不好的紧耦合。你将function_x耦合到{{1}的结构}};你将行为耦合到变量名称;最糟糕的是,你将JS变量与HTML元素的类名联系起来。这将使你的代码变得非常脆弱,当你想要改变某些东西时(并且你会),做好准备一个受伤的世界。

      例如,如果您重新组织HTML会发生什么?页面可能会中断,因为JS的结构必须匹配HTML / CSS中的类。你必须重命名或重写functions_collection和其他所有类似的东西,否则你将不得不围绕你已有的JS仔细规划新的HTML。

      如果你想使用JS minifier,会发生什么?取决于,但如果你允许它更改对象文字中的成员名称,它会完全破坏所有内容,你必须从一个“好”的想法开始。

      现在,你得到了什么以换取这种不灵活性?您可以在每个函数的开头保存一个额外的行。不值得,恕我直言。只需咬紧牙关并保持简单。

答案 4 :(得分:2)

假设变量名与其包含的函数具有相同的名称:

var keys = [];
for (var p in functions_collection) {
    if (typeof(functions_collection[p]) == 'function') {
        keys.push(p);
    }
}

你有它,一个包含所有函数名的数组。