The 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”?
Let's Start
When we write a JavaScript function, we do the following things…
- Create function
- Creating the
argument
list from arg1
till end - Then call that function
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 arguments 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 does is, when we call like the last way:
greet('Maddy');
Then JavaScript takes it like…
greet.call(window, "world");
Member Function Invocation
When we create an object and add a function as a member, and call that function, then it acts differently.
Like it takes that created object as the default parameter.
Code
var person = {
name:'Maddy',
greet: function (thing) {
console.log(this + " says hello " + thing);
}
};
person.greet("world");
person.greet.call(person, "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")
greet("world")
Here is what the conclusion on the above is:
- 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.
Function.prototype.bind
Yes, it can help us in 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.
var person = {
name: "Mac",
greet: function(thing) {
return (this.name + " says hello " + thing);
}
}
var boundHello = function(thing) {
return person.greet.call(person, thing);
}
alert(boundHello("world"));
Here it is in a 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);
}
}
var boundHello = bind(person.greet, person);
boundHello("world");
In the above code, the bind
method returns a new functions by invoking the 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);
boundHello("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));
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 a 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 in many ways.
Thanks for reading! :)
CodeProject