【问题标题】:Javascript: How to get the parent key inside a function?Javascript:如何在函数中获取父键?
【发布时间】:2013-05-31 06:39:17
【问题描述】:

我有一些函数,存储在一个集合/数组中,我想在不重新输入的情况下获取键(函数名)。有什么捷径可以访问吗?

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)

【问题讨论】:

  • 你能给出用例吗,为什么需要这个?
  • @itz2k13 有一些 CSS 类被命名为函数。在函数内部,我需要像 $(".function_x .button").html("123"); 一样使用它们并希望尽可能保持我的代码干净。
  • 您可以调用var name = Object.keys(this)(或使用getOwnPropertyNames)来获取对象中键的列表。除非只有一个,否则不会只给你父键?
  • 为什么不使用 CSS 类名作为函数的参数?
  • @adeneo 我猜你的答案就是我所需要的。你为什么只发表评论而不是答案?

标签: javascript arrays function


【解决方案1】:

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

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

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

【讨论】:

  • 不是我正在寻找的答案,但很高兴知道将来的一些代码。非常感谢! +1
【解决方案2】:

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

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

FIDDLE

【讨论】:

【解决方案3】:

在我看来,您需要更改上面的代码,因为您拥有没有名称的匿名函数——这样的更改应该会起作用:

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

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

【讨论】:

  • +1,但我很好奇为什么在本地这不起作用,但在 jsFiddle 中,它起作用了。
  • 这仅在您在声明中键入函数名称两次时才有效。最常见的方法是将匿名函数分配给对象属性(在警报中给出“”)。
  • 如果它是匿名的,它没有名字,这就是它被称为匿名的原因;)
  • 在 OP 的问题中它是匿名的。他想知道调用该函数的对象的键。
  • 不是反对者,但可能是因为arguments.callee is considered bad practice.
【解决方案4】:

您可以通过多种方式访问​​这里。有些是好主意,有些则不是。

首先,一些不好的想法

  1. 坏主意:arguments.callee.name

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

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

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

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

现在是“正确”的方式

改变你的整体方法。忘记尝试从 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 缩小器会发生什么?取决于,但如果你允许它更改对象文字中的成员名称,它会完全破坏一切,你必须从“好”的想法之一重新开始。

现在,你用这种僵化换取了什么?您在每个函数的开头保存一个额外的行。不值得,恕我直言。咬紧牙关,保持简单。

【讨论】:

    【解决方案5】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-09
      • 1970-01-01
      • 2011-01-10
      • 2018-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多