本文详细解析JavaScript中方法调用的核心概念,重点阐述方法调用时this关键字指向当前对象的行为。通过代码示例对比点号与中括号访问方式,并深入探讨嵌套函数中this丢失的原因及通过保存this变量进行修复的标准解决方案。
JavaScript方法调用与this指向机制
在JavaScript中,当函数作为对象的属性被调用时,这种调用方式被称为“方法调用”。与方法调用不同,此时函数内部的this关键字不再指向全局对象,而是指向调用该方法的对象本身,该对象即成为方法调用的调用上下文。
代码如下:
var x = 99;
var sample = {
x:1,
act:function(a){
this.x = a*a;//assign value to sample's x, not global object's x.
}
}
sample.act(6);
console.log(sample.x);//36
console.log(x);//99
中括号访问方式
与访问对象属性类似,除了使用点号操作符,JavaScript还支持使用中括号操作符来执行方法调用。
代码如下:
//other ways to invoke method
sample["act"](7);
console.log(sample.x);//49
嵌套函数与变量访问
针对 JavaScript 里的 function,存在一个较为特殊的行为表现,即在 function 内部可以嵌套定义另一个 function(也就是闭包)。当执行方法调用操作时,若该 method 内部包含有嵌套的 function,则此嵌套 function 内部的代码逻辑具备访问外部变量数值的能力:
代码如下:
//nested function can access variable outside of it.
var y = 88;
var sample2 = {
y:1,
act2:function(a){
this.y = inner();
function inner(){
return a*a;
}
}
}
sample2.act2(8);
console.log(sample2.y);//64
console.log(y);//88
嵌套函数中的this丢失问题
然而,与直觉相反的是,嵌套函数无法继承外部方法的this值。在嵌套函数内部,this关键字指向的是全局对象,而非调用方法的对象。
代码如下:
//nested function does not inherit "this". The "this" in nested function is global object
var sample3 = {
act3:function(){
inner();
function inner(){
console.log(this);//window object
}
}
}
sample3.act3();
保存this变量的解决方案
若需在嵌套函数中访问调用方法的对象,可在外部方法中将this的值保存到一个变量中。
代码如下:
//pass "this" to nested function
var sample4 = {
act4:function(){
var self = this;
inner();
function inner(){
console.log(self);//Object {act4=function()}
}
}
}
sample4.act4();