在JavaScript中,this 的概念比较复杂。除了在面向对象编程中,this 还是随处可用的。这篇文章介绍了this 的工作原理,它会造成什么样的问题以及this 的相关例子。 要根据this 所在的位置来理解它,情况大概可以分为3种:
- 在函数中:this 通常是一个隐含的参数。
- 在函数外(顶级作用域中):在浏览器中this 指的是全局对象;在Node.js中指的是模块(module)的导出(exports)。
- 传递到eval()中的字符串:如果eval()是被直接调用的,this 指的是当前对象;如果eval()是被间接调用的,this 就是指全局对象。
对这几个分类,我们做了相应的测试:
- 在函数中的this
函数基本可以代表JS中所有可被调用的结构,所以这是也最常见的使用this 的场景,而函数又能被子分为下列三种角色:- 实函数
- 构造器
- 方法
1.1 在实函数中的this
在实函数中,this 的值是取决于它所处的上下文的模式。
- Sloppy模式:this 指的是全局对象(在浏览器中就是window)。
1234function sloppyFunc() {console.log(this === window); // true}sloppyFunc(); - Strict模式:this 的值是undefined。
12345function strictFunc() {'use strict';console.log(this === undefined); // true}strictFunc();
this 是函数的隐含参数,所以它的值总是相同的。不过你是可以通过使用call()或者apply()的方法显示地定义好this的值的。
1234567function func(arg1, arg2) {console.log(this); // 1console.log(arg1); // 2console.log(arg2); // 3}func.call(1, 2, 3); // (this, arg1, arg2)func.apply(1, [2, 3]); // (this, arrayWithArgs)
1.2 构造器中的this你可以通过new 将一个函数当做一个构造器来使用。new 操作创建了一个新的对象,并将这个对象通过this 传入构造器中。
123456var savedThis;function Constr() {savedThis = this;}var inst = new Constr();console.log(savedThis === inst); // trueJS中new 操作的实现原理大概如下面的代码所示(更准确的实现请看这里,这个实现也比较复杂一些):
12345function newOperator(Constr, arrayWithArgs) {var thisValue = Object.create(Constr.prototype);Constr.apply(thisValue, arrayWithArgs);return thisValue;}1.3 方法中的this
在方法中this 的用法更倾向于传统的面向对象语言:this 指向的接收方,也就是包含有这个方法的对象。
123456var obj = {method: function () {console.log(this === obj); // true}}obj.method();
- 作用域中的this
在浏览器中,作用域就是全局作用域,this 指的就是这个全局对象(就像window):1t;/script>1Ԩ的。这篇文章介绍了this 的工作原理,它会造成什么样的问题以及this 的相关例子。 要根据this 所在的位置来理解它,情况大概可以分为3种:- 在函数中:this 通常是一个隐含的参数。
- 在函数外(顶级作用域中):在浏览器中this 指的是全局对象;在Node.js中指的是模块(module)的导出(exports)。
- 传递到eval()中的字符串:如果eval()是被直接调用的,this 指的是当前对象;如果eval()是被间接调用的,this 就是指全局对象。
对这几个分类,我们做了相应的测试:
- 在函数中的this
函数基本可以代表JS中所有可被调用的结构,所以这是也最常见的使用this 的场景,而函数又能被子分为下列三种角色:- 实函数
- 构造器
- 方法
1.1 在实函数中的this
在实函数中,this 的值是取决于它所处的上下文的模式。
- Sloppy模式:this 指的是全局对象(在浏览器中就是window)。
1234function sloppyFunc() {console.log(this === window); // true}sloppyFunc(); - Strict模式:this 的值是undefined。
12345function strictFunc() {'use strict';console.log(this === undefined); // true}strictFunc();
this 是函数的隐含参数,所以它的值总是相同的。不过你是可以通过使用call()或者apply()的方法显示地定义好this的值的。
1234567function func(arg1, arg2) {console.log(this); // 1console.log(arg1); // 2console.log(arg2); // 3}func.call(1, 2, 3); // (this, arg1, arg2)func.apply(1, [2, 3]); // (this, arrayWithArgs)
1.2 构造器中的this你可以通过new 将一个函数当做一个构造器来使用。new 操作创建了一个新的对象,并将这个对象通过this 传入构造器中。
123456var savedThis;function Constr() {savedThis = this;}var inst = new Constr();console.log(savedThis === inst); // trueJS中new 操作的实现原理大概如下面的代码所示(更准确的实现请看这里,这个实现也比较复杂一些):
12345function newOperator(Constr, arrayWithArgs) {var thisValue = Object.create(Constr.prototype);Constr.apply(thisValue, arrayWithArgs);return thisValue;}1.3 方法中的this
在方法中this 的用法更倾向于传统的面向对象语言:this 指向的接收方,也就是包含有这个方法的对象。
123456var obj = {method: function () {console.log(this === obj); // true}}obj.method();
- 作用域中的this
在浏览器中,作用域就是全局作用域,this 指的就是这个全局对象(就像window):
- 在函数中:this 通常是一个隐含的参数。