文章出處

  

      說到funciton,也是我對js非常吐槽的一點,封裝的讓我眼瞎,馬蛋的,哥只能大眼睜著去黑盒的使用,簡直只有完完全全的聽各類圖書對

function的道聽圖說,完全沒有做到一點點的眼見為實。

 

一:function是什么

  在很久很久以前,我們只知道function是一個函數,用C#的話來說就是一個方法,既然是方法嘛,肯定就是掛在類下面的,但是其實呢?

在js中函數就是對象,并不是我們慣性思維中的方法。何以為證呢?看代碼。

從圖中可以看到我聲明了一個say函數,但是我很奇怪的看到,為什么say函數會有一些屬性和方法呢?比如本該屬于Object的toString,valueOf,

constructor等等?然后比較好奇的去看看constructor到底是什么,可以看到其實是個Function構造函數,那這樣我就非常清楚了,然來say只不過

是Function對象的一個實例引用,知道了這個我就可以很輕松的把代碼恢復如下:

二:看看function中一些屬性和方法

  現在我們知道了function其實就是一個對象,我們知道所有的引用類型都是繼承自object,那為了好做比較,我定義了一個object的實例,

接下來看看function中到底都有那些專屬屬性和方法。

可以看到,子類function確實還是有點自己的東西,那接下來就簡單探討下常用的屬性和方法。

 

1. arguments屬性

  說到這個屬性就特么的來氣,就眼瞎,眼瞎的地方在于這個arguments屬性里面其實做了很多很多的東西,以至于下面的一些奇怪現象

可能會讓你目瞪口呆!!!

 

<1>奇怪現象一:我的function中都沒有形參,居然還能接受到實參的值。。。

 

 

<2>奇怪現象2:形參和實參傳遞并不統一,可以多傳遞,可以少傳遞,js都不會報錯。

 

 

<3>奇怪現象3:形參和arguments居然可以做到同步,太神奇了。

 

上面的三個現象是不是讓你覺得很奇怪???這些奇怪的現象是不是讓你覺得Function中封裝的太狠,因為他們做了很多操作,而你卻只能大眼

瞪小眼,啥也看不到。。。是不是非常遺憾呢???由于看不到源代碼我也無能為力,只能根據書中的講解以及自己的理解來領悟了。“高程3”中

是這么說的,當調用function中傳遞的實參其實是給了Function構造函數中的一個”內部數組“,而arguments其實是對”內部數組“的高層封裝,

封裝后的arguments不再是數組了,而是一個偽裝的數組,之所以這么說是因為arguments還需要一個自己的獨有屬性callee,而這個callee

保存的就是當前的對象say,所以只能把arguments做成對象,我可以讓你眼見為實。

然后最詭異的一個問題就是形參能夠和arguments實現數據同步,既然能夠做到同步,我的第一個反應就是使用同一塊內存地址,但是仔細想想

他們怎么可能做到共享內存地址呢?但是再想想的話,arguments是對”內部數組“的封裝,我就想這個name應該也是被做過手腳的,也就是說

name其實也是對”內部數組“的封裝,就像ECMA5中對字段提供get/set訪問器一樣,當然這是我的一種猜測,解釋代碼如下:

 

從上圖中我們看到,當我對name進行賦值的時候,其實改變的是args這個數組的值,同理當我改變arguments的值時,其實也是修改”內部數組“

的值,通過類似這種方法來達到我們上層看到的同步機制,畫個簡圖如下:

 

2. length屬性

  如果你知道了上面的原理,那這個也好猜測,要么取得是正真的“內部數組”的length,要么就是取偽類arguments的length,反正最終都是

”內部數組”的length,對不對,比較常用但是又沒什么好說的。

 

3.prototype屬性

   這個也是Function內部做出來的一個屬性,很有意思,我想大家也有耳聞,也不是三言兩語能說得清楚的,準備放在下篇詳細的講講。

 

4.caller屬性

   看這個名字大概也知道個一二,就是用來獲取當前的父函數,不要小看這個caller哦,你有沒有想過它可以實現C#中的stacktrace的功能

呢?有時候我們記js日志就靠這玩意了,比如下面這樣。

 

5:call,apply方法

 因為這兩個函數的功能都一樣,只不過call方法必須逐一參數賦值,而apply必須傳遞數組,如果想眼見為實,可以看看它們在vs里面的代碼

提示,一切都明白了,所以我就放在一塊說了,不過這鳥東西有什么好處呢?它最大的好處就是可以隨便綁定對象,然后就可以實現對綁定對象

動態新增方法和屬性,可能說的有點抽象,看個例子就OK啦。

 我們發現,本來我的obj只是一個空對象,通過apply之后,我的obj對象具有name和age屬性了,是不是很神奇呢?

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜

    大師兄 發表在 痞客邦 留言(0) 人氣()