0

I was watching a javascript design patterns course and I came through this.

var Task = function(name) {
  this.name = name;
  this.completed = false;
}

Task.prototype.complete = function(){
  console.log('completing task: ' + this.name)
  this.completed = true;
}

Task.prototype.save = function(x){
  console.log(`x is ${x}`);
  console.log('saving task: ' + this.name);
}

// inheriting from Task could be done like this :
var UrgentTask = function(name, priority) {
  // first you need to inherit the methods and variables
  Task.call(this, name);
  this.priority = priority;
}
// Second you need to inherit it's prototypes
// now what is the difference between this and just = Task.prototype ??
  // UrgentTask.prototype = Object.create(Task.prototype);
  UrgentTask.prototype = Task.prototype;

  UrgentTask.prototype.notify = function(){
    console.log('Just notifing ..');
  }

  UrgentTask.prototype.save = function() {
    this.notify();
    // Task.prototype.save.call(this,1);
  }

// var ut = new UrgentTask('New Urgent Task', 1)
// ut.save();

var t = new Task('New Urgent Task')
t.save();

Why do changing in UrgentTask.prototype affects Task.prototype, I mean shouldn't the equality goes one way ?

  • What makes you think it goes only one way? You've made a normal assignment, now both `UrgentTask.prototype` and `Task.prototype` reference the exact same object. – Bergi Nov 15 '19 at 18:23

1 Answers1

1

This part of that code is wrong:

 UrgentTask.prototype = Task.prototype;

That just makes the two classes have the exact same prototype object. Change one and the other will be changed too which is not how inheritance works.

The usual way to derive from a class like this is:

 UrgentTask.prototype = Object.create(Task.prototype);

which creates a new, separate prototype object incorporating the parent properties into the new object.

See a further example here on MDN.

Why do changing in UrgentTask.prototype affects Task.prototype, I mean shouldn't the equality goes one way ?

There is no one-way equality in Javascript so I'm not sure what you mean by that. When you assign an object as in x = y where x and y are objects, you end up with a situation where both variables x and y now point at the exact same object. The object isn't copied into a separate object. Both variables point at the same object.


For more description of how objects are assigned from one variable to another, see these references:

reading / assigning reference types in JavaScript

Is global variable assignment atomic on NodeJS?

Here's a very simple example in a runnable snippet:

let x = {greeting: "hello"};
let y = x;

console.log("x", JSON.stringify(x));
console.log("y", JSON.stringify(y));
console.log('x.greeting = "goodbye"');

x.greeting = "goodbye";

console.log("x", JSON.stringify(x));
console.log("y", JSON.stringify(y));
console.log("x === y is", x === y);

Run this snippet to see the results.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • I mean if you assigned y to x and then changed the value of x that doesn't change the value of y , for example: ``` x = 1 y = 2 x = y x = 3 console.log(y); // 2 ``` Now in here I've assigned Task.prototype to UrgentTask.prototype and then changed UrgentTask.prototype, why did Task.prototype change ? – Mahmoud Soliman Nov 15 '19 at 18:37
  • @MahmoudSoliman - Those are primitive values in your example. They are copied to the new variable. Objects are not copied. They are assigned by pointer (something you just have to learn about how Javascript does things). So, if you then modify a property on the object, both variables are pointing at that same object and will thus see the changed property. Please look at the two references I put in my answer that have examples to show you. – jfriend00 Nov 15 '19 at 18:39
  • @MahmoudSoliman - I added a quick demo snippet you can run. – jfriend00 Nov 15 '19 at 18:44
  • Oh yes it makes sense now, Totally forgot about pass by value and reference. Thanks a lot and sorry for wasting your time. – Mahmoud Soliman Nov 16 '19 at 12:43