Javascript:如何在函数中获取父键

Javascript: How to get the parent key inside a function?

本文关键字:获取 函数 Javascript      更新时间:2023-09-26

我有一些函数,存储在集合/数组中,并希望获得键(function-name)而无需重新键入它。有什么捷径可以到达吗?

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",而更喜欢像这样调用它。

很抱歉这个奇怪的话题,提前感谢!

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

Object.keys(this)

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

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

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

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

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

小提琴

在我看来,你需要改变你上面的代码,因为你有匿名函数没有名字 -这样的改变应该工作:

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

见http://jsfiddle.net/9cN5q/1/

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

首先是一些不好的想法

  1. 坏主意: arguments.callee.name

    这最直接地转化为你的问题。arguments.callee是对当前所处函数的引用。然而,它是被认为是坏的实践中,除非你有很好的理由,否则你应该避免使用它。

  2. 坏主意:套用

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

    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);
        }
    }
    

    柯里化对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);
        }
    }
    
    当然,这种方法的一个明显问题是,您可能不想一次调用集合中的每个函数。更根本的问题是,它延续了危险的紧密耦合趋势。这是一件糟糕的事情,可能是一件非常糟糕的事情,它会让你付出各种头痛的代价。

现在"正确"的方式

改变你的整个方法。忘记尝试从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");
    

    我把最简单的留到最后,因为我认为你试图表现得"聪明"是在犯错误,如果那有意义的话。你的方法有很大的风险,回报是不值得的。

为什么坏主意是坏的,好主意是好的

除了arguments.callee.name选项之外,本例中2和3不好的原因是紧耦合。你将function_x耦合到functions_collection的结构;你将行为耦合到一个变量名;最糟糕的是,你将JS变量与HTML元素的类名耦合在一起。这将使你的代码极其脆弱,当你想要改变一些东西时(你会这样做),准备好迎接一个痛苦的世界。

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

如果你想使用JS迷你器会发生什么?看情况,但是如果你允许它改变对象字面量中的成员名,它就会彻底破坏一切,你必须重新开始一个"好"的想法。

那么,这种不灵活性的交换条件是什么呢?在每个函数的开头额外保存一行。不值得,恕我直言。咬紧牙关,保持简单。

假设变量名与包含它的函数同名:

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

就是这样了,一个包含所有函数名的数组