一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

向高級Javascript程序員陣營邁進(jìn):Javascript一些概念研究總結(jié)

  習(xí)慣于OOP語言編程后,會(huì)發(fā)現(xiàn)Javascript世界有很多匪夷所思的奇奇怪怪的現(xiàn)象(比如閉包),我花了大量的精力研究這些奇怪現(xiàn)象的根源,最后發(fā)現(xiàn):源自于Javascript的作用域不是塊級作用域,同時(shí)它有一套基于作用域鏈的標(biāo)識查找機(jī)制。本文大部分內(nèi)容來自互聯(lián)網(wǎng),經(jīng)過整理、改進(jìn)而成。

  • Javascript引擎和DOM采用的垃圾回收算法:引用計(jì)數(shù)
    Javascript和DOM有各自的垃圾回收器,單獨(dú)運(yùn)作良好,合作時(shí)一不小心會(huì)出問題。引用計(jì)數(shù)這個(gè)算法的缺陷就是:Javascript 對象和DOM對象彼此循環(huán)引用,造成彼此的引用計(jì)數(shù)永遠(yuǎn)不能為0,垃圾回收器無法正確回收這些參與循環(huán)引用的對象,最終造成內(nèi)存泄漏(Memory Leak)。閉包是循環(huán)引用“大戶”。如果對垃圾回收感興趣,可以看看 垃圾收集趣史
  • 詞法作用域(lexical scope,一般簡稱作用域)、with/eval
    簡單來說Javascript的作用域是由function劃分的。讀完這篇文章你會(huì)了解詞法作用域 Javascript運(yùn)行機(jī)制淺探,with/eval這 兩個(gè)特例會(huì)擾亂作用域,即所謂動(dòng)態(tài)作用域(dynamic scope)
  • 作用域鏈(Scope Chain) 和 標(biāo)識查找機(jī)制
    作用域鏈?zhǔn)且粋€(gè)鏈表(數(shù)據(jù)結(jié)構(gòu)),它是Javascript的靈魂,只有理解了它才能理解Javascript世界奇奇怪怪的現(xiàn)象。作用域鏈由活動(dòng)對象鏈成。
    標(biāo)識查找機(jī)制稍后結(jié)合函數(shù)執(zhí)行的原理加以說明。 
  • 活動(dòng)對象(call object)
    國內(nèi)很多人稱之為調(diào)用對象(call object),本文用英文call obejct(但我私下認(rèn)為翻譯為"活動(dòng)對象"更好,不至于和this所指的對象混淆。)
    非常特殊的Javascript引擎內(nèi)的對象,ECMAScript規(guī)范術(shù)語稱之為activation object(活動(dòng)對象)。多個(gè)call object和全局對象組成作用域鏈(scope chain )
  • 函數(shù)的本質(zhì)(有名函數(shù)、匿名函數(shù))、函數(shù)的[[scope]]屬性   函數(shù)在Javascript里面是一個(gè)特殊的引用類型 ,它繼承于位于Javascript世界最頂端的object,類型是Function,是其他常見引用類型的構(gòu)造函數(shù)的所屬類型。
      在定義函數(shù)的時(shí)候,Javascript引擎會(huì)為function對象的一個(gè)私有[[scope]]屬性賦值,理論上只有js引擎自己才能訪問(也即:一般情況下無法通過語法來訪問,但Firefox下有一個(gè)__parent___可以訪問到)。匿名函數(shù)的[[scope]]屬性指向匿名函數(shù)定義時(shí)的上下文對象;有名函數(shù)除了和匿名函數(shù)一樣,還會(huì)在[[scope]]屬性的頂端再指向一個(gè)Javascript對象(繼承自obejct.prototype),這個(gè)對象被鏈接到函數(shù)定義時(shí)的Scope Chain,他本身帶有一個(gè)屬性就是函數(shù)的名字,這確保函數(shù)內(nèi)部的代碼可以無誤地訪問到自己的函數(shù)名以便進(jìn)行遞歸。
      當(dāng)定義函數(shù)的時(shí)候,Javascript解析器會(huì)將函數(shù)的作用域鏈(scope chain)設(shè)置為定義函數(shù)時(shí)函數(shù)所在的“環(huán)境”,如果函數(shù)是一個(gè)全局函數(shù),則scope chain中只有window對象。
      當(dāng)執(zhí)行函數(shù)時(shí)的微觀世界,請看稍后的說明。
  • 閉包(closure)
    Javascript所有的函數(shù)都是閉包,但是只有嵌套形式的閉包(也是我們經(jīng)常討論的形式)才能體現(xiàn)這個(gè)Javascript 特性的強(qiáng)大。推薦閱讀這篇文章:
    深入理解JavaScript閉包(closure) 
  • 函數(shù)執(zhí)行時(shí)的作用域鏈和活動(dòng)對象是如何形成的及與閉包的關(guān)系
    1、Javascript解析器啟動(dòng)時(shí)就會(huì)初始化建立一個(gè)全局對象global object,這個(gè)全局對象就 擁有了一些預(yù)定義的全局變量和全局方法,如Infinity, parseInt, Math,所有程序中定義的全局變量都是這個(gè)全局對象的屬性。在客戶端Javascript中,Window就是這個(gè)Javascript的全局對象。

    2、當(dāng)Javascript執(zhí)行一個(gè)function時(shí),會(huì)生成一個(gè)對象,稱之為call object,function中的局部變量和function的參數(shù)都成為這個(gè)call object的屬性,以免覆寫同名的全局變量。

    3、Javascript解析器每次執(zhí)行function時(shí),都會(huì)為此function創(chuàng)建一個(gè)execution context執(zhí)行環(huán)境,在此function執(zhí)行環(huán)境中最重要的一點(diǎn)就是function的作用域鏈scope chain,這是一個(gè)對象鏈,由全局對象和活動(dòng)對象構(gòu)成,對象鏈具體構(gòu)成過程見下面說明。

    4、標(biāo)識的查找機(jī)制:當(dāng)Javascript查詢變量x的值時(shí),就會(huì)檢查此作用域鏈中第一個(gè)對象,可能是function的call object或全局對象(比如window),如果對象中有定義此x屬性,則返回值,不然檢查作用域鏈中的下一個(gè)對象是否定義x屬性,在作用域鏈中沒有找到,最后返回undefined。

    5、當(dāng)Javascript執(zhí)行一個(gè)function時(shí),它會(huì)先將此function定義時(shí)的作用域作為其作用域鏈,然后創(chuàng)建一個(gè)活動(dòng)對象(call object),置于作用域鏈的頂部,function的參數(shù)及內(nèi)部var聲明的所有局部變量都會(huì)成為此調(diào)用對象的屬性。

    6、this關(guān)鍵詞指向方法的調(diào)用者,而不是以調(diào)用對象的屬性存在,同一個(gè)方法中的this在不同的function調(diào)用中,可能指向不同的對象。

    7、The Call Object as a Namespace。將活動(dòng)對象當(dāng)作命名空間使用,避免命名污染。
    (function() {
    // 在方法體內(nèi)用var聲明的所有局部變量,都是以方法調(diào)用時(shí)創(chuàng)建的活對象的屬性形式 存在。
    // 這樣就避免與全局變量發(fā)生命名沖突。
    })();

    8、Javascript中所有的function都是一個(gè)閉包,但只有當(dāng)一個(gè)嵌套函數(shù)被導(dǎo)出到它所定義的作用域外時(shí),這種閉包才強(qiáng)大。如果理解了閉包,就會(huì)理解function執(zhí)行時(shí)的作用域鏈和活動(dòng)對象,才能真正掌握Javascript。

    9、嵌套閉包的微觀世界:在嵌套閉包時(shí),當(dāng)內(nèi)部函數(shù)的引用被保存到嵌套閉包之外一個(gè)全局變量或者一個(gè)對象的屬性時(shí),在這種情況下,此內(nèi)部函數(shù)有一個(gè)外部引用,并且在其外圍調(diào)用函數(shù)的活動(dòng)對象中有一個(gè)屬性指向此內(nèi)部函數(shù)。因?yàn)橛衅渌麑ο笠么藘?nèi)部函數(shù),所以在外圍函數(shù)被調(diào)用一次后,其創(chuàng)建的活動(dòng)對象會(huì)繼續(xù)存在,并不會(huì)被垃圾回收器回收(因?yàn)橐糜?jì)數(shù)不為0),內(nèi)部函數(shù)的參數(shù)和局部變量都會(huì)在這個(gè)活動(dòng)對象中得以維持,Javascript代碼任何形式都不能直接訪問此活動(dòng)對象,但是此活動(dòng)對象是內(nèi)部函數(shù)被調(diào)用時(shí)創(chuàng)建的作用域鏈的一部分,可以被內(nèi)部函數(shù)訪問并修改。 

