javascript筆記:深入分析javascript裡對象的創建(下)—從對象創建到javascript程 – Javascript教程_JS教程_技術文章 – 程式設計聯盟

 

為什麼現在主流程序語言裡我們都要創建對象瞭?下面這個定義我想能給我們一個答案:

  面向對象語言裡對象的定義是:對象是人們要進行研究的任何事物,從最簡單的整數到復雜的飛機等均可看作對象,它不僅能表示具體的事物,還能表示抽象的規則、計劃或事件。拋開這些抽象的定義,從計算機底層技術來理解,對象其實就是一種存儲數據的方式。

  寫這個系列下篇著實讓我犯難瞭,本來我想寫閉包和原型的,但是總覺得不好,在和一位以前同事討論javascript技術時候他告訴我們在計算機語言裡不管是什麼樣的變量其實本質都是數據在計算機的存放方式瞭,程序就是數據和運算組成的,他說我既然在學習javascript對象的創建,那麼你可以想想創建出的對象究竟是什麼樣的東東,他接著說道,在計算機語言裡你不管在創建什麼比如基本數據類型還是復雜類型的數據,其實說白瞭都是變量,變量就是程序裡的數據,而程序的運行就是不停的檢索這些數據,創建數據,再檢索數據,循環往復,最終數據被持久化的過程,他還說,我經常會問他提高程序性能,優化程序的技巧,那麼提高程序裡對數據的檢索能力就是最終極的程序性能優化瞭。

  最近研究雅虎的前端技術,才知道這位大牛講的精辟瞭。

  雅虎的前端技術力說道:

  在javascript裡一共有四種存儲數據的方式(最基本的):

  直接量

  直接量隻代表自身,不存儲特定位置。Javascript裡面的直接量有:字符串、數字、佈爾值、對象、數組、函數。正則表達式以及特殊的null和undefined。

  變量

  開發人員用關鍵字var定義的數據存儲單元。

  數組元素

  存儲在javascript數組對象內部,以數字為索引。

  對象成員

  存儲在javascript對象內部,以字符串為索引。

  牛逼的雅虎前端工程師對這些存儲數據的方式進行瞭性能測試,在大部分瀏覽器裡讀取直接量和變量的速度遠遠大於讀取數組元素和對象成員。也許我們可以這麼思考對象創建:每創建一個對象我們就增加瞭數據檢索的復雜度,假如對象裡再嵌套對象,那麼性能損失將是以幾何倍數的增加。

  對象的創建或許就是應用響應緩慢夢魘的開始。

  我以前說過在javascript也可以借用java裡那句話,:一切皆對象,就連函數也能當做對象。如此說來創建一個函數就是在創建一個對象,而如何創建這個對象是提高程序的性能的關鍵所在。

  在javascript裡創建一個Function對象學問大瞭,如果我們把函數當做對象,有些難以理解的概念也就好理解多瞭。

  在中篇裡面我講到瞭作用域,作用域到底什麼呢?作用域其實是Function對象實例的一個內部屬性【Scope】。函數被創建時候【Scope】這個內部屬性包含瞭這個函數的作用域內所有對象的集合,這個集合叫做作用域鏈,作用域鏈決定瞭函數能訪問到那些數據。

  下面我創建一個函數add,代碼如下:

<script type="text/javascript">

function add(a,b)

{

    var sum = a+b;

    return sum;

}

</script>

 

   這是一個非常常見的函數,我們先定義好這個函數,記住先不執行它,當頁面被加載,這個函數也會被初始化,記得前面我講過,這樣定義的函數是屬於window的,加載頁面時候會預編譯的,這時候函數add的作用域鏈如下圖:

  

 

  

  當函數add被創建時候,如上圖,add函數裡作用域鏈所包含的對象。(隻是部分瞭)

  為什麼這樣,我這裡還真說不清瞭,我在firebug裡面在函數add處定義好斷點,大傢看如下結果:

  

 

  這就是函數add的作用域鏈,也就是這個函數可以訪問到的對象集合瞭。

  這裡隻定義瞭一個函數瞭,函數隻有在運行時候才看到它的本質瞭。看下面代碼:

 

<script type="text/javascript">

function add(a,b)

{

    var sum = a+b;

    return sum;

}

add(1,2);

</script>

復制代碼

  當函數被執行的時候,執行函數會創建一個稱為“運行期上下文(execution context)”的內部對象。這就是我在中篇裡講到的執行環境瞭,不過他是在函數執行時候創建的內部對象瞭,而絕非是函數一個固有的屬性,隻有函數執行時候才會被創建瞭,一個運行期上下文定義瞭一個函數執行時的環境。函數每次執行時候對應的運行環境是獨一無二的,所以多次調用同一個函數時候會導致創建多個運行期上下文,當函數執行完畢,執行器上下文就被銷毀瞭。

  我對運行期上下文的理解就是函數內部一個匿名的函數,這麼理解的原因是因為創建執行器上下文時候也會創建屬於他的作用域鏈瞭,因為我認為在javascript裡面隻有函數才有作用域鏈這個屬性瞭,不過這個特別作用域鏈有特殊作用:這個作用域鏈是用來解析標示符的。

  我的對象的創建的內容講完瞭,由對象的創建我引出瞭作用域和執行環境的概念瞭,也是對象的創建中的特例函數對象的創建我引入瞭作用域和執行環境的本質到底是什麼,對象的創建的內容就此結束瞭,下一篇博文我將通過作用域鏈和執行環境來說說如何寫出高效的javascript程序瞭。

  好久沒寫博客瞭,有朋友說我堅持不去瞭,當然不是瞭,最近事情真多,關鍵斷網瞭20多天瞭,昨天才好瞭。我要做技術專傢,我想任何技能的提升一定要和大傢切磋,所以這個我會堅持下去瞭,但是真的沒時間我也沒法子瞭哈。

  喜歡做軟件,就應該當做愛好,不管什麼堅持不堅持,你真喜歡它不用想堅持也能堅持瞭。

摘自 夏天的森林

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *