JavaScript中this关键词的使用技巧、工作原理以及注

要根据this 所在的位置来理解它,情况大概可以分为3种:

  1、在函数中:this 通常是一个隐含的参数。

  2、在函数外(顶级作用域中):在浏览器中this 指的是全局对象;在Node.js中指的是模块(module)的导出(exports)。

  3、传递到eval()中的字符串:如果eval()是被直接调用的,this 指的是当前对象;如果eval()是被间接调用的,this 就是指全局对象。

  对这几个分类,我们做了相应的测试:
  1、在函数中的this

  函数基本可以代表JS中所有可被调用的结构,所以这是也最常见的使用this 的场景,而函数又能被子分为下列三种角色:

实函数
    构造器
    方法

  1.1  在实函数中的this

  在实函数中,this 的值是取决于它所处的上下文的模式。

  Sloppy模式:this 指的是全局对象(在浏览器中就是window)。

复制代码 代码如下:


function sloppyFunc() {
    console.log(this === window); // true
}
sloppyFunc();

Strict模式:this 的值是undefined。

复制代码 代码如下:


function strictFunc() {
    'use strict';
    console.log(this === undefined); // true
}
strictFunc();

this 是函数的隐含参数,所以它的值总是相同的。不过你是可以通过使用call()或者apply()的方法显示地定义好this的值的。

复制代码 代码如下:


function func(arg1, arg2) {
    console.log(this); // 1
    console.log(arg1); // 2
    console.log(arg2); // 3
}
func.call(1, 2, 3); // (this, arg1, arg2)
func.apply(1, [2, 3]); // (this, arrayWithArgs)

1.2  构造器中的this

  你可以通过new 将一个函数当做一个构造器来使用。new 操作创建了一个新的对象,并将这个对象通过this 传入构造器中。

复制代码 代码如下:


var savedThis;
function Constr() {
    savedThis = this;
}
var inst = new Constr();
console.log(savedThis === inst); // true

JS中new 操作的实现原理大概如下面的代码所示(更准确的实现请看这里,这个实现也比较复杂一些):

复制代码 代码如下:


function newOperator(Constr, arrayWithArgs) {
    var thisValue = Object.create(Constr.prototype);
    Constr.apply(thisValue, arrayWithArgs);
    return thisValue;
}

1.3  方法中的this

  在方法中this 的用法更倾向于传统的面向对象语言:this 指向的接收方,也就是包含有这个方法的对象。

复制代码 代码如下:


var obj = {
    method: function () {
        console.log(this === obj); // true
    }
}
obj.method();

2、作用域中的this

  在浏览器中,作用域就是全局作用域,this 指的就是这个全局对象(就像window):

复制代码 代码如下:


<script>
    console.log(this === window); // true
</script>

在Node.js中,你通常都是在module中执行函数的。因此,顶级作用域是个很特别的模块作用域(module scope):

复制代码 代码如下:


// `global` (not `window`) refers to global object:
console.log(Math === global.Math); // true

// `this` doesn't refer to the global object:
console.log(this !== global); // true
// `this` refers to a module's exports:
console.log(this === module.exports); // true

3、eval()中的this

  eval()可以被直接(通过调用这个函数名'eval')或者间接(通过别的方式调用,比如call())地调用。要了解更多细节,请看这里。

复制代码 代码如下:


// Real functions
function sloppyFunc() {
    console.log(eval('this') === window); // true
}
sloppyFunc();

function strictFunc() {
    'use strict';
    console.log(eval('this') === undefined); // true
}
strictFunc();

// Constructors
var savedThis;
function Constr() {
    savedThis = eval('this');
}
var inst = new Constr();
console.log(savedThis === inst); // true

// Methods
var obj = {
    method: function () {
        console.log(eval('this') === obj); // true
    }
}
obj.method();

 4、与this有关的陷阱

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgpfsw.html