JavaScript中 this的指向取决于function被谁调用,而不取决于其定义。
function fn() { console.log(this) } fn()
上例中,fn是被全局对象调用,因此this指向全局对象。node
const obj = { foo: function () { console.log(this) } } let fn = obj.foo fn() obj.foo()
上例中,fn方法指向obj.foo,因为fn方法被全局对象调用,所以this指向全局对象。而直接调用obj.foo()
,此时foo方法被obj调用,所以this指向obj。浏览器
function Foo() { console.log(this) } const f = new Foo()
上例中,Function Foo被看成构造函数进行了实力化,此时this指向实力化对象f。
ES2015中的class关键字是一种语法糖,其本质仍是声明一个构造函数,所以其内部this指向可参考构造函数。app
function foo() { return () => { console.log(this) } } foo()()
箭头函数虽然也是一种函数,可是其不改变内部this指向,也就是说在查找箭头函数内部this指向时,查找的依然是包裹它的function的调用者。在上例中,foo函数返回的函数是被全局对象调用,所以this指向全局对象。函数
基于上面的四个例子,能够总结出在JavaScript中查找this的步骤为:this
foo()
, this指向全局对象。foo.bar()
,this指向最终调用这个方法的对象。new Person
,this指向新生成的实力化对象。fn.call, fn.apply, fn.bind
,此时this指向调用时传入的参数。在上面提到不少次this指向全局对象,那这个全局对象究竟是什么?命令行
若是在命令行中经过node *.js 执行时,分为下面两种状况。code
if (true) { console.log(this) } console.log(this) // true console.log(this === module.exports)
在上例中,this指向{}。
由于nodejs为保证文件的模块做用域,在执行文件代码时,会为全部的文件代码添加一个包裹函数,上面的执行相似于:对象
// exports 指向module.exports function wrapped(exports) { if (true) { console.log(this) } console.log(this) } wrapped()
所以this会指向{}。ip
function fn() { console.log(this) } fn()
在上例中,fn是全局对象调用,而node环境中,全局对象是Global,所以this指向Global。作用域