Let’s first look at a piece of JavaScript code with two layers of functions nested:
var me = {
name : 'Jimbor',
blog : 'http://jmedia.cn/',
sayMyName : function(){
var pre = 'My name is: ';
function displayName(){
alert(pre this.name);
}
displayName();
}
}
me.sayMyName();
From the code point of view, we hope to display the name attribute of me through the call of sayMyName(), that is: My name is: Jimbor. But the execution result of the browser is:
My name is:
What is the reason why the name attribute is not displayed correctly? It turns out that JavaScript binds this within a global function to a global object, and the same explanation is used for nested functions. The consequence of this error is that nested functions cannot be easily used to complete certain special tasks, because these functions interpret the object pointed to by this differently.
Of course, for this example, we can complete the corresponding function without nested functions. But for some applications this structure may be required. Fortunately, there are ways to correct this mistake.
Method 1: Use the apply() function
apply (this_obj, params_array)
apply() function can rewrite the object pointed to by this when calling a function. It accepts two parameters. The first this_obj is the object you want to rewrite this. The object pointed to, params_array is the parameter array used to pass to the calling function. We rewrite the original code as:
var me = {
name : 'Jimbor',
blog : 'http://jmedia.cn/',
sayMyName : function(){
var pre = 'My name is: ';
function displayName(){
alert(pre this.name);
}
displayName.apply(me);
}
}
me.sayMyName();
Look at the browser execution result:
My name is: Jimbor
Similar functions include call(). The difference is that call() passes parameters one by one instead of packing them into an array.
Method 2: Replace this with that
That is, we can define a variable in the outermost function to point to the object pointed to by this. Once the internal function needs to call this, we will use this defined variable. Usually according to convention, this variable will be named that. Then the original code can be changed to this:
var me = {
name : 'Jimbor',
blog : 'http://jmedia.cn/',
sayMyName : function(){
var pre = 'My name is: ';
var that = this;
function displayName(){
alert(pre that.name);
}
displayName();
}
}
me.sayMyName ();
Very useful, isn’t it? Because it does not involve specific object specification, the second method is more recommended.