摘要:塊狀作用域提起中的關(guān)鍵字,第一個(gè)想法就是塊狀作用域。而如果通過(guò)這些關(guān)鍵詞聲明的,那么也就會(huì)聲明到所在的作用域中。終于回到可以將變量綁定到所在的任意作用域中,通常是內(nèi)部。避免不必要的出現(xiàn)。
讀<你不知道的javascript>,想到哪里寫到哪里。。。
塊狀作用域提起ES6中的let關(guān)鍵字,第一個(gè)想法就是塊狀作用域。
說(shuō)到作用域,以前提及的都是全局作用域和函數(shù)作用域。當(dāng)進(jìn)行作用域查找的時(shí)候,永遠(yuǎn)是一層一層往上查找,直到找到第一個(gè)匹配的標(biāo)示符時(shí)停止。
全局作用域就是整個(gè)作用域的最上層,當(dāng)進(jìn)行作用域查找的時(shí)候,全局作用域永遠(yuǎn)是最上一層,如果在全局作用域中依然無(wú)法找到,那么就會(huì)拋出referenceError。
而說(shuō)到函數(shù)作用域,曾經(jīng)讀過(guò)一本書上面說(shuō)到一個(gè)詞“隱藏”變量和函數(shù)定義,覺(jué)得很貼切。把東西隱藏在函數(shù)中,避免污染外部作用域的同時(shí),可以有效地進(jìn)行模塊化管理。
回到塊狀作用域,除了let,另外一個(gè)with關(guān)鍵字也創(chuàng)造了一個(gè)塊狀作用域。
function foo(obj) { var c = 6; with(obj) { a = b; c = 5; var d = 7; let e = 8; } console.log(c); // 5 console.log(d); // 7 console.log(e); // referenceError } var obj = { a:1, b:2 }; foo(obj);
我們都知道其中的a和b的作用域查找(LHS, RHS)都是在obj中找到。而如果無(wú)法再obj中找到,那么就會(huì)向上作用域繼續(xù)找,這里的c就會(huì)找到foo函數(shù)中的c。而如果通過(guò)var這些關(guān)鍵詞聲明的,那么也就會(huì)聲明到with所在的作用域中。
對(duì)于with,就相當(dāng)于在外面又包了一層作用域,里面包含提供對(duì)象中的所有屬性。
終于回到let, let可以將變量綁定到所在的任意作用域中,通常是{}內(nèi)部。沒(méi)了。。。
提升和var聲明變量和函數(shù)聲明,let不會(huì)進(jìn)行提升??纯聪旅娴膸讉€(gè)例子:
console.log(a); // referenceError let a = 1;
console.log(b); // undefined; var b = 1;
foo(); // 3 function foo(){ console.log("3") }
foo(); // type error var foo = function(){ console.log("4") }
foo(); // referenceError let foo = function(){ console.log("5") }
說(shuō)到提升,提一句:“函數(shù)會(huì)首先被提升,然后才是變量”。像之前的書里的一個(gè)例子:
bar(); // 3 function bar(){ console.log(1) }; var bar = function(){ console.log(2) }; function bar(){ console.log(3) }
提升以后看起來(lái)就像:
function bar(){ console.log(1) }; function bar(){ console.log(3) }; bar(); // 3 bar = function(){ console.log(2) };
這里需要提一句,var bar這一段由于bar在之前已經(jīng)被聲明過(guò)了,所以這里var bar會(huì)被忽略,而不是把bar設(shè)為null。
說(shuō)到提升,還有一種特殊的情況,雖然不建議這么寫,但是肯定會(huì)有人會(huì)踩到雷:
var a = true; if(a) { function foo(){ console.log(1) } } else { function foo(){ console.log(2) } } foo();
原書中說(shuō)這種情況,由于提升,所以會(huì)輸出2,而不是我們想要的1。但是我在chrome和firefox中試了一下,會(huì)按照想要的輸出1。而在IE11中,卻輸出的是2。
所以,很明顯,chrome和firefox對(duì)這種情況作了優(yōu)化,但是還是有瀏覽器的差別,所以盡量不要這么聲明函數(shù)。避免不必要的bug出現(xiàn)。
垃圾收集當(dāng)使用閉包的時(shí)候,會(huì)造成一部分的內(nèi)存不會(huì)進(jìn)行釋放。這是閉包的好處,也是閉包的壞處。好處就是我們可以在外部使用這個(gè)變量,而壞處就是有些不需要的變量也不會(huì)被釋放。
一個(gè)簡(jiǎn)單的閉包:
function Foo(){ var a = [....]; // .....和a做些互動(dòng) var b = 0; return function(){ return b++; } }
這里在閉包中,我們其實(shí)只需要保存b的內(nèi)存就好,而a是不需要的。按照理想情況,a在Foo結(jié)束后就可以垃圾回收了(GC)。然而引擎有可能會(huì)保存著這個(gè)東西(取決于具體實(shí)現(xiàn)--你不知道的javascript),這就造成了內(nèi)存的浪費(fèi)。
那么就可以使用let塊狀作用域的特性,進(jìn)行處理:
function Foo(){ { let a = [....]; // ....和a做些互動(dòng) } var b = 0; return function(){ return b++; } }
這里,由于a的作用域只在{}中,所以當(dāng){}結(jié)束后就會(huì)釋放a的內(nèi)存,而不是長(zhǎng)久占有內(nèi)存。
循環(huán)這里只寫出一個(gè)很有意思的觀點(diǎn)。
我們都知道在循環(huán)中用let可以解決某個(gè)老生常談的問(wèn)題。但是總是轉(zhuǎn)變不過(guò)來(lái),為什么會(huì)解決這個(gè)問(wèn)題。
var a = []; for(var i = 0; i < 10; i++) { a[i] = function(){ console.log(i) }; } a[3](); // 10
var a = []; for(let i = 0; i < 10; i++) { a[i] = function(){ console.log(i) }; } a[3](); // 3
所以到底let做了什么神奇的事情,解決了這個(gè)問(wèn)題?
書中說(shuō)了一句話:
for循環(huán)頭部的let不僅將i綁定到了for循環(huán)的塊中,事實(shí)上它將其重新綁定到了循環(huán)的每一個(gè)迭代中,確保使用上一個(gè)循環(huán)迭代結(jié)束時(shí)的值重新進(jìn)行賦值。
然后給了一個(gè)等價(jià)的例子,一目了然:
var a = []; { let j; for(j=0; j<10;j++){ let i = j; // 每個(gè)迭代重新綁定 a[i] = function(){ console.log(i) }; } } a[3](); // 3
最后啰嗦一句,const這個(gè)關(guān)鍵詞,也是塊狀作用域,也是不提升。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/82421.html
摘要:前面不短時(shí)間持續(xù)投入了時(shí)間在做應(yīng)用架構(gòu)方面的考量一個(gè)是冒險(xiǎn)進(jìn)行了一次應(yīng)用架構(gòu)的調(diào)整另一個(gè)是跟進(jìn)了的進(jìn)展當(dāng)然實(shí)際上是同一個(gè)事情也許錯(cuò)過(guò)的比收獲的還多一些不過(guò)能走到現(xiàn)在也算幸運(yùn)了畢竟單頁(yè)面應(yīng)用還面臨很多不成熟之處國(guó)慶長(zhǎng)假過(guò)去不少現(xiàn)在的想法估計(jì)會(huì) 前面不短時(shí)間持續(xù)投入了時(shí)間在做 React 應(yīng)用架構(gòu)方面的考量一個(gè)是冒險(xiǎn)進(jìn)行了一次應(yīng)用架構(gòu)的調(diào)整, 另一個(gè)是跟進(jìn)了 Redux 的進(jìn)展當(dāng)然, 實(shí)際...
摘要:背景如圖所示馮諾依曼計(jì)算機(jī)體系結(jié)構(gòu)由于最近做業(yè)務(wù)需求做到發(fā)瘟借此發(fā)散一下思維最近業(yè)務(wù)需求的痛點(diǎn)如下基礎(chǔ)代碼骨架已固定業(yè)務(wù)流程固定然而業(yè)務(wù)中產(chǎn)品的配置需要非常靈活并且有可能需要跨過(guò)某段業(yè)務(wù)流程直接執(zhí)行下一段直接方案當(dāng)然是能夠決定條件分支的但架 showImg(https://segmentfault.com/img/bVbrHbo?w=1920&h=981); 背景 如圖所示, 馮諾依曼...
摘要:例如,代碼傾向于使用駝峰命名,因此使用編寫代碼可以提供流暢的感覺(jué)這就可以起到可讀性的作用。這將極大地幫助你提高代碼的可讀性,因?yàn)槟闶紫葟睦斫忾_(kāi)始,然后轉(zhuǎn)向性能。 原文:https://www.codecasts.com/blo... 本文探討編程中的一個(gè)術(shù)語(yǔ):可讀性。 首先我們來(lái)談?wù)勊暮x: 可讀性是描述在其他開(kāi)發(fā)人員沒(méi)有進(jìn)行太多聯(lián)想或猜測(cè)的情況下就能理解代碼的含義。為了讓其他的開(kāi)...
摘要:例如,代碼傾向于使用駝峰命名,因此使用編寫代碼可以提供流暢的感覺(jué)這就可以起到可讀性的作用。這將極大地幫助你提高代碼的可讀性,因?yàn)槟闶紫葟睦斫忾_(kāi)始,然后轉(zhuǎn)向性能。 原文:https://www.codecasts.com/blo... 本文探討編程中的一個(gè)術(shù)語(yǔ):可讀性。 首先我們來(lái)談?wù)勊暮x: 可讀性是描述在其他開(kāi)發(fā)人員沒(méi)有進(jìn)行太多聯(lián)想或猜測(cè)的情況下就能理解代碼的含義。為了讓其他的開(kāi)...
閱讀 2083·2021-09-22 15:54
閱讀 1844·2021-09-04 16:40
閱讀 869·2019-08-30 15:56
閱讀 2632·2019-08-30 15:44
閱讀 2159·2019-08-30 13:52
閱讀 1132·2019-08-29 16:35
閱讀 3352·2019-08-29 16:31
閱讀 2571·2019-08-29 13:48