---
description: 🚧 under construction
---

# this

[JS](../..) ⟩ [execution context]() ⟩ [lexical environment](lexical-environment) ⟩ [environment record](lexical-environment/environment-record) ⟩  "this"&#x20;

{% hint style="success" %}
<mark style="color:yellow;">**(**</mark>[primary](../../grammar/statement/expr/primary "mention")<mark style="color:yellow;">**)**</mark>

Within the <mark style="color:yellow;">**body**</mark> of a [method](../../val/obj/method "mention"), "<mark style="color:purple;">**this**</mark>" <mark style="color:yellow;">**evaluates**</mark> to the [obj](../../val/obj "mention") <mark style="color:yellow;">**on which**</mark> the method was <mark style="color:yellow;">**invoked.**</mark>

* <mark style="color:yellow;">**property**</mark> of an [](<> "mention").
* the **object** “<mark style="color:yellow;">**before dot**</mark>” (the **one** who <mark style="color:yellow;">**calls**</mark> the method).
* [this-determined-on-call-site](this/this-determined-on-call-site "mention") <mark style="color:yellow;">**(**</mark>[runtime](../../compile/runtime "mention")<mark style="color:yellow;">**)**</mark>, \
  <mark style="color:red;">**not by**</mark>**&#x20;**<mark style="color:yellow;">**function declaration (**</mark>[compile-time](../../compile/compile-time "mention")<mark style="color:yellow;">**)**</mark>.
* but there are <mark style="color:red;">**exceptions**</mark>,  👉 see：arrow function [arrow-function-as-class-field](../../val/func/arrow/arrow-function-as-class-field "mention")
{% endhint %}

{% tabs %}
{% tab title="⭐️ 重點" %}
{% hint style="warning" %}
<mark style="color:purple;">**this**</mark>&#x20;

* is <mark style="color:red;">**not**</mark>**&#x20;**<mark style="color:yellow;">**fixed**</mark> in a [method](../../val/obj/method "mention").&#x20;
* <mark style="color:yellow;">**does**</mark>**&#x20;**<mark style="color:red;">**not**</mark>**&#x20;**<mark style="color:yellow;">**necessarily refer**</mark> to the [obj](../../val/obj "mention") containing the [method](../../val/obj/method "mention").
* is <mark style="color:yellow;">**passed**</mark> (at [runtime](../../compile/runtime "mention")) by the <mark style="color:yellow;">**function call**</mark>.  👉 [method binding](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#method_binding).
{% endhint %}

{% hint style="info" %}
The <mark style="color:yellow;">**value**</mark> of <mark style="color:purple;">**this**</mark> in a <mark style="color:yellow;">**normal**</mark> [func](../../val/func "mention") is by default：

* [undefined](../../val/prim/undefined "mention") | [object](../../scope/global/object "mention")
{% endhint %}

{% hint style="danger" %}
[arrow](../../val/func/arrow "mention")s <mark style="color:red;">**don’t have**</mark> “<mark style="color:yellow;">**own**</mark>” <mark style="color:purple;">**this**</mark>, it’s taken from the "<mark style="color:yellow;">**outer context**</mark>" .
{% endhint %}

{% hint style="warning" %}
the <mark style="color:yellow;">**body**</mark> of a [class](../../val/class "mention") has a <mark style="color:purple;">**this**</mark> <mark style="color:yellow;">**context**</mark>.

👉 see [arrow](../../val/func/arrow "mention") ⟩ [arrow-function-as-class-field](../../val/func/arrow/arrow-function-as-class-field "mention").
{% endhint %}

{% hint style="danger" %}
if the <mark style="color:yellow;">**code**</mark> you need to <mark style="color:yellow;">**wrap**</mark> a [scope](../../scope "mention") <mark style="color:yellow;">**around**</mark> has [return](../../grammar/statement/flow/jump/return "mention"), [this](this "mention"), [break](../../grammar/statement/flow/jump/break "mention"), or [continue](../../grammar/statement/flow/jump/continue "mention") in it, <mark style="color:red;">**don't**</mark>**&#x20;**<mark style="color:yellow;">**use**</mark> a [func](../../val/func "mention")/[iife](../../val/func/expr/iife "mention")(which has <mark style="color:yellow;">**its own**</mark> [boundary](../../val/func/boundary "mention")), use a [block](../../grammar/statement/other/block "mention") instead❗️

📗 [You Don't Know JS Yet: Scopes & Closrues](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/ch6.md#function-boundaries)
{% endhint %}

{% hint style="info" %}
the value of [this](this "mention") is stored in [environment-record](lexical-environment/environment-record "mention").
{% endhint %}
{% endtab %}

{% tab title="🔴 主題" %}
* <mark style="color:yellow;">**value**</mark> of [this-determined-on-call-site](this/this-determined-on-call-site "mention")
* [environment-record](lexical-environment/environment-record "mention") - where the value of "this" is stored.
* [this](../../../browser/event/handler/this "mention") - the element which has the handler on it.
* a [class](../../val/class "mention")'s <mark style="color:yellow;">**body**</mark> has its <mark style="color:purple;">**this**</mark> <mark style="color:yellow;">**context**</mark>. ( 👉 arrow function [arrow-function-as-class-field](../../val/func/arrow/arrow-function-as-class-field "mention"))
* [arrow](../../val/func/arrow "mention") <mark style="color:red;">**has no own**</mark> <mark style="color:purple;">**this**</mark>：
  * arrow functions used [as-argument](../../val/func/arrow/as-argument "mention")&#x20;
  * arrow functions used [as-method](../../val/func/arrow/as-method "mention")
{% endtab %}

{% tab title="🧨 雷區" %}
{% hint style="danger" %}
Once a <mark style="color:yellow;">**method**</mark> is <mark style="color:red;">**passed somewhere separately**</mark> from the object – "<mark style="color:purple;">**this**</mark>" is <mark style="color:red;">**lost**</mark>.

```javascript
const user = {
  name: "John",
  sayHi() { console.log(`Hi, ${this.name}!`) }
};

//         ╭────────╮ <---- passed method
setTimeout(user.sayHi, 1000);   // Hello, undefined! 🧨
```
{% endhint %}
{% endtab %}

{% tab title="💈範例" %}
:floppy\_disk: replit：[this determined on call site](https://replit.com/@pegasusroe/this-determined-on-call-site#index.js)

```javascript
// object
let user = {

    name: "Joe",

    sayHi() {
        
        console.log(`Hi, I am ${this.name}.`);
        //                      ╰──╯  
        //                        ↳ ⭐️ value of `this` is NOT determined here.
        
        console.log(`... (sayHi() called by ${this})`)
    }
};

// ❗assign a new name
let f = user.sayHi;    // ⭐️ the function is NOT invoked here❗

// ⭐️ call site #1
user.sayHi();          // ⭐️ this === user (object before "dot")

// Hi, I am Joe.
// ... (sayHi() called by [object Object])

// ⭐️ call site #2
f();                   // ❗this      = `globalObject` or `undefined` ❗
                       // ❗this.name = `undefined`    or ⛔ TypeError❗

// ❗Hi, I am undefined.
// ❗... (sayHi() called by [object global])
```
{% endtab %}

{% tab title="📗 參考" %}
* [ ] [javascript-the-definitive-guide](../../../master/ref/javascript-the-definitive-guide "mention") ⟩&#x20;
  * [ ] 4.5, 8, 8.2.2, 9
* [ ] JS.info ⟩&#x20;
  * [x] ["this" in methods](https://javascript.info/object-methods#this-in-methods)
  * [ ] [Function binding](https://javascript.info/bind)
* [ ] itHome ⟩ [你不可不知的 JavaScript 二三事](https://ithelp.ithome.com.tw/users/20112483/ironman/2016) ⟩&#x20;
  * [ ] [#Day15：this 關鍵字 (1)](https://ithelp.ithome.com.tw/articles/10206700)
  * [ ] [#Day16：this 關鍵字 (2)](https://ithelp.ithome.com.tw/articles/10206841)
  * [ ] [#Day17：this 關鍵字 (3)](https://ithelp.ithome.com.tw/articles/10207207)
  * [ ] [#Day18：this 關鍵字 (4)](https://ithelp.ithome.com.tw/articles/10207343)
{% endtab %}

{% tab title="📘 手冊" %}
* [ ] [this](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)
* [ ] Function.prototype ⟩&#x20;
  * [.bind()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) - bind "<mark style="color:purple;">**this**</mark>" context and return a <mark style="color:yellow;">**new function**</mark>.
  * [.call()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call) - call a function with "<mark style="color:purple;">**this**</mark>" context and <mark style="color:orange;">**indivisual**</mark>**&#x20;**<mark style="color:yellow;">**arguments**</mark>.
  * [.apply()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply) - call a functin with "<mark style="color:purple;">**this**</mark>" context and <mark style="color:yellow;">**arguments**</mark>**&#x20;**<mark style="color:orange;">**array**</mark>.
{% endtab %}

{% tab title="🗣 討論" %}
* [Meaning of "this" in node.js modules and functions](https://stackoverflow.com/questions/22770299/meaning-of-this-in-node-js-modules-and-functions/22771432#22771432)
{% endtab %}

{% tab title="❓" %}
{% hint style="warning" %}
問：「如何利用 [Object.defineProperty()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty) 定義一個<mark style="color:yellow;">**新的屬性**</mark>，它的值是一個<mark style="color:yellow;">**物件**</mark>、具有<mark style="color:yellow;">**物件方法**</mark>，然後<mark style="color:yellow;">**在此方法內**</mark><mark style="color:red;">**參照原物件**</mark>(要定義新屬性的物件)」❓
{% endhint %}
{% endtab %}
{% endtabs %}
