2

I want constructor Paper to inherit constructor View. I've read that there needs to be a temporary constructor new F(), but the parent is modified along with the child class prototype in my code:

function View() {};
function Paper() {};

View.prototype = {
    location: {
        "city": "UK"
    }
}


function F() {};

F.prototype = View.prototype;
Paper.prototype = new F();
Paper.prototype.constructor = Paper;

So when I try to modify the Paper's prototype:

Paper.prototype.location.city = "US";

I find the View's prototype is modified too!:

var view = new View();
console.log(view.location); //US! not UK

So what's wrong with my code? How can I override the prototype without affecting the parent?

Liam
  • 1,041
  • 2
  • 17
  • 31
hh54188
  • 14,887
  • 32
  • 113
  • 184
  • possible duplicate of [Crockford's Prototypal inheritance - Issues with nested objects](http://stackoverflow.com/questions/10131052/crockfords-prototypal-inheritance-issues-with-nested-objects) – Bergi Jul 25 '13 at 15:08

1 Answers1

0

Inheritance in JS is tricky, as you've discovered. Perhaps someone smarter than I can enlighten us on the technical specifics as to why, but a possible solution would be to use the very tiny Base.js framework, courtesy of Dead Edwards.

edit: I have restructured the original code to fit Dean Edward's framework.

Inheritance will work properly once you master the syntax. Here's a possible solution based on your code:

var View = Base.extend({
    constructor: function(location) {
        if (location) {
            this.location = location;
        }
    },

    location: "UK",

    getLocation: function() {
        return this.location;
    }
});

And extending it:

var Paper = View.extend({
    location: "US"
});

And testing it:

var view = new View();
alert("The current location of the view is: " + view.getLocation());
var paper = new Paper();
alert("The location of the paper is: " + paper.getLocation());
alert("The current location of the view is: " + view.getLocation());

Alternatively, the same result can be achieved with:

var Paper = View.extend();

And testing:

var view = new View();
alert("The current location of the view is: " + view.getLocation());
var paper = new Paper("US");
alert("The location of the paper is: " + paper.getLocation());
alert("The current location of the view is: " + view.getLocation());

Both will produce three alerts:

The current location of the view is: UK
The location of the paper is: US
The current location of the view is: UK

I hope this helps!

Liam
  • 1,041
  • 2
  • 17
  • 31
  • Could you please adapt the framework to OP's question, instead of copying the examples from the linked page? I fear it won't work. – Bergi Jul 25 '13 at 15:10
  • @Bergi Done, although I won't be able to test it myself until this afternoon. – Liam Jul 25 '13 at 15:26
  • Please test it somewhen, I believe this still will show the issue. – Bergi Jul 25 '13 at 18:32
  • @Bergi Fixed! Hopefully this at least partially answers OP's question. – Liam Jul 27 '13 at 03:13