将唯一属性关联到JavaScript中的匿名函数

Associating unique properties to anonymous functions in JavaScript

本文关键字:函数 JavaScript 唯一 属性 关联      更新时间:2023-09-26

在创建匿名JavaScript函数时,将唯一属性关联到匿名JavaScript函数的标准方法是什么,以便在执行(即运行时)时可以在函数本身内访问这些属性?

一个场景是这样的:

假设我想将事件绑定到动态生成的匿名函数。

var events = ['connect','disconnect','error','connect_failed'];
for(a in events){
  var handler = function(){
     // console.log(arguments.callee.custom); // Not reliable 'cos callee is supposedly deprecated
     console.log('<event-name>');
  };
  handler.custom = events[a];
  $(window).on(events[a],handler);
}

由于使用参数。callee已弃用,不能保证在所有平台上都是最佳的。实现类似目标的推荐方法是什么?

您也可以在函数中使用handler.custom:

var handler = function() {
  console.log(handler.custom);
  console.log('<event-name>');
};

为了防止异步回调时的作用域问题,您可以通过将代码包装在闭包中来创建一个新的作用域handler函数:

for(a in events){
  (function() {
    var handler = function(){
      console.log(handler.custom);
      console.log('<event-name>');
    };
    handler.custom = events[a];
    $(window).on(events[a],handler);
  })();
}

EDIT:刚刚意识到您也可以使用forEach(尽管这也受到浏览器兼容性问题的影响):

events.forEach(function(event) {
  var handler = function() {
    ...
  };
  handler.custom = event;
  $(window).on(event,handler);
});

命名函数表达式仅在函数作用域中提供对函数本身的引用:

var events = ['connect', 'disconnect', 'error', 'connect_failed'];
for (var a in events) { var handler = function inside() { console.log(inside.custom); // not deprecated console.log('<event-name>'); }; handler.custom = events[a]; // now will stay with function even if renamed or moved $(window).on(events[a], handler); }

However, Internet Explorer 8 and below will not parse named functions correctly - Juriy Zaytsev explains the exact issue behind them in more detail: http://kangax.github.io/nfe/#named-expr

If you really have to target IE8 and below, either stick with arguments.callee or use conditional compilation for IE, which is basically IE conditional comments for JavaScript.

You could do something like this:

var events = ['connect','disconnect','error','connect_failed'];
function assignHandler(eventType, custom) {
   $(window).on(events[a], function() {
      console.log(custom);
   });
}   
for(a in events){
  assignHandler(events[a], events[a]);
}

JS闭包的魔力意味着在assignHandler()内部分配作为事件处理程序的匿名函数将能够访问assignHandler() custom参数,即使在assignHandler()完成后。

然而,因为你似乎正在使用jQuery的.on()方法,你不需要自己实现任何东西,因为jQuery已经有这个功能:

.on( events [, selector ] [, data ], handler(eventObject) )

注意第三个可选参数是data。在事件处理程序中,它可以作为event.data访问。

for(a in events){
  var handler = function(e){
     console.log(e.data);
     console.log('<event-name>');
  };
  var custom = events[a];
  $(window).on(events[a], null, custom, handler);
}

我明白你的意思…当事件被触发时,您需要事件名称,并希望知道在函数中运行时触发了哪个事件…我说的对吗?然后你可以使用事件对象接收处理程序…

var events = ['connect','disconnect','error','connect_failed'];
for(a in events){
  var handler = function(e){
     console.log(e.type); 
      console.log('<event-name>');
  };
  $(window).on(events[a],handler);
}
for(a in events){
  $(window).trigger(events[a]);
}