简体   繁体   中英

How can I call anonymous function without using Eval?

I have an autocomplete function with callback to return data. This autocomplete function is used by many different instances.

$.fn.acItem = function(callback){
  var self = this;
  $(self).autocomplete({
    (...)
    select: function(e, ui){
      // Eval for calling anonymous function (right?)
      window[callback](ui.item);
    }
  });
};

I'm also using namespaces

var Agency = {
  init: function() {
    var self = this;
    self.registerAgency.addItem();
  },

  registerAgency: {
  (...)
    addItem: function(item){
      if(!item){
        (...)
        // Initiate autocomplete on input
        $('.search-item').acItem('Agency.registerAgency.addItem');
      } else {   
        // Do something with Item
      }
    }
}

Agency.init();

Using window[callback](ui.item) works if I'm not using namespace. But with namespace, it gets a bit more complicated as described by Jason Bunting .

Since different namespaces is using acItem() , it needs to know what function to call in the callback. But using Eval for calling anonymous function is strongly discouraged by many.

So what is a good way for doing callback on anonymous functions?

  1. window['foo']() is not "eval". It's the same as window.foo() using different syntax, which you probably wouldn't call "eval" either.
  2. The problem with this is that you expect your callback function to be a specifically named global function. But you don't have to pass functions by name ; functions are first class objects in Javascript and can be passed directly as values . You actually should simply accept a function as callback:

     $.fn.acItem = function(callback) { callback(); }; 

    This function accepts the callback as function and calls it. Very straight forward. You'd pass the callback like this:

      $('.search-item').acItem(function () { .. }); // or: $('.search-item').acItem(this.registerAgency.addItem); // or, to preserve the `this` context inside the callback: $('.search-item').acItem(this.registerAgency.addItem.bind(this.registerAgency)); 

If acItem can take a function as parameter, you just have to give it like this :

$('.search-item').acItem(Agency.registerAgency.addItem);

The function will not be executed when you give it like this. You just give the function, you don't execute it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM