首先,我们需要明白 this 只是函数执行上下文中的一个属性,它的值取决于函数的调用方式,是动态绑定的。
在全局作用域中的this
全局作用域中this指向全局对象
-
Node.js 环境中 this 指向 global 对象
-
浏览器环境中 this 指向 window 对象
-
“伪全局” : Node.js的独立模块中 this 指向 module.exports
- 在Node.js环境中每一个文件都是一个独立模块,在模块内部 this 不指向global对象,而是 module.exports对象
this的绑定规则:函数中的this
函数中的this指向就较为复杂了主要分为三种绑定规则
-
默认绑定 :当函数被独立调用时,函数中的this指向全局对象
- 在浏览器环境中
-
隐藏绑定与隐式丢失
-
隐式绑定:当函数被其它对象引用,且被该对象调用时,函数中的this会绑定到该对象上。
-
隐式丢失:类似于就近原则,当函数被多层对象调用时,函数的this指向离函数最近的对象。
- 图中this 指向了对象 obj 而不是 obj_1
-
-
显式绑定:利用call(),apply(),bind() 函数主动将函数中的this绑定到某个对象上。 在Function的原型中存在call(),apply(),bind()等方法用于显式绑定this,因此所有函数都可以直接使用这些方法
-
利用call()函数 显式绑定this
-
且call()函数还可以帮助调用它的对象接收参数
-
-
apply() 作用与call相同,只是apply接收参数的方式不同,apply接收的参数是一个数组。适合多值传递。
-
利用bind(),作用与call相同,但是会返回一个新的函数对象,并且只绑定但不触发函数
-
只绑定不触发
-
现在我们把新的函数触发掉
- 我们发现 bind()包装后的函数同样可以帮助原函数接收参数
-
扩展
-
箭头函数:没有自己的this属性,如果在箭头函数中写下this关键字,此关键字代表箭头函数外层中的this。
- this指向全局,而不是obj对象,说明this借用的是obj对象的this- 证明:箭头函数自身内部不具备this属性
- 如果obj对象内部定义了一个普通的函数体,obj.fn()调用时,函数中的this指向的是obj对象
总结
- 全局作用域中,this指向该环境的全局对象或者模块(global,window,module.exprots)
- 函数中的this,共有三种绑定规则
- 默认绑定,函数被独立调用,this指向全局对象
- 隐式绑定,函数被其它对象引用时,this指向引用该函数的对象
- 隐式丢失,多层调用函数时,this指向离该函数最近的对象
- 显式绑定:利用Function原型中定义的函数call()、apply()、bind()等函数主动为函数中的this绑定一个对象。
- 箭头函数不拥有自己的this属性