1. 程式人生 > >javascript:this 關鍵字

javascript:this 關鍵字

前言

看過阮一峰的關於 this 的教程,講了很多比較好的例子,但沒有對其本質的東西解釋清楚,而且部分例證存在問題;於是,打算重寫本章節,從this的本質入手;

本文為作者的原創作品,轉載需註明出處;

本文轉載自筆者的私人部落格,傷神的部落格 http://www.shangyang.me/2017/03/24/javascript-lang-this/

References

Javascript中this關鍵字詳解
jQuery Fundamentals Chapter - The this keyword

this 是什麼?

this可以理解為一個指標,指向呼叫物件;

判斷 this 是什麼的四個法則

官網定義

先來看第一段官方的解釋,

In JavaScript, as in most object-oriented programming languages, this is a special keyword that is used within methods to refer to the object on which a method is being invoked. The value of this is determined using a simple series of steps:

  1. If the function is invoked using Function.call
     or Function.apply, this will be set to the first argument passed to call/apply. If the first argument passed to call/apply is null or undefined, this will refer to the global object (which is the window object in Web browsers).
  2. If the function being invoked was created using Function.bind
    , this will be the first argument that was passed to bind at the time the function was created.
  3. If the function is being invoked as a method of an object, this will refer to that object.
  4. Otherwise, the function is being invoked as a standalone function not attached to any object, and this will refer to the global object.

大致翻譯如下,
this是這麼一個特殊的關鍵字,它是用來指向一個當前正在被呼叫( a being invoked )方法的呼叫物件的;( 等等,這句話其實隱藏了一個非常關鍵的資訊,那就是this是在執行期 生效的,怎麼生效的?在執行期this被賦值,將某個物件賦值給this,與宣告期無關,也就是說,this是執行期相關的 );this的賦值場景,歸納起來,分為如下四種情況,

  1. 如果方法是被Function.call或者Function.apply呼叫執行…. bla..bla..
    參考 function prototype call 小節

  2. 如果是被Function.bind… bla…bla
    參考 function prototype bind 小節

  3. 如果某個方法在執行期是被一個物件( an object )呼叫( 備註:這裡為了便於理解,我針對這種情況,自己給起了個名稱叫關聯呼叫 ),在執行期,會將該 object 的引用賦值給該方法的this
    備註:被一個物件呼叫?何解?其實就是指語句obj.func(),這個時候,func()方法內部的this將會被賦值為obj物件的引用,也就是指向obj

  4. 如果該方法在執行期被當做一個沒有依附在任何 object 上的一個獨立方法被呼叫(is being invoked as a standalone function not attached to any object ),那麼該方法內部的this將會被賦值為全域性物件(在瀏覽器端就是 windows )
    獨立方法 ( standalone function )?在執行期,如果func方法被obj關聯呼叫的,既是通過obj.func()的方式,那麼它就不是standalone的;如果是直接被呼叫,沒有任何物件關聯,既是通過func()呼叫,那麼這就是standalone的。

this 執行期相關

官網定義 2

再來看另外一句非常精煉的描述,來加深理解

The this keyword is relative to the execution context, not the declaration context.

this關鍵字與執行環境有關而與宣告環境無關;(補充,而作用域鏈閉包是在函式的宣告期建立的,參考建立時機)

補充,是如何與函式的執行期相關的,參考this 指標執行時賦值

我的補充

