简体   繁体   中英

Correct way to override this JavaScript class method

How should I best go about overriding a JavaScript class method when it has been set up as per below. In this snippet, if I want to override the _other method from another JS file, loaded after this one, what is the correct way to go about it?

 var review = {}; "use strict"; (function ($) { review.list = { _init: function () { // The code I want to leave intact }, _other: function () { // The code I want to override }, init: function () { $(document).ready(function () { review.list._init(); review.list._other(); }); } }; review.list.init(); })(jQuery);

You can just assign to review.list._other . If you want to have access to the previous version, grab that first:

var oldOther = review.list._other;
review.list._other = function() {
    // Your new code here, perhaps calling oldOther if you like
    console.log("The new other code ran.");
};

Example:

 // The original file var review = {}; "use strict"; (function($) { review.list = { _init: function() { // The code I want to leave intact }, _other: function() { // The code I want to override }, init: function() { $(document).ready(function() { review.list._init(); review.list._other(); }); } }; review.list.init(); })(jQuery); // Your file after it (function($) { var oldOther = review.list._other; review.list._other = function() { // Your new code here, perhaps calling oldOther if you like console.log("The new other code ran."); }; })(jQuery);
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

You're actually quite lucky it was written that way. It could easily have been written such that you couldn't override _other at all...


Slightly off-topic, but you've asked below:

Actually, does this class structure look reasonably sensible to you? Trying to dip toes into more OOP JS

I don't know your design constraints, so take anything that follows with a grain of salt... I should note that there's no "class" there at all (neither in the ES5 and earlier sense nor the ES2015 and later sense), just an object. (Which is fine.) But it looks like _init and _other are meant to be private; they could be genuinely private instead of pseudo-private without any cost — except then you wouldn't be able to override _other ! :-) Separately, I would allow the overall controlling code to determine when the initialization happened instead of doing it on ready . (Separately, on a pure style note, I don't hold at all with this two-spaces-indentation nonsense so many of the l33t types seem to be promoting. If your code is so deeply nested that using only two spaces for an indent is necessary, it needs refactoring; four spaces is a good solid clear indent, in my view, without being so big it pushes your code off the right-hand side.)

So something like this if ES5 is required:

(function($) {
    var list = {
        init: function() {
            _init();
            _other();
        }
    };

    function _init () {
        // Can use `list` here to refer to the object
    }

    function _other() {
        // Can use `list` here to refer to the object
    }

    review.list = list;

})(jQuery);

...but again, that makes it impossible (well, unreasonable) to override _other .

Or this if ES2015 and above is okay (for code this short, the differences are quite minor):

(function($) {
    let list = {
        init() {
            _init();
            _other();
        }
    };

    function _init () {
        // Can use `list` here to refer to the object
    }

    function _other() {
        // Can use `list` here to refer to the object
    }

    review.list = list;

})(jQuery);

Just add your new override below... It will work...

 var review = {}; "use strict"; (function($) { review.list = { _init: function() { console.log('I\\'m init') }, _other: function() { //This original will be overridden console.log('Original') }, init: function() { $(document).ready(function() { review.list._init(); review.list._other(); }); } }; review.list.init(); })(jQuery); review.list._other = function() { console.log('overridden') }
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM