> For the complete documentation index, see [llms.txt](https://blog.yuyy.tech/mian-shi-shu-li/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://blog.yuyy.tech/mian-shi-shu-li/qian-duan-ji-chu/javascript/es/han-shu/this.md).

# this

## 一、为什么要有this <a href="#e4-b8-80-e4-b8-ba-e4-bb-80-e4-b9-88-e8-a6-81-e6-9c-89this" id="e4-b8-80-e4-b8-ba-e4-bb-80-e4-b9-88-e8-a6-81-e6-9c-89this"></a>

#### 原因1：不用每次都传上下文（context）

有this的情况：

```javascript
function uppercaseName() {
    return this.name.toUpperCase();
}

function sayHi() {
    console.log(`Hello, I am ${uppercaseName.call(this)}, and ${this.age} years old.`);
}

let Tom = {
    name: 'tom',
    age: 8
};

let Jerry = {
    name: 'jerry',
    age: 9
};

sayHi.call(Tom);
sayHi.call(Jerry);
```

没有this的情况：

```javascript
function uppercaseName(that) {
    return that.name.toUpperCase();
}

function sayHi(that) {
    console.log(`Hello, I am ${uppercaseName(that)}, and ${that.age} years old.`);
}

let Tom = {
    name: 'tom',
    age: 8
};

let Jerry = {
    name: 'jerry',
    age: 9
};

sayHi(Tom);
sayHi(Jerry);
```

#### 原因2：没有this，class无法实现

```javascript
class Person {
    constructor(name, age){
        this.name = name;
        this.age = age;
    }

    uppercaseName() {
        return this.name.toUpperCase();
    }

    sayHi() {
        console.log(`Hello, I am ${this.uppercaseName()}, and ${this.age} years old.`);
    }
}
```

如果没有this，没办法将属性挂载到实例上，属性函数内部也无法相互调用

## 二、this指向谁 <a href="#e4-ba-8cthis-e8-af-af-e5-8c-ba" id="e4-ba-8cthis-e8-af-af-e5-8c-ba"></a>

this一般出现在函数中，this的指向取决于函数执行场景，一般分为4个场景：

#### 1、默认：<mark style="color:green;">this -> 全局变量(非严格模式)/上下文</mark>

```
var name = 'Tom';

function sayName() {
    console.log(`Hi, I am ${this.name}!`);
}

//this隐式指向全局
sayName(); //严格模式指向undefined，非严格模式下正常
```

输出：

浏览器：

> Hi, I am Tom!

node.js：

> <mark style="color:red;">TypeError: Cannot read properties of undefined (reading 'name')</mark>

全局中this的指向：

* 浏览器：this -> window
* node.js：this -> undefined

#### 2、隐式：<mark style="color:green;">this -> 调用对象</mark>

```javascript
let Tom = {
  name: "Tom",
  sayName: function () {
    console.log(`Hi, I am ${this.name}!`);
  },
};

Tom.sayName();

function sayHi() {
  console.log(`Hi, I am ${this.name}!`);
}
let Jerry = {
  name: "Jerry",
  sayName: Tom.sayName,
  sayHi: sayHi,
};

Jerry.sayName(); //this隐式指向Jerry
Jerry.sayHi();
```

输出：

> Hi, I am Tom!&#x20;
>
> Hi, I am Jerry!&#x20;
>
> Hi, I am Jerry!

#### 3、显式：<mark style="color:green;">this -> 指定对象</mark>

```javascript
let Tom = {
  name: "Tom",
  sayName: function () {
    console.log(`Hi, I am ${this.name}!`);
  },
  sayTitle(...titles) {
    this.sayName();
    console.log(`my title: ${[...titles].join("、")}`);
  },
};

Tom.sayName();
Tom.sayTitle("developer");

let Jerry = {
  name: "Jerry",
  sayName: function () {
    console.log(`Hi, I am ${this.name}!`);
  },
};
let Jack = {
  name: "Jack",
};

//this显式指向Jery
Tom.sayTitle.apply(Jerry, ["developer", "programmer", "engineer"]);
Tom.sayTitle.apply(Jack, ["developer", "programmer", "engineer"]);
```

输出：

> Hi, I am Tom!&#x20;
>
> Hi, I am Tom!&#x20;
>
> my title: developer&#x20;
>
> Hi, I am Jerry!&#x20;
>
> my title: developer、programmer、engineer
>
> <mark style="color:red;">TypeError: this.sayName is not a function</mark>

#### 4、new：<mark style="color:green;">this -> 新对象</mark>

new实例化时经典4步中的第3步

```javascript
function Person(name) {
    this.name = name;
    this.sayName = function () {
        console.log(`Hi, I am ${this.name}!`);
    }
}

//this显式指向Person的实例
let Tom = new Person('Tom');
Tom.sayName();

let Jerry = new Person('Jerry');
Jerry.sayName();
```

## 三、破解this的困局

函数的调用方式决定了 `this` 的值（运行时绑定），`this` 不能在执行期间被赋值，并且在每次函数被调用时 `this` 的值也可能会不同：

* ES5 引入了 [bind](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) 方法来设置函数的 `this` 值，而不用考虑函数如何被调用的。
* ES6 引入了[箭头函数](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions)，箭头函数不提供自身的 this 绑定（`this` 的值将保持为闭合词法上下文的值）。

参考：

* <https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/this>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://blog.yuyy.tech/mian-shi-shu-li/qian-duan-ji-chu/javascript/es/han-shu/this.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
