0

Say we have the following example:

const Foo = {
  init: function(who) {
    this.me = who;
  },
  speak: function() {
    console.log(this.me);
  }
};

Then we have new objects whose prototype references foo:

  const b1 = Object.create(Foo);
  const b2 = Object.create(Foo);
  b1.init("Kristopher");
  b2.init("Jane");
  b1.speak();
  b2.speak();

The output is the following:

Kristopher
Jane

But I would have expected "this" to refer to the context of the prototype function. If each new object merely references the prototype, I thought the following would be output:

Jane
Jane

Why is this not the case? I thought that since Foo is the shared prototype of b1 and b2, that modifying this.me would overwrite the variable for both b1 ad b2?

kag359six
  • 1,693
  • 2
  • 16
  • 21
  • 4
    `this` refers to the *current* calling context. In this case, this is the instance created by `Object.create` and stored in, say, `b1`. The prototype is unaffected. If it was, then the whole prototype chain would be pretty useless if everything that descends from a prototype only modifies that prototype. – VLAZ May 10 '19 at 18:43
  • @VLAZ awesome thank you. Can you make that an answer so I can accept it – kag359six May 10 '19 at 18:59

1 Answers1

2

Let's break it down:

const b1 = Object.create(Foo);
const b2 = Object.create(Foo);

These lines create two separate instances, using Foo as prototype.

b1.init("Kristopher");

You called init with "Kristopher" as argument. this in this case is b1. init would assign "Kristopher" as b1's me.

b2.init("Jane");

You called init with "Jane" as argument. this in this case is b2. init would assign "Jane" as b2's me.

b1.speak();
b2.speak();

Prints the me of both objects.

An easier way to put it is that the value of this is not fixed at the time you wrote it (which made you think it was Foo). It depends on how the function was called when it was called.

const obj = { somefunc() { ... } }

obj.somefunc() // this === obj

const foo = obj.somefunc
foo() // this == window in non-strict mode, this === undefined in strict mode

const arr = []

const bound = obj.somefunc.bind(arr)
bound() // this === arr

obj.somefunc.call(arr) // this === arr
obj.somefunc.apply(arr) // this === arr
Joseph
  • 117,725
  • 30
  • 181
  • 234