1

I've a JavaScript class, and I'd like to override a parent method by creating a child class. However, I am struggling to work out how to call the child method from the context of the parent.

Here's a trimmed-down version of my parent:

// "rules" is a global hash

function ForumFilter() {
    this.scanText = function(title, body) {
        // Save 'this' context, as each() overwrites it
        var that = this;
        // This is jQuery each()
        $.each(rules, function(ruleName, rule) {
            // rule.search is a regex
            var match = rule.search.test(body);
            if (match)
            {
                that.isPassed = false;
                // ** I'd like to call a child method here,
                // ** but it only calls the method in this class
                that.setRuleFailed(ruleName);
            }
        });
    }

    this.setRuleFailed = function(ruleName) {
        this.failedRules.push(ruleName);
    }
}

Here's my attempt at the child:

ForumFilterTest.prototype = new ForumFilter();
ForumFilterTest.prototype.setRuleFailed = function(ruleName) {
    // Call parent
    ForumFilter.setRuleFailed(ruleName);
    // Record that this one has triggered
    this.triggered.push(ruleName);
}

Here's my calling my parent method from a child instance:

var scanner = new ForumFilterTest();
scanner.scanText("Hello", "Hello");

So, in scanText (which only exists in the parent) it may call setRuleFailed, which should call the version in ForumFilterTest, which in turn calls the class it overrides. Thus, as its name implies, I am trying to add a behaviour to the parent for testing purposes, so of course I want the parent method to be used if ForumFilter is instantiated on its own.

1 Answer 1

3
+100

After understanding your problem better, here's my actual proposed changes. Specifically, you need to move your ForumFilter methods to its prototype. That will allow ForumFilterTest methods to explicitly reference ForumFilter methods.

Step 1: Move ForumFilter methods to its prototype.

function ForumFilter() {}
ForumFilter.prototype.scanText = function(title, body) {
    // Save 'this' context, as each() overwrites it
    var that = this;
    // This is jQuery each()
    $.each(rules, function(ruleName, rule) {
        // rule.search is a regex
        var match = rule.search.test(body);
        if (match)
        {
            that.isPassed = false;
            // ** I'd like to call a child method here,
            // ** but it only calls the method in this class
            that.setRuleFailed(ruleName);
        }
    });
};
ForumFilter.prototype.setRuleFailed = function(ruleName) {
    this.failedRules.push(ruleName);
};

Step 2: Explicitly reference ForumFilter "parent" method when needed:

// "child class" implementation
function ForumFilterTest() {}
ForumFilterTest.prototype = new ForumFilter();
ForumFilterTest.prototype.setRuleFailed = function(ruleName) {
    // Call parent
    ForumFilter.prototype.setRuleFailed.call(this, ruleName);
    // Record that this one has triggered
    this.triggered.push(ruleName);
};
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the help, much appreciate the jsFiddle example. It's nearly what I am aiming for, however I want the child to be able to call the parent, as per this. Thus, it adds to the parent rather than replaces it.
Ahh, you'll need to move the parent methods to the prototype so that "overridden" methods can still be explicitly invoked by child classes. See this: jsfiddle.net/Tsmgg/3
Superb, many thanks! That's exactly what I'm after, and I've modified my own use case successfully. So, even though the parent methods existed before, they were invisible to the child?
Correct. Your ForumFilter methods were previously set in the constructor and were therefore instance level. This meant that once you ran ForumFilterTest.prototype = new ForumFilter(), these methods were now directly on the ForumFilterTest's prototype, rather than further up the prototype chain. That resulted in the parent setRuleFailed method being completely overridden by the ForumFilterTest.prototype.setRuleFailed = function() {...} call, since that was where the parent setRuleFailed implementation was stored as well.

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.