一区二区久久-一区二区三区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)系我們修改或刪除,多謝。

主站蜘蛛池模板: 69热精品视频在线看影院 | 狠狠做五月深爱婷婷天天综合 | 欧美色欧美亚洲另类二区不卡 | 美女胸又大又www又黄的网站 | 国产熟睡乱子伦视频 | 一区二区三区中文 | 国产成人精品免费视频大全五级 | xxx亚洲日本 | 国产亚洲精品高清在线 | 日韩欧美一中文字幕不卡 | 亚洲影视一区二区 | 国产视频 一区二区 | 国产精品中文字幕在线观看 | 伊人色婷婷综在合线亚洲 | 久九九久福利精品视频视频 | 午夜激情免费 | 久久精品国产精品亚洲红杏 | 国产精品19禁在线观看2021 | 亚洲国产成人久久一区www | 成人看片黄a毛片 | 亚洲第一黄色网址 | 5g成人影院| 日本视频www | 国产精品99| 亚洲天堂黄色 | 在线播放色 | 久久久久网站 | 四虎4hu永久在线观看 | 丁香激情综合 | yellow中文字幕久久网 | 亚洲一区综合在线播放 | 日韩高清一区二区三区五区七区 | 中文字幕一二三区 | 欧美一级日韩一级亚洲一级 | 九九精品国产 | 亚洲免费精品视频 | 草草线在成人免费视频 | 深爱激动网婷婷狠狠五月 | 国产成人永久免费视 | 粉嫩国产精品14xxxxx | 丁香五婷婷 |