this
是JavaScript世界最让人迷惑的关键字之一,如果不明白this
的本质,基本上会被一线互联网公司的面试官扣大量的分。上一篇文章我们知道了执行上下文的概念之后,就更方便理解本篇this的内容了。func
引用了当前执行上下文的变量a
,问题是这个函数func
可以在任意其他执行上下文中被调用,因此这个a
可能就指向不同了。正因为如此,JS引擎需要有一个机制,可以依靠其优雅地、准确地指向当前代码运行时所处的上下文环境(context)。
iAmALongLongLongNameObject
的方法func2
使用了this
关键字,是不是优雅多了?然后即使以后对象名字变化,func2
内部的代码也不用改变。func1
这种确实也可以实现与func2
同样的功能,但是就显得丑陋、不灵活了。this
可以准确地指向(某个对象)而不会产生歧义。this
会指向对象的实例本身”不同,JavaScript的this
指向函数的调用位置的对象,也即调用该函数的对象。你需要知道,JavaScript中所有的函数都有属性,就如对象有属性一样。函数执行阶段(也即执行上下文的执行阶段)会获取this
属性的值,此时this
就是一个变量,储存着调用该函数的对象的值。func
的调用者未通过点操作符.
指明,那它的调用者就是默认的全局对象window
,func
函数作为window
的一个方法,其体内的this.a
就是明确指代window
中属性a
,这种指向是准确而清晰的,不会有歧义。this
的这种灵活性在设计API的时候,会变得很方便和容易被复用。this
的指向。getX
的调用位置,需要先看哪儿调用了它,很明显,有函数有两处位置调用了函数getX()
,接下来分析是谁调用了它。module
对象的getX
方法被调用。 这种情况被谁调用?很明显是被对象module
调用,this是指向module
。module
对象里面有一个属性x
,它的值是1891
,因此console.log(module.getX())
输出1891
。getX
被调用。 这种情况是被谁调用?我们都知道全局函数可以看作为window
对象的方法,那么,很明显现在getX
是被当做全局对象window
的一个方法被调用。this
既不指向函数自身也不指向函数的作用域,这之前是很多前端工程师容易误解的地方,现在澄清一下。this
的指向,是在函数被调用的时候确定的,也就是执行上下文被创建时确定的;this
的指向和函数声明的位置没有任何关系,只取决于函数的调用位置(也即由谁、在什么地方调用这个函数);this
的指向就已经被确定了,在执行阶段this
指向不可再被更改。this
指向全局对象window
。this
指向对象的并不是调用位置是否处于严格模式,而是函数体是否处于严格模式。如果函数体处于严格模式,this
会指向undefined
,否则this
会指向全局对象。this
的指向由调用位置的调用者决定。如果调用者调用的函数,为某以个对象的方法,那么该函数在被调用时,其内部的this
指向该对象。this
指向最终调用函数的对象。这句话可能说得比较拗口,其实简单通俗地说,this
指向最靠近被调用函数的对象,离得远的不是。举例来说:Function
的三个原型方法call()
、apply()
和bind()
,它们的第一个参数是一个对象,它们会把这个对象绑定到this
,接着在调用函数时让this
指向这个对象。bind
可以修正SetTimeout和SetInterval的this指向。还拿 壹.2.3.4.1 的代码演示:new
操作符时被调用的函数。它们并不会属于某个类,也不会实例化一个类。实际上,它们甚至都不能算是一种特殊的类型(class),它们只是被new
操作符调用的普通函数而已。new
来调用函数,或者说发生构造函数调用时,会自动执行下面的操作:this
就指向了这个新对象);this
的指向判断,可以按照下面的优先级顺序来判断函数在某个调用位置应用的是哪条规则new
中被调用(new
操作符指向)?this
绑定的是新创建的对象。call
、apply
、bind
显式指向?this
指向的是call、apply、bind三个方法的第一个参数指定的对象。this
指向的是这个对象。undefined
,否则绑定到全局对象。null
或者undefined
作为this
指向的对象传入call
、apply
或者bind
,这些值在调用时会被忽略,实际应用的是默认指向规则。function
关键字定义的,而是使用被称为“胖箭头”的操作符 =>
定义的。this
的四种指向规则,而是根据函数定义时的作用域来决定 this
的指向。何谓“定义时的作用域”?就是你定义这个箭头函数的时候,该箭头函数在哪个函数里,那么箭头函数体内的this就是它父函数的this。