法則 #3 和 #4,大多數情況都非常容易理解,有幾種情況需要特別注意,

  1. 函式巢狀
    需要注意的是object物件中的函式內部再次巢狀函式的情況,

    
           
            1
           
           
            2
           
           
            3
           
           
            4
           
           
            5
           
           
            6
           
           
            7
           
           
            8
           
           
            9
           
           
            10
           
           
            11
           
           
            12
           
           
            13
           
           
            14
           
           
            15
           
           
            16
           
           
            17
           
           
            18
           
    
           
            var name = 
            "windows"; 
           
            
           
           
            var obj = { 
           
           
            
            name:
            "object", 
           
           
            
            f1:
            function(){ 
           
           
            
            console.log(
            "this: "+
            this.name)
           
           
            
            function f2(){ 
           
           
            
            console.log(
            "this: " + 
            this.name)
           
           
             }
           
           
           
             f2(); 
           
           
             } 
           
           
            };
           

    執行

    
           
            1
           
           
            2
           
           
            3
           
    
           
            > obj.f1();
           
            
            this: object
           
            
            this: windows
           

    可以看到,在執行期,被呼叫函式 f1() 中的this指向 obj,而被呼叫函式 f2() 中的this指向的是 windows ( global object );因為 f1 函式在當前的執行時中是通過 obj.f1() 進行的關聯呼叫,所以,根據定義 #3,在當前的執行期間f1() 內部的 this 是指向 obj 物件的( 通過將 obj 的引用直接賦值給 this ),而, f2 函式在執行期是沒有與其它 object 進行關聯呼叫,所以,在當前的執行時期f2 是一個 standalone 的函式,所以,根據定義 #4,在當前的執行期間f2() 的內部this是指向 windows 的。(注意,這裡我反覆強調當前執行期間,是因為this是在執行時被賦值的,所以,要特別注意的是,即使某個函式的定義不變,但在不同的執行環境(執行環境)中,this是會發生變化;)

  2. 回撥函式
    參看函式回撥場景-1函式回撥場景-2

  3. 函式賦值
    參看將函式賦值-standalone以及相關變種章節

可見,要判斷this執行期到底指的是什麼,並沒有那麼容易,但是,只要牢牢的把握好兩點,就可以迎刃而解,

  • this執行期相關的
    更確切的說,this是在執行期被賦值的,所以,它的值是在執行期動態確定的。
  • this是否與其它物件關聯呼叫
    這裡的關聯呼叫指的是 javascript 的一種語法,既是呼叫語句顯式的寫為obj.func(),另外需要注意的是,javascript 方法的呼叫不會隱式的隱含 this。只要沒有顯式的關聯呼叫,那麼就是standalone的呼叫,就符合法則 #4,所以,this指向 Global Object

this 的 Object

注意,this定義中所指的Object指的是 javascript 的 Object 型別,既是通過


     
      1
     
     
      2
     
     
      3
     

     

相關推薦

javascriptthis 關鍵字

前言 看過阮一峰的關於 this 的教程,講了很多比較好的例子,但沒有對其本質的東西解釋清楚,而且部分例證存在問題;於是,打算重寫本章節,從this的本質入手; 本文為作者的原創作品,轉載需註明出處; 本文轉載自筆者的私人部落格,傷神的部落格 http://www

JavaScript OOP(二)this關鍵字以及call、apply、bind

