極品javascript進階部落格教程《ECMA-262-3 in detail》讀書筆記

來源:互聯網
上載者:User

 前言:

 在我看來javascript是一門非常鬆散靈活的語言,鬆散並不是貶義,而恰恰相反,是對js的一種讚美。javascript相對於c#等靜態編譯語言來說,就像一個騎單車已經十分熟練的頑皮孩子,已經不再需要遵循上車必須從車右邊扶車把,左腳踏踏板右腳蹬地幾下的標準動作了,他可以做出若干不同的上車花式,但始終不會背離平衡這一原則。正式這樣的靈活性甚至看上去有點怪異的行為令javascript與c#這些語言表現格格不入:它是物件導向,卻沒有類,能繼承又搞出個prototype,“this”的神出鬼沒難以捉摸,閉包,範圍,弱類型等概念更是讓人摸不著頭腦。

 但是請不要忘記,我們覺得js怪異只是因為我們早已習慣類C語言的思維,js還是一門電腦語言,就像那個愛玩花式的騎車小男孩沒有背離“平衡”這一原則一樣,js並沒有背離電腦語言的一個原則(就跟其他電腦語言一樣):控制電腦去做事 。

從另一個角度來說,正是因為js的靈活與怪異,我們更應該像學其他靜態語言一樣深入學習它。在“學習另一種頗為不同的語言”的原則指導下, 深入學習js還是很有價值的。學習js能令人從一種與c# java非常不同的思維去認識電腦語言和編程,去認識一些萬變不離其宗的核心東西和思想。

在我學習javascript的過程中,很自然地對很多概念迷惑不解,網上雖然有很多“深入理解javascript XXX”的教程,但始終覺得不夠深入,就像你問別人棧是什麼,別人只告訴你“先進後出”一樣不痛不癢。

但幸運的是,前幾天終於發現了俄國人Dmitry Soshnikov寫的一個系列部落格教程: 《ECMA-262-3 in detail》,在園子裡也有精彩的“官方翻譯”:http://www.cnblogs.com/justinw/archive/2010/04/16/1713086.html。這系列部落格真的是非常的有用,從ECMA規範的角度來解析js更加之深入和徹底,而且涵蓋了js進階的所有話題。但雖然該系列部落格寫的非常好,例子恰當,但畢竟其描述的都是js中比較進階的內容,因此不免有很多點很難馬上弄懂,需要反覆閱讀斟酌,因此本編部落格便是我在學習的過程中的筆記,隨時記錄一些心得和其他需要銘記的點。

 

第一章:Execution Contexts

 函數遞迴調用的時候也會產生execution context

execution context是邏輯堆棧結構

第二章:Variable Object

即使是在永遠不會被執行的else分支中聲明的變數,或者function定義,也會被存放在vo中 

function中的vo叫做Activation Object(AO) ,而global中的vo也就是global,VO只是泛稱。

scope chain=list  of parent's VOs  + function's own AO 

 

另外,有一個現象可能跟一句話有關:An activation object is created on entering the context of a function and initialized by propertyarguments which value is the Arguments object

這個現象就是:如果一個函數中聲明一個變數,且該變數的名稱與函數的形參的名稱相同,那麼,這個變數和這個形參其實是同一個東西,看例子:

