此关键字

关键字 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 中,globalThisglobal 对象:

$ 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 设置 nullundefined 值 将替换为对全局对象的引用。您有时可能会看到 全局绑定,也称为“默认绑定”

隐式绑定

当一个函数作为对象的方法进行调用时, 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 的值 环境,这是包含该箭头函数的方法。由于 myEnclosingMethodthis 的值引用 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 的实例 传递给使用标识符(如 thatself_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 的值设置为 undefinednull,该值在 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 值不会以任何方式强制转换为对象, 即使它是基元、nullundefined 值,也是如此:

"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 再次由最接近的包含执行上下文提供。顶部 级别,这意味着事件处理脚本回调函数中的 thisglobalThis(在严格模式下为 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 对象