this 这 this那,this我想 diss你,给我整懵圈了都。最近写代码的时候老用到 this,就自己研究了一下它的各种运用场景,才知道都叫 this能有这么多差别,光 this指向就分五种判断方式,不过关于 this的知识点也都在这五种判定方法里面了。
前言
在JavaScript中,我们使用this的场景大部分都是简单的函数调用,但有部分人也许连为什么要在这添加this.都不知道,它的目的其实就是确保函数内部的this引用能够正确地指向预期的对象,这样说也许有些抽象,此文会详细带你了解这个十分常用而又容易让人忽略的this。
一、this的几种应用场景
1.对象方法中的 this
:
js
const person = {
name: 'Alice',
sayHello: function() {
console.log(`Hello, my name is ${this.name}`);
}
};
person.sayHello(); // 输出:Hello, my name is Alice
2.构造函数中的 this
:
js
function Person(name) {
this.name = name;
}
const apple = new Person('Apple');
console.log(apple.name); // 输出:Apple
3.箭头函数中的 this
:
js
const person = {
name: 'Alice',
sayHello: () => {
console.log(`Hello, my name is ${this.name}`);
}
};
person.sayHello(); // 输出:Hello, my name is undefined (全局作用域的 `this`)
二、this的指向
这就得拿出this的绑定规则了,用来解释上面几个例子。
核心:
this
的具体值取决于函数的调用方式
绑定规则:
- 全局作用域中的
this
:在全局作用域中,this
通常指向全局对象(在浏览器中是window
,在 Node.js 中是global
)。
- 函数调用中的
this
:当函数作为普通函数调用时,this
的值取决于函数执行的环境。在非严格模式下,this
通常指向全局对象;在严格模式下(使用'use strict';
),this
的值为undefined
。
js
// 非严格模式下:
function greet() {
console.log(this === global); // 输出:true
console.log(this); // 输出:Object [global]{...}
}
greet();
js
// 严格模式下:
'use strict'
function greet() {
console.log(this === global); // 输出:false
console.log(this); // 输出:undefined
}
greet();
- 对象方法调用中的
this
:当函数作为对象的方法被调用时,this
的值为该对象。(应用场景中的第一个例子) - 构造函数调用中的
this
:使用new
关键字调用构造函数时,this
指向新创建的对象实例。(应用场景中的第二个例子) - 箭头函数中的
this
:- 箭头函数没有自己的this
,它捕获其外围最近的非箭头函数作用域的this
值。如果箭头函数在全局作用域中,this
将指向全局对象。(应用场景中的第三个例子)
三、改变this的值
我们可以使用.call()
, .apply()
, 或 .bind()
方法来显式地改变函数调用中的 this
值。
js
var obj = {
a:1
}
function foo() {
console.log(this.a);
}
foo.call(obj) // 输出:1
call的实现原理:先拿到foo,然后将foo引用到obj上,让obj触发foo,最后移除掉obj身上的foo。
结语
如果你了解了this的各种绑定规则,掌握每一个方法中的this指向,就能够轻松地应付它的每一个使用场景了,同时也可以让你在函数里各种变量的拷贝中游刃有余。