col als == ole 構造 prototype logs rip .com JavaScript的this關鍵字非常靈活! this 返回的總是對象;即返回屬性或方法“當前”所在的對象 1 var o1={ 2 name:‘apple‘, 3

JavaScriptthis關鍵字的指向問題

asc 函數調用 javascrip new spa con oba cti func 1、純粹的函數調用,this就代表全局對象Global var x = 1; function test(){ var x = ‘二哈‘; console.log(th

對於JavaScriptthis關鍵字的理解

決定 博客 rip script 答案 搜索 http 環境 return   這是我第二遍學this了,第一遍學的懵懵的。this指哪裏都是憑我一個男人的直覺然後控制臺輸出看看對不對。   剛查了書、博客、視頻。理解差不多了。畢竟菜雞me; 一、首先介紹下什麽是this

Java學習筆記(十五)this關鍵字

bsp java image nbsp his this mage 學習筆記 筆記 Java學習筆記(十五):this關鍵字

JavaScriptthis關鍵字

JavaScript中this關鍵字用法較為靈活,用處較多,主要有以下幾種方式: 1.瀏覽器中,全域性的this指向window; console.log(this===window); console.log(this); this.a='nice'; console

深度解析JavaScriptthis關鍵字

摘要: 神奇的this。 原文:A deep dive into this in JavaScript: why it’s critical to writing good code. 譯文:深度解析JavaScript的this關鍵字 譯者:前端之巔 Fu

php 面向物件this 關鍵字

PHP5中為解決變數的命名衝突和不確定性問題,引入關鍵字“$this”代表其所在當前物件。 $this在建構函式中指該建構函式所建立的新物件。 在類中使用當前物件的屬性和方法,必須使用$this->取值。 方法內的區域性變數,不屬於物件,不使用$this關鍵字取值。 區域性變數和全域性變數與 $

php 面向對象this 關鍵字

func set 實例化 參數 避免 傳遞 析構函數 color 其它 PHP5中為解決變量的命名沖突和不確定性問題,引入關鍵字“$this”代表其所在當前對象。 $this在構造函數中指該構造函數所創建的新對象。 在類中使用當前對象的屬性和方法,必須使用$this->

“全棧2019”Java第四十章this關鍵字

難度 初級 學習時間 10分鐘 適合人群 零基礎 開發語言 Java 開發環境 JDK v11 IntelliJ IDEA v2018.3 文章原文連結 “全棧2019”Java第四十章:this關鍵字 下一章 “全棧2019”Java第四十一章:static關鍵字

Java之路this關鍵字的用法

(1)this代表當前物件的一個引用。所謂當前物件,指的是呼叫類中方法或屬性的那個物件。 最經常使用this關鍵字的情況,是在物件的一個屬性被方法或構造器的引數遮蔽時,需要呼叫這個被遮蔽的屬性,如下: class Person { private String

JavaScriptthis關鍵字原理

先來看一個例子: var obj = { foo: function () { console.log(this.bar) }, bar: 1 }; var foo = obj.foo; var bar = 2; obj.foo() // 1 foo() // 2 造成這種差

javascriptthis常見指向問題的分析

this常見指向問題 this的用法 1.直接在函式中使用 誰呼叫這個函式this就指向誰 2.物件中使用, 一般情況下指向該物件 3.在建構函式中使用 改變this的指向,兩種方法的作用都是相同的,傳遞的寫法不同而已。 call -- (指向誰,引數1,引數2......) 

javascriptthis指向

this常見指向問題 this的用法 1.直接在函式中使用 誰呼叫這個函式this就指向誰 2.物件中使用, 一般情況下指向該物件 3.在建構函式中使用 改變this的指向,兩種方法的作用都是相同的,傳遞的寫法不同而已。 call -- (指向誰,引數1

JavaScriptthis關鍵字改變指向的三種方法(apply、call、bind)

首先,瞭解一下this關鍵字。this關鍵字就涉及到函式呼叫的內容。函式的幾種呼叫方式: 普通函式呼叫 作為方法來呼叫 作為建構函式來呼叫 使用apply/call方法來呼叫 Function.prototype.bind方法 ES6箭頭函式 但是不管

JavaScriptthis 關鍵字

面嚮物件語言中 this 表示當前物件的一個引用。 但在 JavaScript 中 this 不是固定不變的,它會隨著執行環境的改變而改變。 1,在方法中,this 表示該方法所屬的物件。 2,如果單獨使用,this 表示全域性物件。 3,在函式中,this 表示全域性物件。 在函式中,

第149天javascriptthis的指向詳解

doc ava 常見 每一個 document () 學習 知識 對象 js中的this指向十分重要,了解js中this指向是每一個學習js的人必學的知識點,今天沒事,正好總結了js中this的常見用法,喜歡的可以看看: 1、全局作用域或者普通函數中this指向全局對象wi

掌握JavaScript基礎--理解this關鍵字的新思路

handle 無法 公眾號 post tom image gpo alter IT 普通函數 下面這種就是普通函數 function add(x, y) { return x + y; } 每個普通函數被調用的時候,都相當於有一個this參數傳進來。 內部函

JavaScript夯實基礎系列(三)this

瀏覽器 系列 中一 對象屬性 轉化 繼續 存儲 www 能夠 ??在JavaScript中,函數的每次調用都會擁有一個執行上下文,通過this關鍵字指向該上下文。函數中的代碼在函數定義時不會執行,只有在函數被調用時才執行。函數調用的方式有四種:作為函數調用、作為方法調用、作

JavaScript中的this關鍵字的幾種用法

JS 裡的 this 在 function 內部被建立 指向呼叫時所在函式所繫結的物件(拗口) this 不能被賦值,但可以被 call/apply 改變 1. this 和建構函式 function C(){ this.a = 37; }