2

when reading the book You Don't Know JS: this & Object Prototypes

I found this example about this binding:

function foo(something) {
  this.a = something;
}

var obj1 = {
 foo: foo
};

var obj2 = {};

obj1.foo( 2 );
console.log( obj1.a ); // 2

obj1.foo.call( obj2, 3 );
console.log( obj2.a ); // 3

var bar = new obj1.foo( 4 );
console.log( obj1.a ); // 2
console.log( bar.a ); // 4

I don't understand why after the execution of new obj1.foo(4) console.log(obj1.a) prints 2 and not 4. And if I comment the line obj1.foo(2) the result of the log above is undefined.

Tuximo
  • 57
  • 11
  • 1
    Because when you use `new`, the `this` value will be a new object. See [What is the 'new' keyword in JavaScript?](http://stackoverflow.com/q/1646698/1529630) – Oriol Feb 06 '16 at 00:09
  • When I tried to modify my question with the answer of Mike C in my mind, I understood very well my problem.Thank you guys. – Tuximo Feb 06 '16 at 01:25

3 Answers3

2

Because any function can be a constructor. Imagine if you used foo by itself:

var obj3 = new foo(3);

You'd expect to get an object similar too { a: 3 }, right?

This still works even if the function is attached to something else. Every time you use new you're creating a new object, not changing an existing one.

In the first instance, you're using the function as a method:

obj1.foo(2);

In this case, the context is set to obj1 since it's the one that invoked it. But when you use new a brand new object is created and that new object is used as the context.

Mike Cluck
  • 28,921
  • 12
  • 72
  • 85
2

When you call this obj1.foo( 2 ) you execute the method of obj1 passing as an argument the 2. When foo is executed defines a property called a to the calling object and assigns to it the value of something, 2 in this case. The calling object in this case is obj1. So for this reason obj1 acquires a property called a with the value of 2.

And if I comment the line : obj1.foo(2) the result of the log above is undefined.

This is happens because if you comment the line you mentioned. The obj1 doesn't acquire a property a. Hence a is undefined in this case. Generally, speaking, if we consider an empty object obj, obj = {}. If you do the following:

obj.a

You define a property called a on the object obj. Furthermore, if you do the following:

obj.a = 4;

You do two things, you define the property a and you assign a value to it.

Christos
  • 50,311
  • 8
  • 62
  • 97
0

So, let's break it down to smaller steps.

First off, obj1.foo calls the foo function. The foo function takes one argument and assigns that argument to the a key of the object that is calling foo (it's a bit more complicated than that, I can elaborate afterwards if you'd like).

So when you call obj1.foo(2), you're calling the foo method, passing in the parameter 2 by the perspective of the obj1 object. That is why obj1.a will equal 2. Since that's the command that assigns a value to obj1.a, the omission of that call will cause obj1.a to be undefined.

Jonas Meinerz
  • 562
  • 2
  • 9