本文来自 @position_柚子,地址:https://juejin.im/post/5995c7a76fb9a0247a60c407javascript
在平时的代码中,相信你们常常用到 this
,但是你真的明白此 this
真的是你认为的 this
吗?今天柚子君总结了一下平时用到的 this
的场景,你们走过路过不要错过啊~java
首先我们先来看一下《JavaScript 高级程序设计》上是怎么说的。windows
this
对象是在运行时基于函数的执行环境绑定的:在全局函数中,this
等于 windows
,而当函数被做为某个对象的方法调用时,this
等于那个对象。浏览器
还有一种状况,在《深刻理解 ES6》一书中写道:app
若是箭头函数被非箭头函数包含,则 this
绑定的是最近一层非箭头函数的 this
,且不能经过 call()、apply() 或 bind()
方法来改变 this 的值。函数
首先看一下非箭头函数的状况:post
这是一个普通的函数声明,在这种状况下,this
是指向 window
的:this
var test = '哈哈哈'; function thisHandler() { console.log('test:',this.test,'this:',this); } thisHandler() // test: 哈哈哈 this: window
其实上面的代码就至关于 window
调用 thisHandler()
,因此这时 this
指向 window
prototype
var b = '哈哈哈'; function thisHandler() { console.log('b:',this.b,'this:',this); } window.thisHandler() // b: 哈哈哈 this: window
看成为对象的方法被调用时,this
这时就指向调用它的对象。设计
var thisHandler = { name: "柚子", test: function(){ console.log('my name:',this.name); } } thisHandler.test() // my name: 柚子
再来一个栗子:
var thisHandler = { name: "柚子", fn: { name: '芒果', test: function() { console.log('my name:',this.name); } } } thisHandler.fn.test() // my name: 芒果
这时 this
指向的是对象 fn
了,因此,关于对象调用这一点明白了吗,若是明白了,那不要紧,接着看下一个强化题:
var name = '柚子' var thisHandler = { name: "芒果", fn: { name: '糖果', test: function(){ console.log('my name:',this.name); } } } var testHandler = thisHandler.fn.test testHandler()
这里是一秒钟分割线
哒哒哒,答对了,这里的 this
指向的 window
,那么这是为何呢,哪位小盆友来回答一下。举手:
上面说到了,this
指向的是最后调用它的对象,第一步是赋值给了 testHandler
,最后执行的那一句至关于 window.testHandler()
。因此这里的 this
指向的是 window
。最后输出的就是 my name: 柚子
。
哒哒哒,真聪明,来闯下一关~
var name = '柚子' function Bar() { this.name = '芒果' } var handlerA = new Bar(); console.log(handlerA.name); // 芒果 console.log(name) // 柚子
其实要明白为何会是这样一个结果,我们就要来聊聊 new
作了哪些事情。
__proto__
属性设置为 Bar.prototype
。Bar
被传入参数并调用,关键字 this
被设定为该实例。弄明白了 new
的工做内容,天然而然的也明白了上面输出的缘由。
Bar()
中的 this
指向对象 handlerA
,并非全局对象。
使用 apply
方法能够改变 this
的指向。若是这个函数处于非严格模式下,则指定为 null
或 undefined
时会自动指向全局对象(浏览器中就是window对象)。
var name = '芒果'; var thisHandler = { name: "柚子", test: function(){ console.log('my name:',this.name); } }; thisHandler.test(); // my name: 柚子 thisHandler.test.apply(); // my name: 芒果
在《深刻理解 ES6》一书中能够知道箭头函数和普通函数的一个不一样之处就在于 this 的绑定。
箭头函数中没有 this
绑定,必须经过查找做用域链来决定其值。若是箭头函数被非箭头函数包含,则 this
绑定的是最近一层非箭头函数的 this
;不然,this
的值会被设置为 undefined
。
var name = '柚子' var thisHandler = { name: '芒果', test:() => { console.log('my name:',this.name,'this:',this); } } thisHandler.test(); // my name: 柚子 this: Window
这时 this
不是指向 thisHandler
,而是 Window
。
关于 this
的使用和体会仍是要在平时运用中理解,先了解其原理,那么在使用的时候就如鱼得水啦。