透過使用Chrome的開發者工具來學習JavaScript

xiniubook發表於2013-09-30

本文作者是Peter Rybin,Chrome開發者工具團隊成員.

本文中,我們將透過使用Chrome的開發者工具,來學習JavaScript中的兩個重要概念”閉包”和”內部屬性”.

閉包

首先要講的是閉包(closure) - JavaScript中最有名的東西之一.一個閉包就是一個使用了外部變數的函式.檢視下面的例子:

1
2
3
4
5
6
7
8
9
function A(a, b, c){var ar =[a, b, c];returnfunction B(i){return ar[i];};}
 
var b = A('Here','I','am');
console.log( b(1));

函式宣告之後的第一條語句呼叫了函式A,函式A建立了一個值為陣列[a,b,c]的區域性變數ar,返回了一個函式B(儲存在了變數b中),然後執行結束.

第二條語句呼叫了函式B (b),返回並列印出了陣列ar.這就意味著A中的陣列ar在A結束執行後仍然存在.但是它儲存在什麼地方呢?當然,在b上!但是究竟是存在b的哪裡呢?某個屬性中?不是的.

這是JavaScript語言的一個核心特性:一個函式可以持有外層作用域的變數,並且除了呼叫該函式以外沒有任何其他方法可以訪問到這些變數.

透過使用Chrome的開發者工具來學習JavaScript

從現在開始,chrome的開發者工具可以讓閉包中的外部變數現形.在監控表示式(Watch Expressions)皮膚中檢視函式例項b,展開它的屬性後,應該會有一個稱為的子節點.所有被繫結的閉包變數都能在這裡看到,這些變數就是在函式呼叫時可能會被用到的變數.

內部屬性

開發者工具還能顯示出另外一個東西,叫做內部屬性(internal property).

假設你的程式碼中有個變數s,而且還執行了下面這樣的操作:

1
s.substring(1,4)// 返回'ell'

你覺得s肯定是個字串值嗎? 這可不一定.它也有可能是個字串包裝物件.嘗試下面的監控表示式:

1
2
"hello"
Object("hello")

第一個表示式是一個普通的字串字面量,第二個是一個功能完整(full-featured)的物件.令人費解的是,這兩個值幾乎有完全相同的表現.但是第二個表示式才真正的擁有自己的屬性,並且你也可以在它身上新增自定義的屬性.展開它的所有屬性你會看到,它不是一個完全常規的物件:它有一個內部屬性[[PrimitiveValue]] ,被包裝的字串值就儲存在這個屬性裡面.你不能在JavaScript程式碼中訪問到這個內部屬性,但是你能在開發者工具的中看到它.

透過使用Chrome的開發者工具來學習JavaScript

還有哪些值擁有內部屬性?那就是繫結函式(bound function).繫結函式也算是一種包裝物件,只不過被包裝的是個函式.嘗試執行下面的兩條語句:

1
2
function Sum(a, b){return a + b;}var inc = Sum.bind(null,1);// 將形參a繫結為1,this繫結為null

如果你把Sum和inc放在監控表示式皮膚中對比一下,你會看到,它們都是函式,但inc是一個不透明(non-transparent )的函式:你看不到它的函式體內容,也不能看到它定義時的作用域.

透過使用Chrome的開發者工具來學習JavaScript

這就是繫結函式的工作原理.在開發者工具中,你會看到[[TargetFunction]], [[BoundArgs]]以及[[BoundThis]]這三個內部屬性.它們都表明了inc是一個繫結函式,以及一些更具體的資訊:inc繫結的目標函式是Sum,繫結了一個引數1,繫結的this值是null.

透過使用Chrome的開發者工具來學習JavaScript

原文:

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29194811/viewspace-773665/,如需轉載,請註明出處,否則將追究法律責任。

相關文章