function foo(i){
     var i=5;
    alert(arguments[0]); 

 foo(10);//5,而不是10
 

 

而反過來也成立:

 

function foo(i){
    var i;
    arguments[0]=10 
    alert(i); 

foo(5);//10,而不是5

至於底層的實現是不是就是這樣現在還在研究中,但好像以這樣來解析也行得通。 

 

第三章:this.  

Identifier 是變數名,函數名(例如 function foo(){}中的"foo",函數參數名及在global中未識別的屬性)

參考型別只出現在兩種情況:處理Identifier的時候,和屬性訪問器。屬性訪問器就是"."和"[]",例如"obj.foo"和"obj["foo"]"

參考型別的base屬性指向該對象的所有者

第四章:Scope chain.

“scope”其實就是[[scope]],通常說scope的時候是指函數對象的[[scope]]屬性,而 scope chain是指函數對象中[[scope]]鏈表(當然不一定就是鏈表結構) 

[[scope]]是在一個函數建立的時候建立的,而不是在一個函數被執行的時候(進入execution context)時候建立,並且並不會在函數執行其中改變,因此,才有閉包的機制:

var x=10;
function a(){
    alert(x);
}
function b(){
    var x=20;
    a();
}
b();//10,而不是20

 

 

 

 

第六章:閉包

 現在要解析閉包有點難,因為要說清楚閉包就必須要搞清楚scope/scope chain和 context,反正和前幾章都有關聯,要詳細解析閉包可能還要寫一遍比較完整的筆記。現在有些零碎的理解,先記下來吧,反正會有用到,先看一個閉包的經典例子:

function foo(){
   var x=10;
   return function(){
       alert(x);
   }
}
var bar=foo();
bar();//10

 

如果不是閉包的話,按邏輯來說,x是foo中的局部變數,當foo執行完返回的時候,x已經被釋放掉。那麼,從表象的層面來解析,閉包就是在函數返回後仍能訪問該函數內部資料的一種機制,從原理來說,就是被調用的函數(這裡是foo中的那個匿名函數)的scope包含了外部函數(foo)的資料(“資料”一詞是故意用的,這樣說比較籠統,因為我還不清楚這應該是什麼,難道是VO?遲些再研究一下),而從範圍的層面去看,就是因為“js是基於靜態範圍”的,所以《ecmascript in detail》中有一句話:Referencing to algorithm of functions creation, we see that all functions in ECMAScript are closures, since all of them at creation save scope chain of a parent context.(ecmascript中所有函數都是閉包)

 這裡必須看看“動態範圍”和“靜態範圍”。先看一個例子:

 

//假定這裡是global
var x=5;
function foo(){
   alert(x);
}

function bar(){
   var x=10;
   foo();
}
bar();//5,而不是10

靜態範圍,有些地方稱詞法範圍,是指:一個範圍在函數建立的時候,就已經確定好了,而不是在執行的時候。也可以用另外一句話說:函數範圍是在原始碼中確定的。

通過上面例子來看看這個“原始碼中確定“是什麼意思:上面例子中,調用bar的時候,進入bar的上下文,bar裡面聲明了一個x,並賦值x=10,然後調用foo,如果是動態範圍,也就是在代碼執行時刻確定範圍的話,那麼,foo裡面被alert的x應該是bar裡面的x,也就是10,但是在靜態範圍的原理下”函數範圍是在原始碼中確定的”,也就是說,調用foo的時候,解析引擎會回到foo定義的地方(原始碼的前4句)去找,而在這裡,很明顯,x是第一句原始碼定義的那個值為5的x,而且在foo被定義的原始碼中,值為10的x都還沒有出世~~~。這個就是我自己對“靜態範圍”的理解,不過對於動態範圍我理解不多,有空看看維基百科上關於動態範圍。

在這裡順便提一下,C語言也是靜態範圍:

#include "stdafx.h"

int x=5;
void fun1(){
    printf("%d",x);
}

void fun2()
{
    int x=10;
    fun1();
}
int _tmain(int argc, _TCHAR* argv[])
{
    fun2();//5
    scanf("%d",&x);

 

 ecmascript只使用靜態範圍(文法範圍)

 

ECMAScript中,閉包指的是:
從理論角度:所有的函數。因為它們都在建立的時候就將上層內容相關的資料儲存起來了。哪怕是簡單的全域變數也是如此,因為函數中訪問全域變數就相當於是在訪問自由變數,這個時候使用最外層的範圍。從實踐角度:以下函數才算是閉包:1.即使建立它的上下文已經銷毀,它仍然存在(比如,內建函式從父函數中返回)2.在代碼中引用了自由變數
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.