灵感
上个星期课余时间很少编程😏,联合了两三个寝室的同学一起玩转「狼人杀」游戏,直到昨晚老霄问我一个this指向的问题,让我有了少许的回顾时间。突然有一个灵感告诉我:JavaScript里的this其实就相当于「狼人杀」中跳身份以及逻辑判断(这真的是一个讲逻辑的游戏)。
出现地点
作为函数调用
在函数被直接调用时,this会绑定到全局对象。而在我们浏览器中,window就是全局对象
|
|
其实很多时候,我们会忘记我们写的代码还在一个隐藏的作用域里(即全局作用域)。初学的时候,看见过这样的一句话「申明的变量都会挂在window(全局对象)上」,其实window就是一匹铁狼,还是那一匹我们最容易忘记它身份的😲
内部函数
当我们开始写一些嵌套函数的时候,当里面出现this的时候,请注意执行的地方。
setTimeout、setInterval
这两个是延时函数,运行的规则是看运行队列是否已经结束,最后由window执行回调函数,所以this指向的是全局对象
作为构造函数调用
构造函数就是通过一个函数生成一个新对象(object)。这时候,this的指向就是这个新对象。
因为使用了new运算符,其后面跟着一个函数F以及函数的参数:new F(args)。在生成一个新对象这一过程分为三步:
- 创建类的实例:把一个空对象的
__proto__属性绑定到F.prototype - 初始化实例:将传入的参数的函数
F执行一遍,this被绑定到了这个实例上 - 返回实例123456789function Person(name){this.name = name;}Person.prototype.printName = function(){console.log(this.name);};var p1 = new Person('Byron');p1.printName(); // Byron
作为对象方法调用
如果一个函数是是写在对象里面,此时该函数叫做该对象的方法,这时调用函数,this自然绑定到改对象
DOM对象绑定事件
在事件处理程序中this代表事件源DOM对象(低版本IE有bug,指向了window)
新招
上面只是列举了一些ES5语法下出现的方式。那时候我记得方法是谁调用,那么this指向的就是他,因为笔者专业偏管理,就想到会计中的谁受益谁承担的概念。
其实还有一种方法来解释this:
F.call(context,arg1)
函数还有call/apply的调用方法,而且里面的第一个参数context就代表着this的指向。call使用MDN介绍
|
|
这时候你会说,那不应该是underfined吗?可是这个API的文档有规定:
如果这个函数处于非严格模式下,则指定为null和undefined的this值会自动指向全局对象(浏览器中就是window对象)
|
|
那么其他的出现的方法也就类似的解法了
昨晚问题
|
|
总结
- 谁调用,
this就是谁 - 可以转变
call调用,this就是第一个参数 - 有时候细节很可怕,还要看清楚作用域在哪里
