上次聊的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吧
作者:业余马拉松选手
链接:https://www.jianshu.com/p/7c13b4968c9a