Note: you really shouldn't be doing this, as internal jQuery code also calls the constructor, which could bring about very unusual issues if you aren't extremely careful.
Your problem is that you aren't calling oldInit
as a constructor - rather as a function, which doesn't really work because anything set inside jQuery.fn.init
will go on jQuery.fn
, rather than a new jQuery object.
Why doesn't just setting the ThisBinding to {} work then?
Although this can seem somewhat intuitive after learning about the way the "new" operator works, this doesn't actually do the same thing. Why?
function Foo() { this.bar(); }
Foo.prototype.bar = function () { alert(1); };
new Foo; // 1 is alerted
Foo.apply({}); // TypeError: Object #<Object> has no method 'bar'
When new
is used, it also gives the instance's __proto__
the constructor's prototype
object. When you create an object literal, this is the standard Object.prototype
, not the intended prototype object.
What to do then?
If you are attempting to override jQuery.fn.init
, you need to use something like this:
var oldInit = jQuery.fn.init;
jQuery.fn.extend(
{ init: function ()
{ return oldInit.apply(new oldInit, Array.prototype.slice.call(arguments));
}
});
How does this work?
By calling new oldInit
with no arguments, we'll just get back an empty object with __proto__
set to jQuery.fn
, exactly what we want. Then, we'll supply the arguments to oldInit
, and any arguments will go straight to this empty new object, just like the original.
This works because when you call it, your actual ThisBinding (the value of this inside the function call) will already be the new jQuery object, because you are meant to refer to this
to add new properties to an instance of the jQuery.fn.init
constructor.
Your original code was the following:
var oldInit = jQuery.fn.init;
jQuery.fn.extend({
init: function () {
return oldInit.apply(jQuery.fn, Array.prototype.slice.call(arguments));
}
});
That would make your constructor think that the new function is meant to be jQuery.fn
, which is probably not what you had intended. If you had a standard function, that would work (as that is what the ThisBinding is meant to be), however since the "new" operator changes the ThisBinding, this no longer means the same thing as before.