灵感
上个星期课余时间很少编程😏,联合了两三个寝室的同学一起玩转「狼人杀」游戏,直到昨晚老霄问我一个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
就是第一个参数 - 有时候细节很可怕,还要看清楚作用域在哪里