在平时的代码中,相信大家经常用到 this,可是你真的明白此 this 真的是你认为的 this 吗?今天柚子君总结了一下平时用到的 this 的场景,大家走过路过不要错过啊~
首先咱们先来看一下《JavaScript 高级程序设计》上是怎么说的。
this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this等于windows,而当函数被作为某个对象的方法调用时,this等于那个对象。
还有一种情况,在《深入理解 ES6》一书中写道:
如果箭头函数被非箭头函数包含,则
this绑定的是最近一层非箭头函数的this,且不能通过call()、apply()或bind()方法来改变this的值。
首先看一下非箭头函数的情况:
一、普通函数调用
这是一个普通的函数声明,在这种情况下,this 是指向 window 的.
其实上面的代码就相当于 window 调用 thisHandler(),所以这时 this 指向 window:
|
|
二、作为对象的方法调用
当作为对象的方法被调用时,this 这时就指向调用它的对象。
再来一个栗子🌰:
|
|
这时 this 指向的是对象 fn 了,所以,关于对象调用这一点明白了吗,如果明白了,那没关系,接着看下一个强化题😏:
🍭 这里是一秒钟分割线 🍭
哒哒哒,答对了,这里的 this 指向的 window,那么这是为什么呢,哪位小盆友来回答一下。
举手:
上面说到了,
this指向的是最后调用它的对象,第一步是赋值给了testHandler,最后执行的那一句相当于window.testHandler()。所以这里的this指向的是window。最后输出的就是my name: 柚子。
哒哒哒,真聪明,来闯下一关~
三、构造函数的调用
|
|
其实要明白为什么会是这样一个结果,咱们就要来聊聊 new 做了哪些事情。
- 创建类的实例。这步是把一个空的对象的
__proto__属性设置为Bar.prototype。 - 初始化实例。函数
Bar被传入参数并调用,关键字this被设定为该实例。 - 返回实例。
弄明白了 new 的工作内容,自然而然的也明白了上面输出的原因。
Bar()中的this指向对象handlerA,并不是全局对象。
四、apply / call 调用
关于 apply,可以看一下 MDN 关于 apply() 方法的说明。
使用 apply 方法可以改变 this 的指向。如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动指向全局对象(浏览器中就是window对象)。
|
|
下面是箭头函数的舞台~
四、箭头函数
在《深入理解 ES6》一书中可以知道箭头函数和普通函数的一个不同之处就在于 this 的绑定。
箭头函数中没有
this绑定,必须通过查找作用域链来决定其值。如果箭头函数被非箭头函数包含,则this绑定的是最近一层非箭头函数的this;否则,this的值会被设置为undefined。
|
|
这时 this 不是指向 thisHandler,而是 Window。
关于 this 的使用和体会还是要在平时运用中理解,先了解其原理,那么在使用的时候就如鱼得水啦。