最后介紹一個(gè)奇怪現(xiàn)象:下面的代碼,為什么鼠標(biāo)移動(dòng)到li上,title總是6,而不是我們所預(yù)想的數(shù)字呢?看你能不能根據(jù)以上的知識,解釋這種現(xiàn)象的原因。提示:變量查找機(jī)制。

 

<html>  
<head>  
    
<title>循環(huán)內(nèi)的閉包 應(yīng)該謹(jǐn)慎title>  
head>  
<body>  
<ul id="list">  
<li>第1條記錄li>  
<li>第2條記錄li>  
<li>第3條記錄li>  
<li>第4條記錄li>  
<li>第5條記錄li>  
<li>第6條記錄li>  
ul>  
<script type="text/Javascript">
    
var list_obj = document.getElementById("list").getElementsByTagName("li"); //獲取list下面的所有l(wèi)i的對象數(shù)組
    for (var i = 0; i <= list_obj.length; i++) {
            list_obj[i].onmousemove 
= function() {
                
this.style.backgroundColor = "#eee";
                document.title
=i
            };
            list_obj[i].onmouseout 
= function() {
                
this.style.backgroundColor = "#fff";
            }
    }
<.script>  
body>  
html>  

it知識庫向高級Javascript程序員陣營邁進(jìn):Javascript一些概念研究總結(jié),轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 久久久久国产一级毛片高清板 | 尤物网址在线观看日本 | 色五月在线视频 | 国产日产欧产精品推荐推荐 | 91精品国产91久久久久福利 | 在线观看免费视频网站色 | 在线观看视频网站www色 | 人人干在线观看 | 久久成年人视频 | 亚洲黄色在线观看 | 在线综合网 | 四虎影视国产精品一区二区 | 香蕉一区二区三区观 | 亚洲一区二区三区中文字幕 | 欧美高清强视频 | 五月六月丁香 | 麻豆亚洲| 成人综合激情 | 亚洲欧美色鬼久久综合 | 国产区更新 | 美女网站黄在线看 | 91麻豆精品国产91久久久久久 | 二区三区在线 | 国内精品久久久久影院不卡 | 91热视频 | www欧美在线观看 | 中文字幕在线观看日韩 | 国产熟睡乱子伦视频观看看 | 国内精品中文字幕 | 国产欧美一区二区三区观看 | 精品国内自产拍在线视频 | 亚洲精品成人网 | 国内精品小视频在线 | 成人免费观看视频高清视频 | 在线亚洲播放 | 日本一区二区三区中文字幕 | 九色国产在视频线精品视频 | 亚洲区小说区图片区qvod伊 | 深爱激动网婷婷狠狠五月 | 欧美人禽猛交狂配免费看 | 黄色日韩网站 |