I'm unable to use native code functions as JavaScript objects in WebKit-based browsers. Is it impossible to alias these functions directly?
This is easiest to explain by example, so here is what I am running in the Developer Tools console:
console.warn;
// Outputs:
// function warn() {
// [native code]
// }
console.warn("console.warn");
// Outputs: "console.warn"
var _c = console;
_c.warn("_c.warn");
// Outputs: "_c.warn"
var _w = console.warn;
_w("_w");
// Outputs: "TypeError: Type error" on Safari/WebKit (Mac)
// Outputs: "TypeError: Illegal invocation" on Chrome (Mac)
var _w2 = function () { console.warn.apply(console, arguments); }
_w2("_w2");
// Outputs: "w2"
This issue came up as I tried to use jQuery Lint in Safari; it uses the following approach to prevent breakage if window.console does not exist:
_console = {
warn: window.console && console.warn || function(){},
...
}
_console.warn("some error");
Here's my temporary workaround:
if((jQuery.browser.safari || jQuery.browser.webkit) && window.console) {
jQuery.LINT.level = 3;
jQuery.LINT.console = {
warn: function() { console.warn.apply(console, arguments); },
group: function() { console.group.apply(console, arguments); },
groupEnd: function() { console.groupEnd(); },
groupCollapsed: function() { console.group.apply(console, arguments); },
log: function() { console.log.apply(console, arguments); }
}
}
You can't alias any methods in JavaScript, native or not, WebKit or not.
When you say
var _w = console.warn;
, you are strippingwarn
away from its owner objectconsole
and treating it as a standalone function. When you call it, it gets nothis
reference to theconsole
, so it fails to work.You may find this unusual from how bound methods work in other languages, but that's just how JavaScript method calls are designed: the
this
reference is passed to a function based solely on whatowner
is inowner.method()
(orowner['method']()
). If the function is called alone without an owner,this
is set to thewindow
object and the method will most likely fall over.To get around this and pass in a proper
this
, you must either usemethod.call
(ormethod.apply
) explicitly as described by @slebetman, or make your own bound function using a closure likevar _w= function() { console.warn.apply(console, arguments) };
or, in ECMAScript Fifth Edition,method.bind(owner)
.That should be:
The first parameter to apply is the value of this to pass into the
warn
method.