Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript difference between calling a function and creating an instance of a function

Tags:

javascript

I am trying to understand why an inner function can access a public property of an outer function when the outer function is called directly, but not when it is assigned to a variable?

Example:

function outer(x,y){

    this.x = x;
    this.y = y;

    function inner(){
        alert(this.x);       
    }

    inner();
}

outer(1,2); //As expected, alerts 1
var func = outer(1,2) //Also alert 1
var func2 = new outer(1,2); //Alerts undefined

One thing I tried was to remove the this keyword from alert(this.x); and it did work for all three cases. However, if I do remove the this keyword, I'd be accessing the passed in param, not the public variable, which is definitely not the desired action. Can someone explain this behavior?

like image 599
Hazem Salama Avatar asked Aug 23 '12 13:08

Hazem Salama


People also ask

What is the difference between calling function with () in JavaScript?

The call() allows for a function/method belonging to one object to be assigned and called for a different object. call() provides a new value of this to the function/method. With call() , you can write a method once and then inherit it in another object, without having to rewrite the method for the new object.

What is the difference between a function and a function call?

A function is a block of code that does a particular operation and returns a result. It usually accepts inputs as parameters and returns a result. The parameters are not mandatory. A function call is the code used to pass control to a function.

What is function instance in JavaScript?

The JavaScript instanceof operator is used to check the type of an object at the run time. It returns a boolean value(true or false). If the returned value is true, then it indicates that the object is an instance of a particular class and if the returned value is false then it is not.

Is calling and invoking a function same?

There is a very slight difference between calling and invoking a function. In JavaScript functions can be invoked without being called which means that the code inside the body of the function can be executed without creating an object for the same.


2 Answers

When you call outer(1, 2) like that, this is a reference to window, so "x" and "y" are effectively global variables. That's why inner() can access "x".

When you call new outer(1, 2) you have caused this (in "outer") to be a reference to a new object. When "inner" is called inside "outer", this will still reference window, so there's no "x".

The value of this is determined for every function call, and the value depends only on the particulars of that call. Thus the fact that you call "outer" via new has no effect on the interior call to "inner" — because you simply call the function as inner();, the value of this inside that function will be a reference to window (well, the global context, whatever that is).

Here are the ways this can be set upon a call to a function:

  1. If the function is called via the new operator, then this will refer to a newly-created object.
  2. If the reference to the function is obtained via a property lookup on an object (foo.someFunction()), then this will be a reference to that object.
  3. If the function is called via .call() or .apply() from the Function prototype, then this will refer to the first argument to whichever of those functions was used, coerced to an object value if necessary.
  4. If the function is called via a simple "naked" reference, then this will refer to the global context (window in a browser). edit — Šime Vidas points out in a comment above that in strict mode, this case results in this being null (which really makes a little more sense, and would avoid the weirdness observed in the OP).
like image 166
Pointy Avatar answered Sep 25 '22 00:09

Pointy


There are 4 ways to use a function in Javascript what each of these does is change what the content of this is :

  • function calls: this = global object (window in browser)
  • method calls: this = object it is called from.
  • constructor calls: this = new object you are creating.
  • call/apply calls: this = object you passed.

In your case this == window when you call the function directly (outer()) but if you call using new (new outer()) then it will be the new object you are creating.

basically what I wrote here

like image 37
Mark Broadhurst Avatar answered Sep 23 '22 00:09

Mark Broadhurst