面向对象语言中 this 表示当前对象的一个引用。
但在 JavaScript 中 this 不是固定不变的,它会随着执行环境的改变而改变。(与其他语言相比,函数的 this
关键字在 JavaScript 中的表现略有不同,此外,在严格模式和非严格模式之间也会有一些差别。)
作用:
- 1.在方法中,this 表示该方法所属的对象。
- 2.如果单独使用,this 表示全局对象。
(单独使用 this,则它指向全局(Global)对象。
在浏览器中,window 就是该全局对象为 [object Window]:)
- 3.在函数中,this 表示全局对象。
- 4.在函数中,在严格模式下,this 是未定义的(undefined)。
- 5.在事件中,this 表示接收事件的元素。
- 6.类似 call() 和 apply() 方法可以将 this 引用到任何对象。
- 7.在箭头函数中,this的值由当前作用域中的外层函数确定(使用箭头函数定义的函数不会改变this的值,它会继承上层作用域中的this值。)
<script>
// 创建一个对象
var person = {
firstName: "John",
lastName : "Doe",
id : 5566,
fullName : function() {
return this.firstName + " " + this.lastName;
}
};
// 显示对象的数据
document.getElementById("demo").innerHTML = person.fullName();
</script>
实例中,this 指向了 person 对象。
因为 person 对象是 fullName 方法的所有者。
最后的结果: John Doe
例2:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h2>JavaScript <b>this</b> 关键字</h2>
<p>在实例中,<b>this</b> 指向了 fullName 方法所属的对象 person。</p>
<p id="demo"></p>
<script>
var person = {
firstName : "John",
lastName : "Doe",
id : 5566,
myFunction : function() {
return this;
}
};
document.getElementById("demo").innerHTML = person.myFunction();
</script>
</body>
</html>
结果:
特点:
1:this永远指向一个对象;
2:this的指向完全取决于函数调用的位置;
3:
- 默认绑定
- 隐式绑定(上下文绑定)
- 显式绑定
- new 绑定
针对以上的第一点特别好理解,不管在什么地方使用this,它必然会指向某个对象;确定了第一点后,也引出了一个问题,就是this使用的地方到底在哪里,而第二点就解释了这个问题,但关键是在JavaScript语言之中,一切皆对象,运行环境也是对象,所以函数都是在某个对象下运行,而this就是函数运行时所在的对象(环境)。这本来并不会让我们糊涂,但是JavaScript支持运行环境动态切换,也就是说,this的指向是动态的,很难事先确定到底指向哪个对象,这才是最让我们感到困惑的地方。
在函数内部,this
的值取决于函数如何被调用。可以将 this
看作是函数的一个隐藏参数(就像函数定义中声明的参数一样),this
是语言在函数体被执行时为你创建的绑定。
对于典型的函数,this
的值是函数被访问的对象。换句话说,如果函数调用的形式是 obj.f()
,那么 this
就指向 obj
。例如:
function getThis() {
return this;
}
const obj1 = { name: "obj1" };
const obj2 = { name: "obj2" };
obj1.getThis = getThis;
obj2.getThis = getThis;
console.log(obj1.getThis()); // { name: 'obj1', getThis: [Function: getThis] }
console.log(obj2.getThis()); // { name: 'obj2', getThis: [Function: getThis] }
注意,虽然函数是相同的,但是根据其调用的方式,this
的值是不同的。这与函数参数的工作方式类似。
this
的值不是拥有此函数作为自己属性的对象,而是用于调用此函数的对象。你可以通过调用对象在原型链中的方法来证明这一点。
this回调
当一个函数作为回调函数传递时,this
的值取决于如何调用回调,这由 API 的实现者决定。回调函数通常以 undefined
作为 this
的值被调用(直接调用,而不附加到任何对象上),这意味着如果函数是在非严格模式,this
的值会是全局对象(globalThis)。这在迭代数组方法、Promise() 构造函数等例子中都是适用的。
例如:
function logThis() {
"use strict";
console.log(this);
}
[1, 2, 3].forEach(logThis); // undefined、undefined、undefined
一些 API 允许你为回调函数的调用设置一个 this
值。例如,所有的迭代数组方法和相关的方法,如Set.prototype.forEach(),都接受一个可选的 thisArg
参数。
JSCopy to Clipboard
[1, 2, 3].forEach(logThis, { name: "obj" });
// { name: 'obj' }, { name: 'obj' }, { name: 'obj' }
偶尔,回调函数会以一个非 undefined
的 this
值被调用。例如,JSON.parse() 的 reviver
参数和 JSON.stringify() 的 replacer
参数都会把 this
设置为正在被解析/序列化的属性所属的对象。