摘要:是什么這個單詞是一個代詞,所以應該是指代某些東西搞清楚的關鍵之處,就是要搞清楚指代了什么那么到底指代了什么呢就像你平時指著一個蘋果說指著一個香蕉說同樣,也會因為情況的不同而不同在中按照常規理解,的值是什么取決于函數如何被調用然而,的值是什么
1. this是什么
this這個單詞是一個代詞,所以this應該是 指代某些東西
搞清楚this的關鍵之處,就是要搞清楚this指代了什么
那么this到底指代了什么呢?
就像你平時
指著一個蘋果說 this is an apple
指著一個香蕉說 this is a banana
同樣,this也會因為情況的不同而不同
在JavaScript中
按照常規理解,this的值是什么取決于函數如何被調用
然而,this的值是什么完全取決于對應函數被call時傳入的第一個參數,而這一般是由js提前就預置好的
注意:這種方法可以判斷一般情況下的this是什么
判斷this值就看函數是怎么被調用的[函數有全局調用和方法調用]
this指向調用它的距離最近的那一個
// 例子 function fn() { console.log(this) } let obj = { a: "", fn: fn } // 場景一 fn() // window[瀏覽器] or global[node] // 場景二 obj.fn() // obj // 場景一:全局調用 // 場景二:方法調用
function VS method
function xx(){...} 是function
method某個對象下面的方法 如 obj = {fn:function(){...}} obj.fn() 叫做方法[method]
更詳細的說明請看深入淺出面向對象和原型【概念篇1】
// test1 function fn() { console.log(this) } let obj1 = { wrapper: { a: "a", fn: fn } } obj1.wrapper.fn() // ? // fn()是被當做wrapper的方法被調用的,所以this是wrapper // this指向調用它的距離最近的那一個 // test2 function executeCallback(cb) { cb() } executeCallback(obj1.wrapper.fn) // this是全局變量 // 因為executeCallback函數是把cb當成全局函數進行調用的 // 不像是obj.cb(),若是obj.cb()就是方法調用了
按照常規理解已經可以解決大部分的面試、筆試題了,但如果想究this之根本,還需要通過call2.2 用call理解
注意:通過對call的初步理解,你可以知道this的值為什么是這樣的,但這種思維不方便你猜this
首先,我們要清楚this在函數中的位置
function fn1([this], parameter) { // this就是隱藏的第一個參數,而且永遠是第一個參數 console.log(this) }
其次,我們要知道call的語法
fun.call(thisArg, arg1, arg2, ...)
OK,現在我們要知道你在使用call的時候
call傳入的第一個參數可以指定(改變)fn1的第一個參數,也就是隱藏的this
所以,為什么直接全局調用fn1時,打印出來的是window呢?
因為js已經幫你call了
// 你寫的代碼 fn1() // 在你寫上面代碼的時候,js幫你寫了一行你看不到的代碼 fn1().call(undefined) // 你可能回問:這樣打出來的值應該是undefined呀 // 但瀏覽器有個機制 // 如果你傳的 thisArg 就 null 或者 undefined,那么 window 對象就是默認的 context(嚴格模式下默認 context 是 undefined)
我們重新來看待一下全局調用和方法調用,以及js是如何用call指定this的
// 例子 function fn() { console.log(this) } let obj = { a: "", fn: fn } // 場景一 fn() // window[瀏覽器] or global[node] // js幫你寫的代碼 fn().call(undefined) // 場景二 obj.fn() // obj // js幫你寫的代碼 obj.fn().call(obj)
小測試(小陷阱)
let module = { x: 42, getX: function () { return this.x; } } let retrieveX = module.getX; console.log(retrieveX()); // undefined console.log(module.getX()) // 422.3 嚴格模式下的this
嚴格模式下只需要注意一點就行,其它情況下與非嚴格模式相同
全局作用域里函數中的this是undefined
function test() { "use strict" console.log(this) } test() // undefined
所以,在使用構造函數時,如果忘了加new,this不再指向全局對象,而是報錯,因為這就是函數的全局調用
let People = function (name) { "use strict" this.name = name } People() // Cannot set property "name" of undefined3.幾種復雜情況中的this 3.1 數組中的this
function fn() { console.log(this) } arr[fn, fn2, fn3] arr[0]() // ?? // answer:arr // 解析 // 數組也是對象的一種 // arr[0]() 可以看做 arr.0().call(arr)3.2 嵌套函數中的this
// 例子一 function fn0() { function fn() { console.log(this); } fn(); } fn0(); // fn中this是全局變量 // 例子二 let a = { b: function () { console.log(this) // {b:fn} function xx() { console.log(this) // window } xx() } } a.b()3.3 setTimeout、setInterval中的this
document.addEventListener("click", function (e) { console.log(this); setTimeout(function () { console.log(this); // 這里的this是全局變量 }, 200); }, false);3.4 事件中的this
document.querySelector("div").addEventListener("click",function (e) { console.log(this) // }) // 事件里的this指向的是觸發事件的DOM節點3.5 使用new時的this
請看深入淺出面向對象和原型【番外篇——重新認識new】
4.總結如果幾種復雜情況下的this你看完了,你應該會有疑惑
為啥我明白了全局調用和方法調用,但this的值仍然和我推斷的不一樣呢?
我說過了,this的值是call的第一個參數,js已經給很多this進行call了
所以,總結一下
this的值是什么,你別猜,很可能會和你想的不一樣
console出來或者去看文檔、看源碼才是最穩妥的選擇
如果你非要猜,就套用一下我這篇博客寫到的這幾種情況
如果你怕猜錯,又要用到this,很簡單,直接用bind去強制指定this
關于call/apply/bind 請看this總結【2】—— call/apply和bind5.參考
this 的值到底是什么?一次說清楚
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92865.html
摘要:和概覽我們要將歸為一類,單獨歸為一類三者的共同點是都可以指定和都是綁定在的原型上的,所以的實例都可以調用這三個方法至于為什么,看完這篇文章你就懂了如果你不懂什么是實例的話,請移步深入淺出面向對象和原型概念篇深入淺出面向對象和原型概念篇第一個 1.call/apply和bind概覽 我們要將call/apply歸為一類,bind單獨歸為一類 三者的共同點是都可以指定this call/...
摘要:目前采用動態加載異步組件的方式來實現小組件之間的通信。內容使用過的都應該知道的動態加載組件通過來綁定需要加載的組件。總結本篇主要借助的動態組件和打包單文件來實現動態加載異步組件,通過的事件總線掛載在上來實現平級組件之間的通信。 背景: 目前我們項目都是按組件劃分的,然后各個組件之間封裝成產品。目前都是采用iframe直接嵌套頁面。項目中我們還是會碰到一些通用的組件跟業務之間有通信,這種...
摘要:說明的視頻片段分發現在沒做出什么成果作者還提了一句,協議有望成為直播內容的傳播協議。仿佛也沒能掩飾住不知道怎么分發視頻片段的尷尬說了這么多,看了代碼發現視頻片段還是通過分發總結最終將建立一個可擴展的,即用即付的直播網絡 Background Livepeer旨在構建帶有激勵機制的視頻直播分布式網絡 Blockchain 以太坊 智能合約和交易基于Ethereum以太坊網絡 DP...
摘要:箭頭函數基本語法函數語法具名函數匿名函數三句話第一句話聲明第二句話聲明匿名函數第三句話把匿名函數賦值給箭頭函數語法特點只能做賦值,不能做聲明第一種寫法完全寫法不省略參數個數,不省略函數體花括號參數個數函數體內語句個數第二種寫法省略參數括號參 1.箭頭函數基本語法 1.1 ES3 函數語法 // 具名函數 function xxx(arg1, arg2) { console.lo...
閱讀 1872·2021-09-22 15:29
閱讀 3355·2019-08-30 15:44
閱讀 3567·2019-08-30 15:43
閱讀 1766·2019-08-30 13:48
閱讀 1493·2019-08-29 13:56
閱讀 2478·2019-08-29 12:12
閱讀 972·2019-08-26 11:35
閱讀 1055·2019-08-26 10:25