命名内联函数有什么优势?

时间:2014-01-17 09:47:41

标签: javascript

在例如。回调,命名内联函数和匿名内联函数之间的区别是什么?

我认为它增加了可读性,但还有其他优势吗?

例如

element.addEventListener("load", function onLoad() {
  // execute code
});

vs.

element.addEventListener("load", function() {
  // execute code
});

编辑:我想我也可以使用命名内联函数

来完成此操作
...
element.addEventListener("load", function onLoad() {
  // execute code ...
  element.removeEventListener("load", onLoad);
});

4 个答案:

答案 0 :(得分:4)

你可以递归:

document.addEventListener('mousemove', function stackOverflow() {
    stackOverflow();
});

您无法使用匿名内联函数执行此操作。不是那么容易,至少(那里arguments.callee,但它不应再被使用了。)

答案 1 :(得分:1)

嗯,唯一的区别是函数的name属性将是匿名函数中的空字符串。 如果保留function onLoad()而不是匿名函数,则属性onLoad.name将包含字符串'onLoad'。 name属性是语言的扩展(它不是ECMA标准的一部分。)

当使用诸如Firebug之类的调试器时,或者从自身递归调用相同的函数时,name属性很有用;否则你可以跳过它。

答案 2 :(得分:0)

只要您想引用该功能,它就会很有用。

除了递归(as previously mentioned)之外,您还可以将数据直接绑定到函数(因为函数是第一类对象,对吧?)。此技术的一个有用应用可能包括memoization,您可以在其中保存函数以前计算的值,以防止以后再次重新计算值。

一个简单的计数器 - JSFiddle

button.addEventListener("click", function fn() {
  fn.counter = fn.counter || 0;
  console.log(++fn.counter);
});

答案 3 :(得分:0)

它主要用于改善Error对象中的堆栈跟踪;因此,在错误的堆栈跟踪中,您将看到函数的实际名称而不是(匿名函数)字符串。

但是,请记住,存在一些范围和兼容性问题。一些JavaScript环境将命名函数表达式的范围表示为Object的实例;也就是说,它从Object.prototype继承属性。所以你可能会遇到这样的问题:

var constructor= function() { return null; };
var f = function() { return constructor() };
f(); 

最后一行将在某些ES3 JavaScript环境中返回{},而不是null。值得庆幸的是,ES5中没有此问题。

如果您想使其递归,您可以选择执行以下操作:

var recurs = function(){
    recurs();
} 

document.addEventListener('mousemove', recurs);

还有一点需要注意的是内联函数(或命名函数表达式)的名称仅在函数本身中可见。