Javascript prototype properties and object properties

I am trying to apply prototyped inheritance to a function in Javascript. All this is quite simple and even described in the Wikipedia javascript lemma . It works if my properties are simple JavaScript types:

function Person() { this.age = 0; this.location = { x: 0, y: 0, absolute: false }; }; function Employee() {}; Employee.prototype = new Person(); Employee.prototype.celebrate = function () { this.age++; } var pete = new Employee(); pete.age = 5; pete.celebrate(); var bob = new Employee(); bob.celebrate(); console.log("bob is " + bob.age + " pete is " + pete.age); 

With Employee.prototype = new Person(); all Person properties and (prototype) methods are inherited by Employee, which is fundamental to inheritance.

This works as expected: bob is 1 pete is 6

Now I'm starting to mess around with the pet place (after the celebration)

 pete.celebrate(); pete.location.absolute=true; 

Displaying bob.location.absolute shows: true , which is counterintuitive (I didnโ€™t touch the location of bob, so I expect it to have the initial value declared in Person ) and will ruin my solution.

In my original understanding, this was supposed to be false. I really understand that I should probably clone a location object from the original Person, but I'm not sure where and how to do this. And if there can be better methods for inheritance?

+6
source share
3 answers

When you instantiate a new employee, all Person properties are copied. Since this is a shallow copy, the pet and the bean have the same location object. For your problem, it seems not a good solution. You can use the framework or hack like this:

 function Employee() { Person.apply(this); }; 

This invokes the Person constructor in the context of this object.

The MDC has more information about this: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/apply

+3
source

Do not run the Person constructor when inheriting, Employee should not even have .location , because it is not in Person.prototype .

 function createObject( fn ){ function f(){} f.prototype = fn.prototype; return new f; } 

Then:

 Employee.prototype = createObject( Person ); 

This inherits correctly without side effects (running constructor).

You only run the parent constructor in the child constructor:

 function Employee() { Person.apply( this, arguments ); } 
+3
source

I ran into a similar problem. As a result, I used a separate constructor for the internal object.

 function engine(cc, fuel) { this.cc = cc; this.fuel = fuel } function car(type, model, cc, fuel) { this.type = type; this.model = model; this.engine = new engine(cc, fuel); } var mycar = new car("sedan", "toyota corolla", 1500, "gas"); console.log(mycar.type); //sedan console.log(mycar.engine.cc); //1500 

If I had any methods on prototypes of the 'engine' or 'car' constructors, they would still be available. However, I cannot take the car class out of the engine class in the sense of OOP. I didnโ€™t have to. The "engine" is used as a component of the "car".

Meanwhile, for inheritance, I prefer to use the new methods included in ECMAScript 5, which means using Object.create, Object.defineProperties, etc. They are supported even in IE9. Before that, I used the same apply () method proposed by Costa.

0
source

Source: https://habr.com/ru/post/905065/


All Articles