2019-12-20:第五章:引用類型(函數(shù))

5.function類型

函數(shù)實際上是一個對象。因此函數(shù)名的本質(zhì)是一個指向函數(shù)對象的指針。

函數(shù)的對象定義法

他并不與某個函數(shù)綁定,這同時也就解釋了將某一個函數(shù)名多次定義,js只會調(diào)用最后一次定義的內(nèi)容。

另外,由于我們說函數(shù)名實際上是一個指向函數(shù)對象的指針,那么這也就意味著同一個函數(shù)可以有多個名字。我們可以在定義一個函數(shù)后,定義另外一個變量 = 之前的指針,這樣同一個函數(shù)就有兩個名字了。因此,函數(shù)名只是指向函數(shù)對象的引用,這個定義非常重要。要訪問函數(shù)指針,只需要訪問變量值,而去掉括號即可。

5.1沒有重載(深入講解)

函數(shù)名是一個指針,他實際上并不與某個函數(shù)綁定,這同時也就解釋了將某一個函數(shù)名多次定義,js只會調(diào)用最后一次定義的內(nèi)容。也就是沒有重載的原因。

調(diào)用的是最后一次定義的a

5.2函數(shù)聲明和函數(shù)表達(dá)式

在運行js代碼時,解析器和率先讀取到函數(shù)的聲明,并且使其在任何代碼被執(zhí)行前設(shè)置為可訪問狀態(tài)。而真正的函數(shù)表達(dá)式,則必須等到解析器執(zhí)行到了調(diào)用它的具體代碼時,才會被解釋和執(zhí)行。

函數(shù)的聲明會被升格到代碼頂部,而具體的定義只有在被調(diào)用的是皇后才會被解釋和執(zhí)行

為了驗證這個結(jié)論,我們可以使用兩種函數(shù)定義的方式,檢查函數(shù)聲明的升格情況:

賦值型的函數(shù)定義報錯了

這是因為賦值的函數(shù)定義并不是函數(shù)聲明,不會在代碼被解釋前執(zhí)行函數(shù)的升格操作。因此在運行到console.log(sum2(a,b))時,sum2并沒有被定義,它也根本沒有指向文中定義的函數(shù)對象,所以報錯sum2 is not a function也不足為奇了。

5.3作為值的函數(shù)

因為我們可以將函數(shù)名看做是指向函數(shù)對象的引用類型變量,因此,可以將函數(shù)作為一個參數(shù)傳遞給另外一個函數(shù),就是理所當(dāng)然的了。

這里sum1是作為內(nèi)部的參數(shù)變量而使用的。如果不將sum1寫入函數(shù)中,根據(jù)前面我們講過的標(biāo)識符解析流程,他仍然可以在外層環(huán)境中找到該標(biāo)識符。

除此之外,在一個函數(shù)中返回另外一個函數(shù)也是非常好的寫法:舉個例子,在一個函數(shù)的連環(huán)定義中,內(nèi)容其實有三個參數(shù):propertyName,object1,object2:

函數(shù)中返回一個函數(shù)

我們可以在外面的函數(shù)中傳入一個propertyName的值,隨后這個函數(shù)會返回一個函數(shù)的定義:

function(object1,object2){? do some things}

此時這個被返回的函數(shù)就可以在別的函數(shù)中作為一個參數(shù)被使用過了:最簡單的使用例子就是我們定義比較函數(shù):

一個非常好的模塊化編程的例子

5.4函數(shù)內(nèi)部的屬性

函數(shù)內(nèi)部有兩個特殊屬性:arguments和this。

① arguments我們在前文多次提到過,他是一個類數(shù)組的保存參數(shù)的對象,雖然arguments的主要用途是保存參數(shù)對象,但這個對象其實還有一個叫做callee的屬性,這個屬性是一個引用類型的指針,它指向擁有arguments對象的函數(shù)。

而我們可以使用它,在函數(shù)發(fā)生遞歸時,一旦想要改變函數(shù)名,那么遞歸就會失效,但是使用callee替代原來的函數(shù)名指向函數(shù)就不會有什么問題:

可以發(fā)現(xiàn)使用callee達(dá)到了相同的效果

② 函數(shù)內(nèi)部地另外一個特殊對象是this。this是在js編程中經(jīng)常搞不清楚的一點。但是書里有一句清晰的定義,即永遠(yuǎn)記住一句話:this指向的是函數(shù)據(jù)以引用的環(huán)境對象?;蛘哒f,this的值就是據(jù)以執(zhí)行的環(huán)境對象。

