我有一些函数,存储在一个集合/数组中,想要获取密钥(函数名)而无需重新输入。有没有简短的方法来访问它?
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)
答案 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);
}
}
答案 2 :(得分:3)
要获取对象键的名称,您可以使用Object.getOwnPropertyNames(this)
或更新的浏览器Object.keys(this)
,这将获得this
对象的所有键和任何键的数组有:
var functions_collection = {
function_x: function() {
var name = Object.keys(this);
console.log(name);
}
}
答案 3 :(得分:3)
有几种方法可以去这里。有些是好主意,有些则不是。
糟糕的主意: arguments.callee.name
这最直接地转化为您的要求。 arguments.callee
是
对您当前所在职能的引用。但是,it's
considered bad
practice,
除非你有充分的理由,否则你应该避免使用它。
糟糕的主意: 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中的很多东西都很有用,在很多情况下它都是个好主意。不过这里,我将在下面解释原因。
糟糕的主意:使用本地参数并遍历包含对象
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中回收类名;保持简单。
好主意:使用本地变量
谁在乎你的功能?如果您知道要让他们触摸哪些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();
好主意:传递参数
你已经在调用这个功能吧?所以可能已经有代码可以访问你想要的名称。
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
耦合到{{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);
}
}
你有它,一个包含所有函数名的数组。