这是javascript前端编程中非常常用的关键字,也是一道常见的面试题。但是由于这不是其他面向对象语言的定点,而是不同的调用代码,会产生不同的点。这。下面我们系统地分析一下我们在编程的时候在各个案例中是如何理解this点的。这个的定义首先,当我们面对一个编程语言的问题,尤其是关键字或者nativeAPI的时候,第一反应应该是查看官方文档,因为官方文档是最正确、最权威、最通俗的解释,这就是也是我这么多年编程经验的总结。下面是MDNWeb文档中对此的解释。与其他语言相比,函数的this关键字在JavaScript中的行为略有不同,严格模式和非严格模式之间也存在一些差异。在大多数情况下,函数的调用方式决定了this(运行时绑定)的值。this在执行过程中不能赋值,每次调用函数时this的值可能都不一样。ES5引入了bind方法来设置函数的this值,而不管函数是如何调用的。ES2015引入了箭头函数,它不提供自己的this绑定(this的值将保留封闭词法上下文的值)。最重要的一句话是,“调用函数的方式决定了this(runtimebinding)的值”,我们可以这样理解,比如调用person.run()时,run方法中的this指向person目的。在下一章中,我们将结合具体案例进行详细分析。(以下案例参考非严格模式的案例分析)this的案例分析我们将用6个案例来分析每个场景下this的含义Case1函数执行functionrun(){console.log('this->'+this)}run()//this->[objectWindow]console.log('this->'+this)//this->[objectWindow]vartitle='window'functiondoJob(){lettitle='doJob'functiontest(){console.log('this->'+this.title)//this->window}test()}doJob()第一个是运行时打印this对象,由于没有指定run的执行对象,所以默认this指向window。二是在全局环境中打印this,这也是默认的window对象。第三点是看测试的执行情况。测试是单独执行的,没有任何绑定对象,所以测试中的this是window对象Case2对象创建函数run(){this.sum=18console.log('this->'+this)}newrun()//this->[objectObject]letperson={name:'123',prun:run};person.prun()//this->[objectObject]letarr=[1,2,run]arr[2]()//this->1,2,functionrun(){...}注意:new在执行过程中会做四件事来创建一个新的子对象;让子对象继承其原型对象(prototype)构造函数;调用构造函数,将this指向子对象,并为子对象添加相应的属性(比如在run中添加this.sum=18);将子对象返回到函数外部。当第一个newrun()执行时,可以理解为new转run进入构造函数。这时候this会指向新创建的子对象,打印//this[objectObject]的结果。第二个人.run()执行时,this指向'.'前面的person对象,所以this指向person。当执行第三个arr[2]()时,this指向arr数组。Case3调用、申请、绑定应用函数run(){console.log('this->'+this)}letobj={name:'456'}run.call(obj)//this->[objectObject]run.apply(obj)//this->[objectObject]letbindRun=run.bind(obj)bindRun()//this->[objectObject]函数调用、apply、bind具有指定this的作用影响函数执行范围的对象。所以上面都是打印指定的obj对象。案例4dom绑定
