你害怕javascript的this嗎?

this在javascript中一直像是一個(gè)惡魔般的存在,導(dǎo)致很多的前端開發(fā)者對(duì)它都抱有一定的恐懼感,畢竟它看起來是那么的變幻無常。

克服對(duì)它的恐懼,就得需要正面面對(duì)它,了解它熟悉它。對(duì)于this的解釋我覺得在《你不知道的javascript》中解釋的已經(jīng)很清楚的,這里我就不在照搬概念了。

  • 了解this
    在函數(shù)內(nèi)部this既不是指函數(shù)本身也不指函數(shù)的詞法作用域。在函數(shù)沒有調(diào)用之前,this是不確定的,只有在調(diào)用函數(shù)的時(shí)候才會(huì)確定this的指向。在函數(shù)調(diào)用時(shí),除了傳入?yún)?shù)外,js還會(huì)默認(rèn)傳遞隱形的this和arguments參數(shù)。this指的是當(dāng)前的執(zhí)行主體。

  • 那么我們?cè)趺凑业疆?dāng)前的執(zhí)行主體呢?
    在js中有這么5種情況:
    先看看下面幾個(gè)例子
    1, 默認(rèn)綁定

function func(){
  console.log(this.a)
}
var a = 'a'
func(); // a

這種情況就是默認(rèn)綁定,為啥是默認(rèn)綁定呢?因?yàn)樵谡{(diào)用函數(shù)的時(shí)候,沒有用到任何的修飾,所以只可能是默認(rèn)綁定。那么this就指向全局變量。所以,不管在什么地方調(diào)用func,this == window。需要注意的是在嚴(yán)格模式下,this不會(huì)指向全局變量,會(huì)變成undefined。
2, 隱式綁定

var name = 'global'
function fn(){
  console.log(this.name)
}
let obj = {
  name: 'obj',
  fn: fn
}
obj.fn(); // obj

這種隱式綁定,在函數(shù)調(diào)用的時(shí)候,會(huì)把this綁定到當(dāng)前執(zhí)行者的上下文對(duì)象。也就是說obj對(duì)象在調(diào)用函數(shù)fn的時(shí)候是擁有了function fn(){},所以this就會(huì)綁定到obj對(duì)象上。隱式綁定我們只需要記住,是誰調(diào)用函數(shù),this就指向誰。
需要注意的是,在隱式綁定中this也有可能會(huì)丟失!

var name = 'global'
function fn(){
  console.log(this.name)
}
let obj = {
  name: 'obj',
  fn: fn
}
var newFn = obj.fn;
newFn(); // global

因?yàn)榇藭r(shí)調(diào)用newFn是不帶任何修飾的,所以已經(jīng)變成了默認(rèn)綁定,這個(gè)就相當(dāng)于
var newFn = fn
3, 在構(gòu)造函數(shù)中的this

function Obj(name){
  this.name = name
}
var o = new Obj('小明');
o.name // 小明

在使用new操作函數(shù)的時(shí)候,函數(shù)返回的對(duì)象就是函數(shù)內(nèi)部的this指向。
4,顯示綁定
這個(gè)就比較明顯了,一般都是會(huì)有call,apply,bind這樣的修飾符,調(diào)用這些修飾函數(shù)的函數(shù)的第一個(gè)參數(shù)就是this的指向

function func(){
    console.log(this.name)
}
var name = 'global'
var newO = {
  name: 'newO'
}
func.call(newO) // newO

5,箭頭函數(shù)
箭頭函數(shù)是沒有this的,那么箭頭函數(shù)內(nèi)部的this會(huì)是誰呢?它的指向是包裹該函數(shù)的外面作用域,也就是說外層是否有函數(shù)包裹,那么this就是外層函數(shù)的this;外層沒有函數(shù),那么this就是window。

var name = 'global'
function func(){
    var name = 'func'
    var inner = () => {
        console.log(this.name)
    }
    return inner
}
func()() // global

function func2(){
    var name = 'func2'
    var inner = () => {
        console.log(this.name)
    }
    inner()
}
func2(); // global

function func3(name) {
    this.name = name;
    var inner = () => {
          console.log(this.name)
    }
    inner()
}

var obj = new func3('func3'); // func3

前兩種情況都是global,是因?yàn)楹瘮?shù)都是默認(rèn)綁定,this就是window。最后的一種情況打印func3,包含inner函數(shù)的外層函數(shù)func3的this在用new操作之后指向的是obj,所以inner箭頭函數(shù)的this,就是obj。

function func3(name) {
    this.name = name;
    function inner() {
          console.log(this.name)
    }
    inner()
}

var obj = new func3('func3'); // global

如果不是箭頭函數(shù)的話,就會(huì)打印全局global。

說了一大堆,可能有同學(xué)已經(jīng)頭暈?zāi)垦A?,那么最后我們用一張圖總結(jié)一下。
image.png

如果上面說的那么多可以幫助到你,可以幫我點(diǎn)個(gè)小小的愛心支持鼓勵(lì)下。如果有講的不清楚或者不對(duì)的地方也望大佬在評(píng)論區(qū)多多指點(diǎn)共同進(jìn)步,康桑密達(dá)!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 關(guān)于 this this 關(guān)鍵字是 JavaScript 中最復(fù)雜的機(jī)制之一。它是一個(gè)很特別的關(guān)鍵字,被自動(dòng)定義在...
    游學(xué)者灬墨槿閱讀 625評(píng)論 1 2
  • 為什么要學(xué)習(xí)this? 首先,我們?yōu)槭裁匆獙W(xué)習(xí)this? this使用頻率很高,如果我們不懂this,那么在看別人...
    六月繁花開閱讀 519評(píng)論 0 3
  • 1.函數(shù)調(diào)用棧和調(diào)用位置 在函數(shù)執(zhí)行的時(shí)候,會(huì)有一個(gè)活動(dòng)記錄(也叫執(zhí)行上下文)來記錄函數(shù)的調(diào)用順序,這個(gè)就是函數(shù)調(diào)...
    lightNate閱讀 605評(píng)論 1 14
  • ??我們都知道Javascript中的「this」真的是個(gè)頭痛的東西,今兒我們就來好好總結(jié)下這個(gè)「this」。 ?...
    Jason_Shu閱讀 495評(píng)論 0 0
  • 一是門診險(xiǎn),二是重疾險(xiǎn),三是住院險(xiǎn)。 重疾險(xiǎn)必須買,越早越好 毫無疑問,兒童重疾險(xiǎn)必須買,越早越好。因?yàn)榘l(fā)重疾,對(duì)...
    逸縷塵痕閱讀 159評(píng)論 0 0

友情鏈接更多精彩內(nèi)容