上次聊的this的问题,基本都还是在“术”的层面,没有更深入的解释,今天就试着继续深入的聊一聊
先说一下之前提到过的“上下文环境”这个词吧。其实在JavaScript中,每个函数在执行的时候都是会单独一个执行环境,我们再拿上次最后的例子来看下:
var b = {
name : "I'm b",
say : function(){
var updateName = function(newName){
this.name = newName;
}
updateName("I'm Big B");
console.log(this);
console.log(this.name);
}
}
b.say();
这里,updateName这个函数表达式,在执行的时候,是会单独一个执行环境,也就是说是在global的环境下的,那么你可能就要问了。上下文执行环境是否可以切换呢,当然是可以的,上次我们用self = this
的方法就是一种,那么还有一类就是使用apply和call,我们继续在之前的代码上进行调整:
var b = {
name : "I'm b",
say : function(){
console.log( "say:"+this.name);
}
}
b.say();
var c = {
name : "I'm c"
}
b.say.apply(c);
当然,这个例子中,你也可以使用call,具体这两个方法的区别,主要就是参数上的差别,但一般常用的场景就是在去切换执行的上下文环境中,这种用法建议你可以多想想,也算是this理解的一种延伸
那么下面我们再接着聊聊在闭包的玩法
闭包也算是JavaScript里不太好掌握的一个点了,而实际上我们在我们的乱弹中竟然还没涉及,其实主要是我自己还理解的不够好,这次就接着this的用法,稍微提一下闭包吧
根据“红宝书”里一句最经典的定义:闭包是指有权访问另一个函数作用域中变量的函数。好,我们还是继续看代码吧
var b = {
name : "I'm b",
hobby : ['running','singing','play video game'],
showInfo : function(){
console.log("show info:"+this.name); //this是指向b这个对象的
this.hobby.forEach (function(hobby){
console.log(this);// this是指向global对象的
console.log(this.name);//这里是undefined
console.log(hobby+"|");
})
},
say : function(){
console.log( "say:"+this.name);
}
}
b.showInfo();
那么如果我确实需要在闭包的函数里访问这个对象里的值怎么办呢?恩,其实还是老办法,在外面定义一个值来保存这个this,然后都不用传了,因为闭包函数本来就是可以访问外部的变量的嘛
好,今天算是稍微深入的讲了一点点this的玩法,但感觉还是不过瘾,下次我们还继续说下this吧