闭包、执行环境、作用域链
生活随笔
收集整理的這篇文章主要介紹了
闭包、执行环境、作用域链
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
閉包是指有權訪問另一個函數作用域中的變量的函數,創建的常見方式就是在一個函數內部創建另一個函數。
我們來理解下執行環境和作用域鏈: 1.執行環境有全局執行環境和函數執行環境之分。 2.每次進入一個新的執行環境,都會創建一個用于搜索變量和函數的作用域鏈。 3.函數的局部環境不僅有權訪問函數作用域中的變量,而且有權訪問其包含(父)環境,由底向上乃至全局環境。 4.變量的執行環境有助于確定應該何時釋放內存。
執行環境和作用域鏈 function createComparisonFunction(propertyName){ ? ? ?return function(object1,object2){ ? ? ?var value1=object1[propertyName]; ? ?? var value2=object2[propertyName]; ? ? ? ? ? ?if(value<value2){ ? ?? ?????return -1; ?????}else if(value1>value2){ ? ? ? ? ? retutn 1;? ?????}else{ ? ? ? ? ?return 0;? ?????} ?????}; } //創建函數 var compareNames=createComparisonFunction("name"); //調用函數 var result=compareNames({name:"joey"},{name:"ross"}); //接觸對匿名函數的引用,用于釋放內存 compareNames=null; 因為只是用于自己加強理解,就直接把圖片放在這里了,因為用于文字實在很難描述出來作用域鏈的關系。 值得一提的是,每個執行環境都有表示變量的對象--變量對象,全局環境中的變量對象始終存在,而內部函數的局部環境變量則只在函數執行過程中存在。 而在這個例子中,createComparisonFunction()的作用域鏈包含兩個變量對象,一個本身的活動對象,一個全局變量對象,而匿名函數的作用域鏈包含著三個對象變量,多了一個自身的閉包活動對象,外面訪問不進來,里面卻可以訪問外面,所以也包含外部函數的活動對象和全局變量對象,重要的是,當外部函數執行完畢之后,它的活動對象也不會被銷毀,因為匿名函數的作用域鏈接仍然在引用這個活動對象,換句話說,外部函數返回后,其執行環境會銷毀,但是它的活動對象依然留在內存中,知道匿名函數被銷毀,外部函數的活動對象才會被銷毀。
閉包與變量 function create(){ var result=new Array(); for(var i=0; i<10, i++){ result[i]=function(){ return i ; } } } //藍色的全局變量對象,紅色的是create()函數活動對象,綠色的閉包的活動對象。
作用域鏈的這種配置機制引出一個值得注意的副作用,閉包只能取得包含函數中任何變量的最后一個值。 上面這句話是重點,這個代碼我起初沒看懂的,反復理解了之后才懂,這個函數會返回一個函數數組,[0(),1().....9()],從0到9,而函數返回的 i ?值應該對應函數名稱,即是0()里面返回0,1()里面返回1,以此類推,實際上每個函數返回的都是10,因為 create()這個函數的作用域鏈保存這這個函數的活動對象,活動對象有result,還有i,函數調用后,變量 i 的值已經是10,并且保存在活動對象里,此時閉包去引用的都是同一個 i 。
我們來理解下執行環境和作用域鏈: 1.執行環境有全局執行環境和函數執行環境之分。 2.每次進入一個新的執行環境,都會創建一個用于搜索變量和函數的作用域鏈。 3.函數的局部環境不僅有權訪問函數作用域中的變量,而且有權訪問其包含(父)環境,由底向上乃至全局環境。 4.變量的執行環境有助于確定應該何時釋放內存。
執行環境和作用域鏈 function createComparisonFunction(propertyName){ ? ? ?return function(object1,object2){ ? ? ?var value1=object1[propertyName]; ? ?? var value2=object2[propertyName]; ? ? ? ? ? ?if(value<value2){ ? ?? ?????return -1; ?????}else if(value1>value2){ ? ? ? ? ? retutn 1;? ?????}else{ ? ? ? ? ?return 0;? ?????} ?????}; } //創建函數 var compareNames=createComparisonFunction("name"); //調用函數 var result=compareNames({name:"joey"},{name:"ross"}); //接觸對匿名函數的引用,用于釋放內存 compareNames=null; 因為只是用于自己加強理解,就直接把圖片放在這里了,因為用于文字實在很難描述出來作用域鏈的關系。 值得一提的是,每個執行環境都有表示變量的對象--變量對象,全局環境中的變量對象始終存在,而內部函數的局部環境變量則只在函數執行過程中存在。 而在這個例子中,createComparisonFunction()的作用域鏈包含兩個變量對象,一個本身的活動對象,一個全局變量對象,而匿名函數的作用域鏈包含著三個對象變量,多了一個自身的閉包活動對象,外面訪問不進來,里面卻可以訪問外面,所以也包含外部函數的活動對象和全局變量對象,重要的是,當外部函數執行完畢之后,它的活動對象也不會被銷毀,因為匿名函數的作用域鏈接仍然在引用這個活動對象,換句話說,外部函數返回后,其執行環境會銷毀,但是它的活動對象依然留在內存中,知道匿名函數被銷毀,外部函數的活動對象才會被銷毀。
閉包與變量 function create(){ var result=new Array(); for(var i=0; i<10, i++){ result[i]=function(){ return i ; } } } //藍色的全局變量對象,紅色的是create()函數活動對象,綠色的閉包的活動對象。
作用域鏈的這種配置機制引出一個值得注意的副作用,閉包只能取得包含函數中任何變量的最后一個值。 上面這句話是重點,這個代碼我起初沒看懂的,反復理解了之后才懂,這個函數會返回一個函數數組,[0(),1().....9()],從0到9,而函數返回的 i ?值應該對應函數名稱,即是0()里面返回0,1()里面返回1,以此類推,實際上每個函數返回的都是10,因為 create()這個函數的作用域鏈保存這這個函數的活動對象,活動對象有result,還有i,函數調用后,變量 i 的值已經是10,并且保存在活動對象里,此時閉包去引用的都是同一個 i 。
?
轉載于:https://www.cnblogs.com/Agrass/p/6595875.html
總結
以上是生活随笔為你收集整理的闭包、执行环境、作用域链的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (转)如何成为顶级生物信息学家?
- 下一篇: 打开页面默认弹出软键盘,同时兼容iOS和