I have a problem node.js structure with javascript oop. I created a class using another class.
var base = function (name) {
this.Rows = new Array();
};
var top = function (name) {
this.name = name;
};
top.prototype = new base();
var myClass = new top("");
myClass.Rows.push("a");
console.log(myClass.Rows);
var myClass2 = new top("test");
myClass2.Rows.push("b");
console.log(myClass2.Rows);
This code returns the following results;
[ 'a' ]
[ 'a', 'b' ]
but I do not have to be found by the algorithm as the result of this code?
[ 'a' ]
[ 'b' ]
Thank you for helping.
solved: i solved this problem. refactoring code;
var base = function (name) {
this.Rows = new Array();
}
var top = function(name) {
top.prototype.constructor.call(this, name);
this.name = name;
}
top.prototype = Object.create(new base());
thanks for all.
That's how JavaScript's prototypical inheritance works.
This seems rather confusing to newcomers to the language :)
Both objects myClass and myClass2 have the same prototype (set in top.prototype = new base();)
This means when you access their Rows property since neither of them has one they access the one of their prototype. Since it's the same for both they both act on the same object. If you add the line console.log(myClass2.Rows); to the end of your code it would also output [ 'a', 'b' ]
Prototypical inheritance seems to confuse beginners because in classical languages if class A extends class B then all of A's properties are copied to B - this is not the case in JavaScript.
You can accomplish the same functionality if you refactor your code to the following:
var base = function () {
};
base.prototype.getRows = function(){
return this.rows;
}
var top = function (name) {
this.name = name;
this.rows= [];
};
top.prototype = new base();
var myClass = new top("");
myClass.getRows().push("a");
console.log(myClass.getRows());
var myClass2 = new top("test");
myClass2.getRows().push("b");
console.log(myClass2.getRows());
This would produce the 'classical' result you expect.
However, JavaScript's prototypical model focuses more on sharing functionality. I would probably refactor your code to:
var myClass = {Rows:[]},myClass2 = {Rows:[]};
Yes, prototypes are shared. I think you intended this type of inheritance:
var base = function (name) {
this.Rows = new Array();
};
var top = function (name) {
base.call(this,name); // this replaces your prototype
this.name = name;
};
var myClass = new top("");
myClass.Rows.push("a");
console.log(myClass.Rows);
var myClass2 = new top("test");
myClass2.Rows.push("b");
console.log(myClass2.Rows);
call will invoke the function as if it was a method, so it will set up the object as base, then you override it with specific properties. As noted by nrabinowitz in the comments, this won't inherit any prototype methods.
Also my initial suggestion, which I quite like but it has no benefits over the above:
var top = function (name) {
this.super=base; // these two lines replace your prototype
this.super(name);
this.name = name;
};
The method makes "base" into a member function, then calls it. It will set up "top" as a new "base" object, then customise it. I chose "super" as the variable name because it's similar to Objective C's style.