0

In Javascript, it's possible to have some kind of inheritance, by using function contructors and their "prototype" attribute (i.e the "parent of future instances"), or more recently Object.create(), to get new objects.

However recently I needed to "override" the Jquery object ("$") for one of my projects, that is to say, provide a similar function, which also has all the fn/extend/... [inherited] attributes of the original "jQuery" factory function.

The goal was to have a "$()" function which always received "window.parent" as the second parameter by default, so that the whole program modified the parent frame and not the iframe in which the program was loaded.

Typically I expected to be able to do something like this:

var oldJQ = $;
$ = function (selector) {
    return oldJQ(selector, window.parent);
}
$.__proto__ = oldJQ .__proto__;

$.extend({...});  // must work

Despite numerous attempts, I couldn't get it to work, I always got simple objects instead of real functions when using the "new" keyword, or the inheritance didn't work. I found alternative ways (for example, by copy-pasting all attributes from $ into my new function object), but it seems to me like a horrible way of doing stuffs.

Is there any way to have a new function object which has, as a parent/prototype, the original $ object ?

4
  • "I always got simple objects instead of real functions". Consider that function isn't an actual data type. These are the only actual data types. Does that clarify? Commented Jul 3, 2015 at 20:14
  • No, this isn’t possible. Objects can have only one prototype, and things inherited from Function aren’t callable. ES6 proxies might help, but that’s not quite the same thing. Commented Jul 3, 2015 at 20:15
  • I'd recommend watching this to get a better understanding of how inheritance works. Commented Jul 3, 2015 at 20:17
  • Thanks for the answers, so it confirms that "function objects", like the famous "$", can't simply share attributes via prototypal inheritance... Commented Jul 4, 2015 at 15:50

1 Answer 1

2

While functions are objects in javascript, they aren't regular objects. Specifically, they're objects for which inheritance is broken. Functions are not the only such objects in the language, DOM elements are similarly handicapped. That's one reason jQuery is implemented as wrapper around DOM rather than extending the DOM's features via inheritance.

Fortunately, while OOP doesn't work in this case, we can take inspiration from jQuery itself and use FP to do what we need. In other words, while you can't inherit functions, you can wrap it in another function.

For example, if you need a special console.log function for your app that sends logs back to your server you can override it by redefining it:

var log_orig = console.log;
console.log = function () {
    ajaxlog([].slice.call(arguments,0).map(function(x){
        return JSON.parse(x);
    }).join(',');
    log_orig.apply(console,arguments);
}

Or if you want a special version of $ that does something extra:

function $$ () {
    /*
     * do extra stuff
     */
    return $.apply(null,arguments);
}

Or if you want to override $ instead if wrapping:

var old$ = $;
function $ () {
    /*
     * do extra stuff
     */
    return old$.apply(null,arguments);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.