10. this
Last updated
Was this helpful?
Last updated
Was this helpful?
接着上一节讲的话,应该轮到“执行上下文栈”了,但是这里不得不插入一节,把this
说一下。因为this
很重要,js 的面试题如果不出几个与this
有关的,那出题者都不合格。
其实,this
的取值,分四种情况。我们来挨个看一下。
在此再强调一遍一个非常重要的知识点:在函数中this
到底取何值,是在函数真正被调用执行的时候确定的,函数定义的时候确定不了。因为this
的取值是执行上下文环境的一部分,每次调用函数,都会产生一个新的执行上下文环境。
所谓构造函数就是用来 new对象 的函数。其实严格来说,所有的函数都可以 new 一个对象,但是有些函数的定义是为了 new 一个对象,而有些函数则不是。另外注意,构造函数的函数名第一个字母大写(规则约定)。例如:Object、Array、Function
等。
以上代码中,如果函数作为构造函数用,那么其中的this
就代表它即将new
出来的对象。
注意,以上仅限 new Foo() 的情况,即 Foo函数 作为构造函数的情况。如果直接调用 Foo函数,而不是 new Foo(),情况就大不一样了。
这种情况下this
是window
,我们后文中会说到。
如果函数作为对象的一个属性时,并且作为对象的一个属性被调用时,函数中的this
指向该对象。
以上代码中,fn 不仅作为一个对象的一个属性,而且的确是作为对象的一个属性被调用。结果this
就是 obj对象。
注意,如果 fn函数 不作为 obj 的一个属性被调用,会是什么结果呢?
如上代码,如果 fn函数 被赋值到了另一个变量中,并没有作为 obj 的一个属性被调用,那么this
的值就是window
,this.x 为undefined
。
当一个函数被call
和apply
调用时,this
的值就取传入的对象的值。至于call
和apply
如何使用,不会的朋友可以去查查其他资料,本系列教程不做讲解。
在全局环境下,this
永远是window
,这个应该没有非议。
普通函数在调用时,其中的this
也都是window
。
以上代码很好理解。
不过下面的情况你需要注意一下:
函数f 虽然是在 obj.fn 内部定义的,但是它仍然是一个普通的函数,this
仍然指向window
。
完了。
看到了吧,this
有关的知识点还是挺多的,不仅多而且非常重要。
最后,既然提到了this
,有必要把一个非常经典的案例介绍给大家,又是jQuery
源码的。
以上代码是从jQuery
中摘除来的部分代码。jQuery.extend
和jQuery.fn.extend
都指向了同一个函数,但是当执行时,函数中的this
是不一样的。
执行jQuery.extend(…)
时,this
指向jQuery
;执行jQuery.fn.extend(…)
时,this
指向jQuery.fn
。
这样就巧妙的将一段代码同时共享给两个功能使用,更加符合设计原则。
上面说到this
的其中一种情况是构造函数的,在构造函数的prototype
中,this
代表着什么。
如上代码,在 Fn.prototype.getName 函数中,this
指向的是 f1对象。因此可以通过 this.name 获取 f1.name 的值。
其实,不仅仅是构造函数的prototype
,即便是在整个原型链中,this
代表的也都是当前对象的值。
好了,聊完了this
。接着上一节继续说“执行上下文栈”。