2

Hey guys i have this below small programme :

function foo() {
  this.x = 2;
  return this;
}


var y = foo();
var g = foo();                                                                                                             
g.x = 3;
console.log("y", y.x); // 3
console.log("g", g.x); // 3
console.log("this", this.x); //3

now all 3 console.logs print 3 , i guess the 1st console.log prints 3 because y.x is overwritten by g.x but i don't quite get why this.x prints 3 , because i have no this.x in the global scope .

My 1st question : Why does this.x print 3 ?

now if my original programmer is corrected in the following way(basically i am adding the new operator) :

function foo() {
              this.x = 2;
              return this;
            }

            var y = new foo();
            var g =  new foo();                                                                                                             
            g.x = 3;
            console.log("y", y.x);   // 2
            console.log("g", g.x);   // 3
            console.log("this", this.x); // undefined

I get more predictable results or rather expected ones (check comments) .

What difference the new operator makes eludes me , now i browsed through SO and found this below thread :

New operator

also i saw the MDN doc's, but still i'am confused .

can somebody answer my 1st question and then also tell me Most Importantly ,how does the new operator make any difference ? in my example , make ur answer concise , just tell me the exact reason why the new operator gives me the results i want ?

Thank you .

Alexander .

Community
  • 1
  • 1
Alexander Solonik
  • 9,838
  • 18
  • 76
  • 174
  • 3
    in first case _this_ is _window_ object, in second - _this_ - created object – Grundy Feb 16 '15 at 11:28
  • In the first case y,g,and this POINT to the same object, as objects in javascript are passed by reference. When using new (practice that is not recommended by Crockford) you are instancing different objects, so changing the values of a property of an object does not involve other objects. – lateralus Feb 16 '15 at 11:30
  • It would be LOVELY if you could document Your LOVELY comments in an answer and just post it , Thanks though ! . also be elaborate and concise at the same time . – Alexander Solonik Feb 16 '15 at 11:32
  • @Grundy new implicitly returns the function , which means it points to the function ? – Alexander Solonik Feb 16 '15 at 11:35
  • Relevant: [You Don’t Know JS: this and Object Prototypes](https://github.com/getify/You-Dont-Know-JS/tree/master/this%20%26%20object%20prototypes), chapter [one](https://github.com/getify/You-Dont-Know-JS/blob/master/this%20&%20object%20prototypes/ch1.md) and [two](https://github.com/getify/You-Dont-Know-JS/blob/master/this%20&%20object%20prototypes/ch2.md) in particular. – Tim S. Feb 16 '15 at 11:35
  • 1
    @AlexanderSolonik in most cases _new function()_ return new object, you can read about it on [mdn](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new) – Grundy Feb 16 '15 at 11:37
  • @AlexanderSolonik my comment is based on "Javascript: The good parts", one of the most appreciated Javascript books by Crockford. – lateralus Feb 16 '15 at 11:56
  • 1
    @AlexanderSolonik you need more read about [this keyword in javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this) – Grundy Feb 18 '15 at 07:30

2 Answers2

3

To determine the value of this in a function, Javascript looks at how you call this function:

  • if you call it with .apply (or .call), as in foo.call(someObj), this is the value of the first argument
  • if there's a new before the function call, this is a newly created object
  • if there's a dot (or a bracket) before the function, as in someObj.foo(), this is what precedes the dot (someObj here)
  • if there's nothing before the function name, this is the Global object (window if you run in a browser)

NB: the above is intentionally simplified, refer to the standard for the full picture (search for "thisArg")

So, in your first snippet, you modify the Global object and return it. In the second snippet, you modify and return a fresh object created by new.

georg
  • 211,518
  • 52
  • 313
  • 390
-1

My question was about why when i use the new keyword in the below programme , do i get the desired result , look below .

function foo() {
              this.x = 2;
              return this;
            }

            var y = new foo();
            var g =  new foo();                                                                                                             
            g.x = 3;
            console.log("y", y.x);   // 2
            console.log("g", g.x);   // 3
            console.log("this", this.x); // undefined

now without new the result is

console   
 3 
 3 
 undefined

now i did read the Mozilla but it was less helpful in understanding the new keyword .

what my common sense tells me is that when i say the following :

p = foo();

i am still referring to the original copy of foo(), so any modifications made to p will affect foo() .

but when i say :

p = new foo(); 

i am actually creating a new independent copy that exactly like foo() but not bound to it . p can now be used and modified without affecting the original foo() .

well sometimes common sense works better , than documentation(i still recommend reading the documentation though LOL .)

new was just doing what it was suppose to do , Make a new independent instance of the function .

georg
  • 211,518
  • 52
  • 313
  • 390
Alexander Solonik
  • 9,838
  • 18
  • 76
  • 174
  • 1
    No, your understanding is wrong. Function calls don't make copies of functions. If your function returns "this", its return value depends on how you call it. – georg Feb 17 '15 at 12:12
  • @georg i don't quite get it , when i'am saying . var p = foo(), p is pointing to the original foo() function right ? but when i say var p = new foo() , p is an independent copy of foo() , is that right ? there is no `this` keyword involved here , i am talking only about the new keyword . Thanks – Alexander Solonik Feb 17 '15 at 13:06
  • No. After `var p = foo()`, `p` is what the function returns and it's not linked to `foo` in any way. Consider e.g. `function foo() { return 1 }; p=foo()` - `p` is just "1", it has no connection to the function. – georg Feb 17 '15 at 13:14
  • 1
    @AlexanderSolonik you need more read about [this keyword in javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this) – Grundy Feb 18 '15 at 07:29