換句話說,函數(shù)定義在哪個類里,它所指向的就是哪個類。

第二次第三次結(jié)果不同,因為執(zhí)行的環(huán)境對象不同

對于第一個this.color,因為其定義在全局類里,環(huán)境對象為window,因此color為全局的red。

對于第二個this.color,因為其是從ob1.f()發(fā)起的,環(huán)境對象為ob1,因此this指向ob1,因此color為類內(nèi)的blue。

對于第三個this.color,雖然是在函數(shù)內(nèi)定義,但是因為會發(fā)生函數(shù)定義升格,因此其環(huán)境是全局類,環(huán)境對象為winodw,因此color為全局的red。

但是在這里同時要注意,函數(shù)的名字僅僅是一個包含指針的變量。因此,即便在不同的環(huán)境里,打印color得到不同的值,但其實全局的fun1與ob1.f兩個指針同樣指向一個函數(shù)。二者做邏輯判斷也會返回true。

③ 還有一個函數(shù)屬性叫做caller,它返回調(diào)用當(dāng)前函數(shù)的函數(shù)的引用。定義讀起來很繞,但是看個例子就明白了:

打印出的是fun1()的定義

5.5函數(shù)的屬性與方法

前文我們提到過,函數(shù)其實也是對象,因此函數(shù)也有屬性和方法。每個函數(shù)都有兩個屬性:length和protype,以及三個方法:apply和call,和bind。

length為這個函數(shù)在定義時寫入的參數(shù)個數(shù)。

prototype為真正保存引用類型所有實例方法的地方,它是函數(shù)的一個子對象,在第六章會詳細(xì)介紹這個屬性,在這先按下不表。另外,prototype屬性是不可以枚舉的,因此for-in無法發(fā)現(xiàn)該屬性。

展示對象自帶的方法

apply和call的用途都是在特定的作用域中調(diào)用函數(shù)。實際功能就是設(shè)置函數(shù)體內(nèi)this的值。

apply接受兩個參數(shù):1是特定的作用域,另外一個是參數(shù)數(shù)組。而call與apply唯一的不同僅僅是call是填參數(shù)數(shù)組,而apply是把參數(shù)全部一個一個列進(jìn)去。

首先運行fun2時,this指向window,因此this.c = 10,fun1的結(jié)果也就是13。

當(dāng)將d.f也指向函數(shù)fun2時,this指向了d,因此this.c = 20,fun1的結(jié)果也就變成了23。

apply和call可以有效的指定函數(shù)在何種作用域運行,我們可以首先定義類,再將不同的類作為環(huán)境傳入函數(shù)中去,這時函數(shù)中的this.prototype的值就會變成不同環(huán)境域下的值。

而bind與前二者不同,bind是根據(jù)已有的函數(shù)復(fù)制一個新的函數(shù),而這個新的函數(shù)的作用域和this指向的對象由開發(fā)人員自己決定。一般使用可以分為三個步驟:

可以發(fā)現(xiàn),新的函數(shù)的作用域已經(jīng)被更換為了o,因此即便是在全局話你就能夠下跑這個函數(shù),仍然是采用o作為執(zhí)行環(huán)境對象。

另外其實每個函數(shù)也都有toLocaleString,toString,valueOf三個方法,但是因為不同的瀏覽器返回的值不同,但基本上都是函數(shù)實現(xiàn)的內(nèi)容,這些信息在調(diào)試代碼時是比較有用的。在這就不多贅述了。

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

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

  • ??引用類型的值(對象)是引用類型的一個實例。 ??在 ECMAscript 中,引用類型是一種數(shù)據(jù)結(jié)構(gòu),用于將數(shù)...
    霜天曉閱讀 1,218評論 0 1
  • 概要 64學(xué)時 3.5學(xué)分 章節(jié)安排 電子商務(wù)網(wǎng)站概況 HTML5+CSS3 JavaScript Node 電子...
    阿啊阿吖丁閱讀 9,849評論 0 3
  • 函數(shù)和對象 1、函數(shù) 1.1 函數(shù)概述 函數(shù)對于任何一門語言來說都是核心的概念。通過函數(shù)可以封裝任意多條語句,而且...
    道無虛閱讀 4,947評論 0 5
  • ECMAScript關(guān)鍵字 delete do else finally function in instance...
    doudou2閱讀 768評論 0 0
  • 本章內(nèi)容 使用對象 創(chuàng)建并操作數(shù)組 理解基本的 JavaScript 類型 使用基本類型和基本包裝類型 引用類型的...
    悶油瓶小張閱讀 779評論 0 0

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