摘要:作用域鏈的用途,是保證對執(zhí)行環(huán)境有權(quán)訪問的變量和函數(shù)的有序訪問。全局執(zhí)行環(huán)境始終是作用域鏈的最后一個對象。延長作用域鏈雖然執(zhí)行環(huán)境的類型只有兩種。
基本類型和引用類型最近在忙于寫一個react+node的全棧博客demo,沒有時間更新文章。但是還是覺得這樣一忙起來不更新是不應(yīng)該的。正好在空閑上下班地鐵上都會再去細(xì)讀js原生知識。所以打算整理、總結(jié)、系統(tǒng)性的分享給大家。
在ECMAScript中,變量分為基本類型和引用類型兩種。
基本類型就是存儲簡單的數(shù)據(jù)段。而引用類型指的是那些可能由多個值構(gòu)成的對象。
在ECMAScript中,基本類型包括:Undefined、Null、Boolean、Number和String。
這些基本類型的對象都是按值訪問的。所以js中我們可以直接操作他們。
但是引用類型如Object等,是按照引用來操作的。并非直接操作其值。
并且我們可以動態(tài)的為引用類型變量添加屬性和方法。而基本類型則不可以。
這里其實對于基本類型來說沒有什么需要重點說明的。這里就重點說下引用類型吧
對于賦值
function setName(obj) { obj.name = "Neal"; obj = new Object(); obj.name = "yang"; } var person = new Object(); setName(person); console.log(person.name);
如上代碼,最后console出來的是Neal。
這段代碼說明兩點:
引用類型在傳參的時候,是按照引用傳遞的,不然不可能person.name為Neal
即使在函數(shù)內(nèi)部修改了參數(shù)的值。原始的引用依然不變。實際上,在重寫obj的時候,這個變量的引用已經(jīng)是一個局部變量了。只是在這兒函數(shù)運行完,這個對象被銷毀了。
所以說到這,對于對象的賦值,一句以概之:引用的賦值。
執(zhí)行環(huán)境及其作用域這大概是一個非常基礎(chǔ)也是重要的部分,后續(xù)會在進(jìn)階里面詳細(xì)展開。
執(zhí)行環(huán)境定義了變量或者函數(shù)有權(quán)訪問的其他數(shù)據(jù),決定了他們的行為。每一個執(zhí)行環(huán)境都有一個與之關(guān)聯(lián)的變量對象(如global、window)。環(huán)境中定義的所有變量和函數(shù)都保存在這個對象中。
某一個執(zhí)行環(huán)境執(zhí)行完畢后,該環(huán)境會被銷毀。其中的所有的變量和函數(shù)也將隨之銷毀。全局執(zhí)行環(huán)境知道應(yīng)用程序退出才被銷毀(如關(guān)閉網(wǎng)頁等)
當(dāng)代碼在一個環(huán)境中執(zhí)行的時候,會創(chuàng)建變量對象的一個作用域鏈。作用域鏈的用途,是保證對執(zhí)行環(huán)境有權(quán)訪問的變量和函數(shù)的有序訪問。作用域鏈的前端,始終是當(dāng)前執(zhí)行的代碼所在的
環(huán)境的變量對象。全局執(zhí)行環(huán)境始終是作用域鏈的最后一個對象。
標(biāo)識符的解析也就是沿著作用域鏈一級一級的搜索的過程。搜索過程從作用域鏈的前端開始,然后逐級向后回溯。知道找到標(biāo)識符為止。
var color = "red"; function changeColor() { var anotherColor = "blue"; function swapColors() { var tempColor = anotherColor; anotherColor = color; color = tempColor; //這個執(zhí)行環(huán)境中可以訪問到 tempColor color antherColor } //這里只能訪問anotherColor color swapColors(); } changeColor();//這里只能訪問color
所以從上面代碼我們可以感受到:內(nèi)部環(huán)境可以通過作用域鏈訪問到外部環(huán)境的變量。反之不可。這些環(huán)境之間的聯(lián)系都是線性、有次序的。
延長作用域鏈雖然執(zhí)行環(huán)境的類型只有兩種。局部的和全局的。但是還有一種方法可以延長作用域鏈。
這是因為有些語句可以在作用域鏈的前端臨時添加一個變量對象,改變量對象會在代碼執(zhí)行后被移除。
try-catch 語句中的catch
with語句
對于width語句而言,會將指定的對象添加到作用域鏈中。對于catch語句而言,會創(chuàng)建一個新的變量對象,其中包含被拋出的錯誤對象的申明。
關(guān)于作用域、環(huán)境之類的話題后續(xù)會再細(xì)說。這里作為基礎(chǔ)篇,就先介紹到這里。
垃圾收集很開心~js不需要你來收拾垃圾!好~此篇完結(jié)!
好吧~雖然我們不收拾垃圾,但是也是要稍微了解下js是如何收拾垃圾的。
首先什么是垃圾:哪些不再被繼續(xù)使用的變量都是垃圾。什么叫收拾?釋放起垃圾所占用的空間即為釋放。
局部變量只在函數(shù)執(zhí)行過過程中存在。而在這個過程中,會為局部變量在?;蛘叨阎蟹峙湎鄳?yīng)的內(nèi)存空間(存值唄)。然后函數(shù)執(zhí)行啦,用了這些變量,執(zhí)行完啦。完啦!則這些變量就沒有用了。沒用了,則為垃圾,既需清理。
但是并非所有的情況下都這么容易的得出結(jié)論。垃圾收集器必須跟蹤哪個變量用了哪個變量沒用。對于不在利用的打上標(biāo)記,已被將來收回其所占用的內(nèi)存。
標(biāo)記清除這是最為常用一種清除方式。當(dāng)一個變量進(jìn)入到環(huán)境的時候,標(biāo)記為‘進(jìn)入環(huán)境’,這個基本是不會被清除的,因為執(zhí)行流進(jìn)入到相應(yīng)的環(huán)境的時候可能會用到。當(dāng)變量離開環(huán)境的時候,標(biāo)記為‘離開環(huán)境’。
可以使用任何方式來標(biāo)記。我們要知道是如何標(biāo)記不重要,重要的是采用什么策略。
垃圾收集器在運行的時候會給存儲在內(nèi)存中的所有變量都加上標(biāo)記。他會去掉環(huán)境中的變量以及被環(huán)境中的變量所引用的變量的標(biāo)記。剩下的,則視為嫌疑人,準(zhǔn)備刪除。因為環(huán)境中的變量已經(jīng)無法訪問到這些變量了。目前IE、ff 、 opera 、 chrome都是這種標(biāo)記清除方式
引用計數(shù)因為不常用,簡單說下
引用計數(shù)的意思就是跟蹤記錄每一個值被引用的次數(shù)。當(dāng)一個引用類型的變量復(fù)制給一個變量的時候,這個引用次數(shù)則+1,如果有別復(fù)制給另一個變量,則再+1,如果包含對這個值的引用的變量又被賦值了別的值。則這個值-1.
當(dāng)引用次數(shù)為0的時候,為垃圾~回收!
為什么不常用呢?看著也很清晰?。?/p>
look code:
function test() { var objectA = new Object(); var objectB = new Object(); objectA.someOtherObject = objectB; objectB.someOtherObject = objectA; }
如上,對象A和對象B的屬性互相引用。也就是說,這兩個對象的引用次數(shù)永遠(yuǎn)都是2.哪怕這個函數(shù)執(zhí)行完咯,也沒法清理的。對的,這就是bug~
節(jié)制點~你懂得雖然垃圾回收機(jī)制幫我們做了很多事,但是電腦分配給瀏覽器的可用內(nèi)存通常要比桌面應(yīng)用的內(nèi)存要小的多,畢竟是為了防止運行js的網(wǎng)頁耗盡所有的內(nèi)存而導(dǎo)致系統(tǒng)崩潰的問題發(fā)生。
所以我們確保用最少的內(nèi)存可以讓頁面獲取最好的性能,最佳的執(zhí)行方案就是執(zhí)行中的代碼都是有必要的數(shù)據(jù)。就好比用最低的經(jīng)濟(jì)拿最多的人頭一樣,一旦經(jīng)濟(jì)不夠,技術(shù)彌補!一旦數(shù)據(jù)不要用了,自己主動掃除。
function createPerson(name) { var localPerson = new Object(); localPerson.name = name; return localPerson; } var neal = createPerson("Neal"); //主動清理垃圾 createPerson = null;
這里講createPerson設(shè)置為null,并沒有就把他給清除了,只是釋放了他的引用。讓其脫離其執(zhí)行環(huán)境,以便于垃圾收集器更快的將其回收。
微信公眾號:前端的全棧之路歡迎大家訂閱~更多原創(chuàng)文章整理(js、react)
一起交流~一起進(jìn)步~
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/88694.html
摘要:作用域分類作用域共有兩種主要的工作模型。換句話說,作用域鏈?zhǔn)腔谡{(diào)用棧的,而不是代碼中的作用域嵌套。詞法作用域詞法作用域中,又可分為全局作用域,函數(shù)作用域和塊級作用域。 一篇鞏固基礎(chǔ)的文章,也可能是一系列的文章,梳理知識的遺漏點,同時也探究很多理所當(dāng)然的事情背后的原理。 為什么探究基礎(chǔ)?因為你不去面試你就不知道基礎(chǔ)有多重要,或者是說當(dāng)你的工作經(jīng)歷沒有亮點的時候,基礎(chǔ)就是檢驗?zāi)愫脡牡囊豁?..
摘要:在及之前版本,只擁有函數(shù)作用域,沒有塊作用域和除外。函數(shù)表達(dá)式分為匿名函數(shù)表達(dá)式和具名函數(shù)表達(dá)式。但是,由于這個事件回調(diào)函數(shù)形成了一個覆蓋當(dāng)前作用域的閉包,引擎極有可能依然保存著這個數(shù)據(jù)結(jié)構(gòu)取決于具體實現(xiàn)??偨Y(jié)函數(shù)是中最常見的作用域單元。 在 ES5 及之前版本,JavaScript 只擁有函數(shù)作用域,沒有塊作用域(with 和 try...catch 除外)。在 ES6 中,JS 引...
摘要:可實現(xiàn)單例模式代碼塊初始化靜態(tài)變量,只被執(zhí)行一次內(nèi)部類不能與外部類重名,只能訪問外部類靜態(tài)數(shù)據(jù)包括私有多分支選擇整型或字符類型變量或整數(shù)表達(dá)式開始支持。 前言 大學(xué)期間接觸 Java 的時間也不短了,不論學(xué)習(xí)還是實習(xí),都讓我發(fā)覺基礎(chǔ)的重要性?;ヂ?lián)網(wǎng)發(fā)展太快了,各種框架各種技術(shù)更新迭代的速度非常快,可能你剛好掌握了一門技術(shù)的應(yīng)用,它卻已經(jīng)走在淘汰的邊緣了。 而學(xué)習(xí)新技術(shù)總要付出一定的時間...
摘要:具體來說就是當(dāng)執(zhí)行流進(jìn)入下列任何一個語句時,作用域鏈就會得到加長語句的塊和語句。這兩個語句都會在作用域鏈的前端添加一個變量對象。對來說,會將指定的對象添加到作用域鏈中。 1. 基本類型和引用類型的值 JavaScript變量可以用來保存兩種類型的值:基本類性值和引用類性值。基本類型值源自以下5種基本數(shù)據(jù)類型:Undefined、Null、Boolean、Number和String。基本...
摘要:查詢是在作用域鏈中,一級級的往上查找該變量的引用。作用域和作用域鏈作用域的概念,應(yīng)該兩張圖幾句話就能解釋吧。這個建筑代表程序中的嵌套作用域鏈。一層嵌一層的作用域形成了作用域鏈,變量在作用域鏈中的函數(shù)內(nèi)得到了自己的定義。 javascript作用域和閉包之我見 看了《你不知道的JavaScript(上卷)》的第一部分——作用域和閉包,感受頗深,遂寫一篇讀書筆記加深印象。路過的大牛歡迎指點...
閱讀 3214·2021-10-14 09:42
閱讀 3574·2019-08-26 13:56
閱讀 3489·2019-08-26 11:59
閱讀 955·2019-08-23 18:00
閱讀 2218·2019-08-23 17:51
閱讀 3537·2019-08-23 17:17
閱讀 1490·2019-08-23 15:11
閱讀 5227·2019-08-23 15:05