Reputation: 3801
Anyone know of an easy way to test a variable to see if it is an object of type jQuery.Callbacks.
Background: I've got some jquery widgets I've created, and they each have events managed using jQuery.Callbacks. Some of my widgets use other widgets and will pass along the configuration given to itself to the sub-widget, and this includes events. So if my parent widget initialises an event, I don't want the child widget to initialise it again, or i'll lose any existing subscriptions.
For Example:
var notCallbackHandler1='';
var notCallbackHandler2={ add: function(something) { } };
var callbackHandler=$.Callbacks();
function isVariableACallbackHandler(variable) {
// <-- What goes here?
}
isVariableACallbackHandler(notCallbackHandler1); // Should return false
isVariableACallbackHandler(notCallbackHandler2); // Should return false
isVariableACallbackHandler(callbackHandler); // Should return true
Upvotes: 0
Views: 150
Reputation: 7250
Well you can check if the passed argument has a method which is specific for jQuery.Callbacks()
. Like this for example:
var $callbacks = $.Callbacks(),
$noCallbacks = $('div'),
checkIfCallbacks = function(callback) {
var checkFun = 'fireWith';
return typeof callback[checkFun] == 'function';
};
checkIfCallbacks($callbacks); // true
checkIfCallbacks($noCallbacks); // false
Update: checking for typeof suffices.
Update: Here would be an improved version of your code, just don't use for...in loops and avoid jQuery functions if possible if you want better performance.
var $callbacksProto = $.Callbacks();
$.isCallbacks = function (object) {
// first check if we even have an object
// this can already save a lot of comparison time
if (typeof object == 'object') {
var prop, i;
for (i = 0; i < $callbacksProto.length; i++) {
prop = $callbacksProto[i];
// check if the property name of the original $callbacksProto is a function in our object
// because every $callbacksProto property is a function
if (typeof object[prop] != 'function') {
return false;
}
}
} else {
return false;
}
// if no error occurred return true
return true;
};
Upvotes: 2
Reputation: 3801
Here is what I ended up using:
var tempCallbacksObject=$.Callbacks();
$.isCallbacks = function (variable) {
for (var propertyName in tempCallbacksObject) {
if (variable[propertyName] == undefined) { return false; }
if ($.type(tempCallbacksObject[propertyName]) != $.type(variable[propertyName])) { return false; }
}
return true;
};
I created a tempCallbacksObject so that I wouldn't have to keep creating a Callbacks object each time I wanted to compare. I also compared every member of the callbacks object so that it is much less likely that an object with a member or two with the same name causes a false positive.
I still don't like it though because it requires a loop and that always takes time, especially since it is likely to be used to check each event handler on each widget I create. Oh well, if someone finally does come up with something better (or an improved version of this) then I've only got the one place to change it.
Upvotes: 0