关键字 this
是指绑定到
调用该函数时,也就意味着,它的值会因
一个函数是作为方法调用、作为独立函数调用,还是作为
构造函数。
调用函数时,该函数会在调用后创建一个关键字 this
的实例,
场景作为对包含该函数的对象的引用,为
在其作用域内访问与其一起定义的属性和方法。
在某些方面,使用 this
与使用声明的变量类似
和const
。与常量一样,this
也无法移除,其值也无法移除
但 this
关键字指定的对象的方法和属性
包含可以进行更改。
全局绑定
在函数或对象的上下文之外,this
是指
globalThis
属性,该属性是对大多数
JavaScript 环境。对于在网络浏览器中运行的脚本,
全局对象是 window
对象:
this;
> Window {0: Window, window: Window, self: Window, document: document, name: '', location: Location, ...}
在 Node.js 中,globalThis
是 global
对象:
$ node
Welcome to Node.js v20.10.0.
Type ".help" for more information.
> this
<ref *1> Object [global] {
...
}
在严格模式之外,this
还会引用独立文件内的
函数,因为父 Window
实际上是“拥有”的对象
这些函数。
function myFunction() {
console.log( this );
}
myFunction();
> Window {...}
(function() {
console.log( this );
}());
> Window {...}
使用严格模式时,this
在独立脚本中的值为 undefined
函数:
(function() {
"use strict";
console.log( this );
}());
> undefined
在引入严格模式之前,为 this
设置 null
或 undefined
值
将替换为对全局对象的引用。您有时可能会看到
全局绑定,也称为“默认绑定”
隐式绑定
当一个函数作为对象的方法进行调用时, this
内的
该方法引用了包含该方法的对象,从而提供对
方法和属性:
let myObject = {
myValue: "This is my string.",
myMethod() {
console.log( this.myValue );
}
};
myObject.myMethod();
> "This is my string."
this
的值可能取决于函数及其
封装对象定义。相反,this
值的上下文是
当前 execution 上下文。在此示例中,执行上下文是
myObject
对象正在调用 myMethod
方法,因此 myObject
是值
价格为 this
。就上一案例而言,这可能是一项技术性要求。
但对于 this
的更高级用途,
。
通常,应以不希望周围代码的形式使用 this
任何特定结构。此规则的例外情况是 ES5
箭头函数。
箭头函数中的 this
在箭头函数中,
this
解析为
包含词汇的环境。这意味着
this
箭头函数中的 this
是指该函数
包含最接近的上下文:
let myObject = {
myMethod() { console.log( this ); },
myArrowFunction: () => console.log( this ),
myEnclosingMethod: function () {
this.myArrowFunction = () => { console.log(this) };
}
};
myObject.myMethod();
> Object { myMethod: myMethod(), myArrowFunction: myArrowFunction() }
myObject.myArrowFunction();
> Window {...}
在前面的示例中,myObject.myMethod()
将 myObject
记录为对象
“拥有”该方法,但 myObject.myArrowFunction()
会返回 globalThis
(或 undefined
),因为箭头函数内 this
的实例
是指最高封闭范围。
在以下示例中,myEnclosingMethod
在
对象。this
实例在
箭头函数现在引用封装内 this
的值
环境,这是包含该箭头函数的方法。由于
myEnclosingMethod
内 this
的值引用 myObject
,
定义箭头函数,箭头函数内的 this
还指代
myObject
:
let myObject = {
myMethod() { console.log( this ); },
myEnclosingMethod: function () {
this.myArrowFunction = () => { console.log(this) };
}
};
myObject.myEnclosingMethod();
myObject.myArrowFunction();
> Object { myMethod: myMethod(), myArrowFunction: myArrowFunction() }
显式绑定
隐式绑定可处理与 this
相关的大多数用例。不过,您
有时可能需要使用 this
的值来表示特定的执行
上下文,而不是假设的上下文。如果稍微有些过时
示例是在 setTimeout
的回调函数中使用 this
,
因为此回调具有唯一的执行上下文:
var myObject = {
myString: "This is my string.",
myMethod() {
console.log( this.myString );
}
};
myObject.myMethod();
> "This is my string."
setTimeout( myObject.myMethod, 100 );
> undefined
尽管后来修复了 setTimeout
的这一特定缺点
其他功能、“丢失”等类似问题this
之前已得到解决
方法是在this
预期上下文。您可能偶尔会看到已分配 this
的实例
传递给使用标识符(如 that
、self
或 _this
)的变量
代码库。这些是包含
传递的 this
值。
当您使用 call()
、bind()
或 apply()
方法调用函数时,
this
会明确引用正在调用的对象:
let myFunction = function() {
console.log( this.myValue );
}
let myObject = {
"myValue" : "This is my string."
};
myFunction.call( myObject );
> "This is my string."
var myObject = {
myString: "This is my string.",
myMethod() {
console.log( this.myString );
}
};
setTimeout( myObject.myMethod.bind( myObject ), 100 );
> "This is my string."
显式绑定会替换隐式绑定提供的 this
值。
let myObject = {
"myValue" : "This string sits alongside myMethod.",
myMethod() {
console.log( this.myValue );
}
};
let myOtherObject = {
"myValue" : "This is a string in another object entirely.",
};
myObject.myMethod.call( myOtherObject );
> "This is a string in another object entirely."
如果调用函数的方式会将 this
的值设置为
undefined
或 null
,该值在 strict 之外会替换为 globalThis
模式:
let myFunction = function() {
console.log( this );
}
myFunction.call( null );
> Window {...}
同样,如果以为 this
赋予基元的方式调用函数
值将替换为
原始值的封装容器对象
非严格模式:
let myFunction = function() {
console.log( this );
}
let myNumber = 10;
myFunction.call( myNumber );
> Number { 10 }
在严格模式下,传递的 this
值不会以任何方式强制转换为对象,
即使它是基元、null
或 undefined
值,也是如此:
"use strict";
let myFunction = function() {
console.log( this );
}
let myNumber = 10;
myFunction.call( myNumber );
> 10
myFunction.call( null );
> null
new
绑定
将类用作构造函数且使用
new
关键字,this
是指新创建的实例:
class MyClass {
myString;
constructor() {
this.myString = "My string.";
}
logThis() {
console.log( this );
}
}
const thisClass = new MyClass();
thisClass.logThis();
> Object { myString: "My string." }
同样,使用 new
调用的构造函数内 this
的值
是指正在创建的对象:
function MyFunction() {
this.myString = "My string.";
this.logThis = function() {
console.log( this );
}
}
const myObject = new MyFunction();
myObject.logThis();
> Object { myString: "My string.", logThis: logThis() }
事件处理脚本绑定
在事件处理脚本的上下文中,this
的值会引用
调用它。在事件处理脚本的回调函数内,这意味着 this
引用与处理程序相关联的元素:
let button = document.querySelector( "button" );
button.addEventListener( "click", function( event ) { console.log( this ); } );
当用户与上一个代码段中的 button
互动时,结果为
包含 <button>
本身的元素对象:
> Button {}
将箭头函数用作事件监听器回调时,
this
再次由最接近的包含执行上下文提供。顶部
级别,这意味着事件处理脚本回调函数中的 this
是
globalThis
(在严格模式下为 undefined
):
let button = document.querySelector( "button" );
button.addEventListener( "click", ( event ) => { console.log( this ); } );
> undefined
与任何其他对象一样,当您使用 call()
、bind()
或 apply()
时
用于引用事件监听器回调函数 this
的方法
显式引用该对象:
let button = document.querySelector( "button" );
let myObject = {
"myValue" : true
};
function handleClick() {
console.log( this );
}
button.addEventListener( "click", handleClick.bind( myObject ) );
> Object { myValue: true }
检查您的理解情况
对于在网络浏览器中运行的脚本,全局对象是什么
在函数或this
和对象上下文?
window
对象browser
对象undefined
对象