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 strippingwarnaway from its owner objectconsoleand treating it as a standalone function. When you call it, it gets nothisreference 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
thisreference is passed to a function based solely on whatowneris inowner.method()(orowner['method']()). If the function is called alone without an owner,thisis set to thewindowobject 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).