涅槃重生(一) JS中this的那些事

2021-09-08 03:35:15 字數 4346 閱讀 3582

經歷了一年多的各種嘗試之後,最終還是決定回到程式設計師的行列中來。一年中的許許多多事情不是由我自己主動結束就是最終走向了失敗幻滅。

從小開始教科書就教育我們做人不能三心二意、眼高手低,成功露出水面的訣竅也只能是他們在水面下苦苦構築的巨大冰山。回想從一開始起,就是以工程化為目的,奉行拿來主義,大部分情況下不知道自己放置於工程中的部分**所引用的庫中究竟是用什麼手法達到我想要的目的的。

故以此為契機重拾部落格寫作,記錄我重新學習的全過程,計畫中的學習內容當然不僅於前端。苦思冥想很久,決定以昨天面試官問的js中的this問題作為系列部落格的第一篇吧!

根據紅寶書介紹,在函式的內部有兩個特殊的物件: arguments 和 this,其中this引用的是函式據以執行的環境物件(也譯為執行上下文)。我們來看乙個紅寶書中的例子:

//例一

window.fruit =

;var a =

;function

say(

)say()

;a.say = say;

a.say()

;//"orange"

例子中的 say() 執行與全域性域下,預設指向 window 物件,相當於執行 window.say(),所以這時候 this.fruit 指向 window.fruit。而 a.say() 執行時此時 say() 執行於a物件之中,所以 this 物件指向 a 物件,這個時候當然輸出的就是 a.fruit 的值了。

通過這個例子我們已經簡單了解了 this 是什麼了,那麼它是怎麼在我們的日常程式設計中起到舉足輕重的作用呢?

我們通過乙個列印字元例子來看一看:

//例二

//實現列印字元

var str =

"hello"

function

printa()

else

}printa()

;//"hello"

我們通過呼叫 this 獲取到了上下文物件,輸出了其中 str 欄位的值。這樣我們的函式的返回值就不是固定的值了,而是由執行時候上下文的具體資料決定,大大提高了函式的靈活性!

this 的具體指向一直是各路面試的重點問題,下面我帶大家來捋一捋 this 指向的原理

這裡有乙個很重要的原理請大家務必謹記!

this的指向在建立時無法確定,只有具體呼叫時才能決定

this 的指向共有以下幾種情況:

1、如果乙個函式有 this,且未被上一級物件所呼叫,那麼這個 this 指向頂層物件,一般為window。

2、如果乙個函式有 this,且被上一級物件呼叫,那麼這個 this 指向上一級物件。

3、如果乙個函式有 this,這個函式被包含於多層物件中,儘管是被最外層物件所呼叫,但this仍指向上一級物件。

在理解這幾種情況之前,需要先明確我們的函式本質上也是頂層物件的乙個屬性,我們常用的 alert 函式其實也是 window 物件的乙個屬性,完整寫法應為 window.alert(),若 alert 中存在 this,那麼很明顯應該指向 window 物件。

在例一中已經有1、2的情況了,那麼3又是什麼情況會出現呢?

//例三

//本例 this指標指向上一級物件即 b,但 b中無 a屬性

//故結果為 undefined

var sample =}}

sample.b.fn(

);//undefined

以上舉的都是比較簡單的 this 的應用,下面我們來看看實際應用中 this 都是如何指向的。

一般地,函式呼叫有以下幾種方式:

下面來看看幾種呼叫的具體例子

普通函式呼叫

function

normal()

normal()

;//window 10

以方法的形式呼叫

var str =

"hello"

;var obj =

}obj.fn(

);//"hi"

構造函式呼叫

function

example

(num)

var num =

example(10

);console.

log(num.num)

;//undefined

console.

log(window.num)

;//10

函式中含return乙個物件

*null物件仍指向原函式例項

//此時this指向返回的物件

function

obj1()

return;}

var a =

newobj1()

;console.

log(a.user)

;//undefined

function

obj2()

return1;

}var a =

newobj2()

;console.

log(a.user)

;//liming

function

obj3()

return undefined;

}var a =

newobj3()

;console.

log(a.user)

;//liming

箭頭函式呼叫

//箭頭函式this始終指向其定義時的上下文物件

//箭頭函式this一旦定義無法改變

function

person()

,1000);

}var person =

newperson

;

來個例子

var obj1 =

;var obj2 =

;this

.name =

"jenny"

;var

getname

=function()

getname()

;//jenny

getname.

call

(obj1)

;//john

getname.

(obj2)

;//clancy

function.prototype.bind()

bind方法會建立乙個新函式,當呼叫這個新函式時,新函式會以建立他時的第乙個引數為 this ,後面傳入的引數當做是原函式的引數進行呼叫。

這是 api 上對於 bind 方法的解釋,也就是用於改變函式內部的 this 指向。下面來個例子

var name =

"john"

;function

person

(name)

,bind

(this),

500)

//此時該匿名函式this始終指向person物件}}

var person =

newperson

("clancy");

person.

sayname()

;//"clancy"

eval方法

該函式執行時,this 會繫結到當前作用域的物件上

這個方法由於效能問題所以基本不考慮了,但是還是以防萬一面試的時候被問到

var name =

"john"

;var

person

=function()

}person.

sayname()

;//"clancy"

var a = person.

sayname()

;a()

;//"john"

以上便是關於 this 的所有總結了,其中有些地方還是需要細細琢磨。

最近獲得的最大的人生經驗,就是要溫故而知新,很可能有些你學過的知識你並沒有真正的掌握。

所以偶爾複習一下才是上上之策。

i can be whatever i want to be

我和學員那些事兒 涅槃重生的背後

在這一年,我重回原點 這一年,我在磨難中成長 這一年,我滿載對學員 會員朋友的謝意!趁此之際,回顧一下這一段段難忘的記憶。學員催生的艱難決定 在罵聲和讚賞聲交織中成長 於是我針對這些問題一一嘗試努力改進,反覆練習,盡量以面授的節奏來講課,盡量把話講得更標準。不過,說實話,這普通話很難練得很標準,我只...

我和學員那些事兒 涅槃重生的背後

在這一年,我重回原點 這一年,我在磨難中成長 這一年,我滿載對學員 會員朋友的謝意!趁此之際,回顧一下這一段段難忘的記憶。學員催生的艱難決定 在罵聲和讚賞聲交織中成長 於是我針對這些問題一一嘗試努力改進,反覆練習,盡量以面授的節奏來講課,盡量把話講得更標準。不過,說實話,這普通話很難練得很標準,我只...

涅槃重生,這是我的時代,也是你的時代

今天是2021年3月的第一天,我休整了乙個月,這段時間我想了很久,打算來一次斷捨離,整合之後取名為盛夏隨心筆記,個人中文筆名 盛夏,英文筆名 bj,以後會用這兩個名稱進行隨心寫作,也是我目前階段對生活的態度,隨心而行,也總結十二個字 打破定義,達己,學無止境。這世界似乎每個人都有對生活不一樣的態度,...