Reputation: 9701
I have the following code example :
Application.Polyfills.prototype.prettifyCode = function(enable, js_lib, css_lib) {
return Modernizr.load([{
test : enable,
yep : [ css_lib, js_lib ],
complete: function() {
return window.prettyPrint && prettyPrint();
}
}]);
};
If I do a console.log(typeof this.prettifyCode)
, in which this
refers to the Application.Polyfills
, I get function
, but if I do console.log(typeof this.prettifyCode())
I get undefined
. Can someone tell me why do I get that and how can I fix it so I get the same result in both cases, because most of the times the functions require arguments so I need to use parentheses ?
To be more specific, I have a method :
Application.Polyfills.prototype.callPolyfills = function(array) {
for (var i = array.length - 1; i >= 0; i--) {
console.log(typeof array[i]);
(typeof array[i] === "function") ? array[i].apply(this, [ this ]) : console.log('Index [' + i + ']: Invalid [ Function Required ]') ;
};
};
The above method is used to call all my functions that are placed inside an array, something like the following :
this.callPolyfills([
self.polyfillize([
{
test : [Modernizr.localstorage, Modernizr.sessionstorage],
polyfill : [self.polyfills_url.storage_polyfill_url]
},
{
test : [Modernizr.json],
polyfill : [self.polyfills_url.json_polyfill_url]
}
]),
self.prettifyCode(self.prettify, self.libraries_url.google_code_prettyfier.css, self.libraries_url.google_code_prettyfier.js),
self.consoleAvoidError()
]);
Making abstraction of all the variables in there that are unknown, I would like to see if what I call in that array is actually a function, as I'm already trying to check now in the callPolyfills
method. But it fails because it returns undefined
each time even though it's a function.
Upvotes: 0
Views: 147
Reputation: 193261
Maybe instead of calling explicitly your polyfills inside of callPolyfills, you could change your approach? Like this:
this.callPolyfills([
[self.polyfillize, [
{
test : [Modernizr.localstorage, Modernizr.sessionstorage],
polyfill : [self.polyfills_url.storage_polyfill_url]
},
{
test : [Modernizr.json],
polyfill : [self.polyfills_url.json_polyfill_url]
}
]],
[self.prettifyCodeself.prettify, self.libraries_url.google_code_prettyfier.css, self.libraries_url.google_code_prettyfier.js],
self.consoleAvoidError
]);
So then you would check like this:
Application.Polyfills.prototype.callPolyfills = function(array) {
for (var i = array.length - 1; i >= 0; i--) {
if (typeof array[i] == "function") {
// call with no arguments
array[i].apply(this);
}
else if (typeof array[i].shift() == "function") {
// call with arguments
array[i].apply(this, array[i]);
}
else {
// Invalid [ Function Required ]') ;
}
};
};
Upvotes: 1
Reputation: 75317
Adding this as a new answer as the two answers aren't realling related at all
You're function callPolyfills
is spot on; it's what you're passing to callPolyfills
that is the problem (you're passing an array of the results of the functions you wan't to call, not the functions themselves).
function foo() {
return "hi";
};
var bar = foo; // stores a reference to the function foo in `bar`, but doesn't call foo.
var baz = foo(); // calls foo and stores the result of the function ("hi") in baz.
What you're doing (self
, this
's, and confusing arguments aside is):
callPolyfills([
foo(),
foo(),
foo()
]);
... i.e. saying "hi" to callPolyfills
numerous times, without actually passing it what you want.
What you should be passing is;
callPolyfills([
foo,
foo,
foo
]);
This stops you being able to specify arguments to the functions though; in this circumstance the easiest way to do this would be to wrap those functions in anonymous functions.
this.callPolyfills([
function () {
self.polyfillize([{
test: [Modernizr.localstorage, Modernizr.sessionstorage],
polyfill: [self.polyfills_url.storage_polyfill_url]
}, {
test: [Modernizr.json],
polyfill: [self.polyfills_url.json_polyfill_url]
}]);
}, function () {
self.prettifyCode(self.prettify, self.libraries_url.google_code_prettyfier.css, self.libraries_url.google_code_prettyfier.js);
},
self.consoleAvoidError
]);
... but then I'm not sure what you're gaining really.
Upvotes: 1
Reputation: 75317
typeof this.prettifyCode()
is checking the type of the value returned by this.prettifyCode()
; which is undefined
.
typeof this.prettifyCode
however, is checking what the type of the prettifyCode
member on this
is; which is a function
You shouldn't want these to be the same. The only way they could be the same is if this.prettifyCode
returned a function, but the fact that both typeof this.prettifyCode()
and typeof this.prettifyCode
would be function
is meaningless.
Upvotes: 4