Click here to Skip to main content
Click here to Skip to main content
Go to top

Is JavaScript function invocation confusing?

, 3 Oct 2014
Rate this:
Please Sign up or sign in to vote.
Answer will be Yes for those “Who don’t understand the core primitive of JavaScript function”. No for those “Who understands the core primitive”.

Answer will be…

  • Yes for those “Who don’t understand the core primitive of JavaScript function”.
  • No for those “Who understands the core primitive”.

So, what is “Core Primitive In JavaScript Function Invocation”?

Lets start

When we write a JavaScript function, we do following things…

Code

function greet(thing) {
    console.log(this + " says hello " + thing);
} 

greet.call("Maddy", "world");

Output

Maddy says hello world

Explanation:

So, here you can see that function argument are two when we call, but there is only one argument in function definition. In JavaScript function, the first argument acts as this, and then others are as argument.
Let’s understand it by calling the above differently.
If we call the same function as

greet.call('Maddy');

Output

Maddy says hello undefined

NOTE : It will take the first argument as this.
Obviously calling a JavaScript function with .call() is bit annoying. So JavaScript allows us to call directly.
So when we call it like

Code

greet('Maddy');

Output

[object Window] says hello Maddy

Basically, what it dose is, when we call like the last way

greet('Maddy');

Then JavaScript takes it it like…

greet.call(window, "world");

Member Function Invocation

When we create a object and add a function as a member, and call that function then it act as differently.
Like it take that created object as the default parameter.

Code

var person = {
    name:'Maddy',
    greet: function (thing) {
            console.log(this + " says hello " + thing);
    }
};

// this:
person.greet("world"); // Output - [object Object] says hello world
 
// takes it to this:
person.greet.call(person, "world"); // Output- [object Object] says hello world

It doesn’t actually matter how that method is being attached.
Let’s see what happens when we attach it dynamically:
Now we will attach a method to an object dynamically.

function greet(thing) {
    console.log(this + " says hello" + thing);
}

person = { name: "mac" }
person.greet = greet;
 
person.greet("world") // act as person.greet.call(person, "world")
greet("world") // "[object DOMWindow]world"

Here what the conclusion on above:

  1. Create function
  2. Creating the argument list from arg1 till end
  3. Then call that function

    Function.prototype.bind

    Yes, it can help us having a persistent value of “this” with reference to a function.
    So with some minor “closure” tricks we can make the value of “this” persistent.

    // define the object 
    var person = {
    	name: "Mac",
    	greet: function(thing) {
    		return  (this.name + " says hello " + thing);
    	}
    }
    
    var boundHello = function(thing) { 
    	return person.greet.call(person, thing);  // Here the use of call method to change the value of "this"
    }
    
    alert(boundHello("world")); // Output- Mac says hello world.
    

    Here it in more generic fashion:

    var person = {
    	name: "Brendan Eich",
    	greet: function(thing) {
    		console.log(this.name + " says hello " + thing);
    	}
    }
    
    var bind = function(func, thisValue) {
    	return function() {
    		return func.apply(thisValue, arguments); //more generic using apply() method
    	}
    }
     
    var boundHello = bind(person.greet, person);
    boundHello("world");// "Mac says hello world"
    

    In the above code the bind method returns a new function by invoking original function.

    Bind is useful

    var person = {
    	name: "Mac",
    	greet: function(thing) {
    		console.log(this.name + " says hello " + thing);
    	}
    }
    
    var boundHello = person.greet.bind(person); // it bind person object to the greet method
    boundHello("world") // "Mac says hello world"
    

    Also, if you want to directly call it on dom operation

    var person = {
    	name: "Mac",
    	greet: function() { console.log(this.name + " says hello world"); }
    }
    	 
    $("#some-div").click(person.greet.bind(person)); 
    // raw function to pass as a callback: 
    // Output - Mac says hello world
    

    NOTE :
    jQuery uses these call and apply methods internally to set the this value to other than window.

    Conclusion

    This is an extremely powerful thing but it makes an wrong impression on beginners as this is very strange.But if we carefully understand the core primitive of javascript functions, and its invocation we can use it many ways.

    Thanks for reading Smile | :)


    • Function doesn’t have a persistent value of its ‘this’.
      • It is always set at call time based upon the way it was invoked by its caller.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

_debasis
Software Developer Mindfire Solutions
India India
Software Engineer | Blogger | Reader| Music Lover | Cook | Traveler | Foodie
Follow on   Twitter   Google+   LinkedIn

Comments and Discussions

 
GeneralMy Vote 5 PinmemberShemeemsha RA2-Oct-14 5:42 
GeneralMy vote of 3 PinmemberThanhTrungDo1-Oct-14 7:24 
QuestionThe first example and the second example are lying PinmemberThanhTrungDo1-Oct-14 7:23 
QuestionWhy! PinmemberBob100030-Sep-14 10:18 
GeneralRe: Why! Pinprofessional_debasis30-Sep-14 20:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.141002.1 | Last Updated 3 Oct 2014
Article Copyright 2014 by _debasis
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid