2016-02-29 56 views
2

我有下面的代码长度:

var callbacks = $.Callbacks(); 
callbacks.add(fn1); 
callbacks.add(fn2); 

有没有什么办法让的回调列表的长度。在我的情况下,它应该是2. 我读过the documentation,但没有得到解决方案。

回答

3

看起来不像。回调函数中的范围隐藏了回调list数组。看看源代码。 list在初始回调函数中定义,并由内部回调函数通过查找范围来访问,但实际的回调函数仅返回包含定义函数的对象。所以不幸的是我看不到那个list,所以你可以看到它的长度,jQuery没有提供任何机制来获得长度。以下是jQuery中的代码:

jQuery.Callbacks = function(options) { 

    // Convert options from String-formatted to Object-formatted if needed 
    // (we check in cache first) 
    options = typeof options === "string" ? 
     createOptions(options) : 
     jQuery.extend({}, options); 

    var // Flag to know if list is currently firing 
     firing, 

     // Last fire value for non-forgettable lists 
     memory, 

     // Flag to know if list was already fired 
     fired, 

     // Flag to prevent firing 
     locked, 

     // Actual callback list 
     list = [], 

     // Queue of execution data for repeatable lists 
     queue = [], 

     // Index of currently firing callback (modified by add/remove as needed) 
     firingIndex = -1, 

     // Fire callbacks 
     fire = function() { 

      // Enforce single-firing 
      locked = options.once; 

      // Execute callbacks for all pending executions, 
      // respecting firingIndex overrides and runtime changes 
      fired = firing = true; 
      for (; queue.length; firingIndex = -1) { 
       memory = queue.shift(); 
       while (++firingIndex < list.length) { 

        // Run callback and check for early termination 
        if (list[ firingIndex ].apply(memory[ 0 ], memory[ 1 ]) === false && 
         options.stopOnFalse) { 

         // Jump to end and forget the data so .add doesn't re-fire 
         firingIndex = list.length; 
         memory = false; 
        } 
       } 
      } 

      // Forget the data if we're done with it 
      if (!options.memory) { 
       memory = false; 
      } 

      firing = false; 

      // Clean up if we're done firing for good 
      if (locked) { 

       // Keep an empty list if we have data for future add calls 
       if (memory) { 
        list = []; 

       // Otherwise, this object is spent 
       } else { 
        list = ""; 
       } 
      } 
     }, 

     // Actual Callbacks object 
     self = { 

      // Add a callback or a collection of callbacks to the list 
      add: function() { 
       if (list) { 

        // If we have memory from a past run, we should fire after adding 
        if (memory && !firing) { 
         firingIndex = list.length - 1; 
         queue.push(memory); 
        } 

        (function add(args) { 
         jQuery.each(args, function(_, arg) { 
          if (jQuery.isFunction(arg)) { 
           if (!options.unique || !self.has(arg)) { 
            list.push(arg); 
           } 
          } else if (arg && arg.length && jQuery.type(arg) !== "string") { 

           // Inspect recursively 
           add(arg); 
          } 
         }); 
        })(arguments); 

        if (memory && !firing) { 
         fire(); 
        } 
       } 
       return this; 
      }, 

      // Remove a callback from the list 
      remove: function() { 
       jQuery.each(arguments, function(_, arg) { 
        var index; 
        while ((index = jQuery.inArray(arg, list, index)) > -1) { 
         list.splice(index, 1); 

         // Handle firing indexes 
         if (index <= firingIndex) { 
          firingIndex--; 
         } 
        } 
       }); 
       return this; 
      }, 

      // Check if a given callback is in the list. 
      // If no argument is given, return whether or not list has callbacks attached. 
      has: function(fn) { 
       return fn ? 
        jQuery.inArray(fn, list) > -1 : 
        list.length > 0; 
      }, 

      // Remove all callbacks from the list 
      empty: function() { 
       if (list) { 
        list = []; 
       } 
       return this; 
      }, 

      // Disable .fire and .add 
      // Abort any current/pending executions 
      // Clear all callbacks and values 
      disable: function() { 
       locked = queue = []; 
       list = memory = ""; 
       return this; 
      }, 
      disabled: function() { 
       return !list; 
      }, 

      // Disable .fire 
      // Also disable .add unless we have memory (since it would have no effect) 
      // Abort any pending executions 
      lock: function() { 
       locked = true; 
       if (!memory) { 
        self.disable(); 
       } 
       return this; 
      }, 
      locked: function() { 
       return !!locked; 
      }, 

      // Call all callbacks with the given context and arguments 
      fireWith: function(context, args) { 
       if (!locked) { 
        args = args || []; 
        args = [ context, args.slice ? args.slice() : args ]; 
        queue.push(args); 
        if (!firing) { 
         fire(); 
        } 
       } 
       return this; 
      }, 

      // Call all the callbacks with the given arguments 
      fire: function() { 
       self.fireWith(this, arguments); 
       return this; 
      }, 

      // To know if the callbacks have already been called at least once 
      fired: function() { 
       return !!fired; 
      } 
     }; 

    return self; 
}; 
+0

谢谢@ AtheistP3ace!是的,看起来不可能... – Sergey

+0

不幸的是。如果你完全控制了你的代码,你可以随时追踪你添加到列表中的东西,因为这些东西被添加或解雇了。 – AtheistP3ace

+0

@谢绝你无法在那里找到它。相反,您可以设置一个计数器来获取调用'.add()'方法的次数。 – Jai