摘要:理解作用域作用域負(fù)責(zé)收集并維護(hù)由所有聲明的變量組成的集合,等待引擎的查找。當(dāng)遇到時,編譯器會詢問作用域是否存在變量。詞法作用域就是定義在詞法階段的作用域。但函數(shù)不是唯一的作用域單元。塊作用域?qū)儆谀硞€代碼塊通常指內(nèi)部。
理解作用域
作用域負(fù)責(zé)收集并維護(hù)由所有聲明的變量組成的集合,等待引擎的查找。
var a = 2; console.log(a); // 2 console.log(b); // ReferenceError: b is not defined
var a = 2 可以分解為var a; a = 2。當(dāng)遇到var a時,編譯器會詢問作用域是否存在變量a。如果存在,則忽略該聲明,否則會在當(dāng)前作用域的集合中聲明一個新的變量a。
遇到a = 2時,引擎會詢問當(dāng)前作用域是否存在變量,如果未找到,則會繼續(xù)在上級作用域查找。如果最終找到就會將2賦值給變量a。
console.log(a)時,引擎會去作用域中查找 a,找到把結(jié)果返回,輸出2, console.log(b)時,引擎未在作用域查找到b,拋出異常。
LHS和RHS查詢可以看出"L"和"R"分別代表左側(cè)和右側(cè),即賦值的左側(cè)和右側(cè)。賦值不只是=的賦值,函數(shù)參數(shù)的傳遞也是一種賦值操作。
var a = 2; // LHS查詢,a出現(xiàn)在賦值左側(cè) console.log(a); // RHS查詢, a出現(xiàn)在賦值右側(cè),將變量a賦值給參數(shù)
查詢失敗會出現(xiàn)什么情況
對于LHS查詢a = 2 若a未找到,在非嚴(yán)格模式下并不會報錯,而變量 a 會被自動創(chuàng)建。而對于 RHS 來說,直接使用未聲明的變量就會報 ReferenceError。
console.log(b); // ReferenceError: b is not defined詞法作用域
作用域主要有兩種工作模型:詞法作用域和動態(tài)作用域。
詞法作用域就是定義在詞法階段的作用域。換句話說,詞法作用域是由你寫代碼時變量和塊作用域?qū)懺谀臎Q定的。
function foo(a) { var b = a * 2; function bar(a) { console.log(a, b, c); } bar(b*3); } foo(2);
在這個例子有三個逐級嵌套的作用域。
全局作用域,包含一個標(biāo)識符:foo
foo所創(chuàng)建的作用域,包含三個標(biāo)識符:a, bar, b
bar所創(chuàng)建的作用域,包含一個標(biāo)識符:c
函數(shù)作用域函數(shù)作用域是指屬于這個函數(shù)的變量都可以在整個函數(shù)范圍內(nèi)使用和復(fù)用。
function fn() { var a = 2; console.log(a); // 2 } console.log(a); // ReferenceError: a is not defined
從中可以看出,函數(shù)外部將無法訪問函數(shù)內(nèi)部的變量。
塊作用域ES6引入let、const將變量綁定到所在塊作用域(通常是{...}內(nèi)部)
{ let a = 2; console.log(a); // 2 } console.log(a); // ReferenceError: a is not defined
除let、const外,with、try/catch的catch分句會創(chuàng)建一個塊作用域。
小結(jié)函數(shù)是Javascript中最常見的作用域單元。但函數(shù)不是唯一的作用域單元。塊作用域?qū)儆谀硞€代碼塊(通常指{...}內(nèi)部)。
接下來會講解提升和閉包兩個概念。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/105163.html
摘要:將作用域賦值給變量這里的作用域是,而不是將作用域賦值給一個變量閉包返回瀏覽器中內(nèi)存泄漏問題大家都知道,閉包會使變量駐留在內(nèi)存中,這也就導(dǎo)致了內(nèi)存泄漏。 上一章我們講了匿名函數(shù)和閉包,這次我們來談?wù)勯]包中作用域this的問題。 大家都知道,this對象是在運(yùn)行時基于函數(shù)的執(zhí)行環(huán)境綁定的,如果this在全局就是[object window],如果在對象內(nèi)部就是指向這個對象,而閉包卻是在運(yùn)行...
摘要:但是函數(shù)返回了內(nèi)部函數(shù),內(nèi)部函數(shù)會隨時訪問變量所以垃圾回收機(jī)制是不會回收函數(shù)的內(nèi)部作用域的,這就是閉包的含義。也就是函數(shù)在定義的詞法作用域以外的地方被調(diào)用,閉包使得函數(shù)可以繼續(xù)訪問定義時的詞法作用域。 初學(xué)JavaScript閉包時,閉包這個概念在我眼里及其的神秘,也不知道這個東西在講什么,尤其某些地方的閉包概念定義的非常抽象,屬于那種本來你可能明白這個概念,看了反而又把你給繞糊涂...
摘要:我們在面試時,總會碰到一些奇奇怪怪的關(guān)于作用域的面試題,其實弄清楚原理,萬變不離其宗,大部分的面試題都可以得姐。 showImg(https://segmentfault.com/img/bV7Cri?w=1563&h=879); 我們在面試時,總會碰到一些奇奇怪怪的關(guān)于 作用域 的面試題,其實弄清楚原理,萬變不離其宗,大部分的面試題都可以得 ‘姐’。 所以,今天我們來談?wù)?JavaS...
摘要:在內(nèi)部,理所當(dāng)然能訪問到局部變量,但當(dāng)作為的返回值賦給外的全局變量時,神奇的事情發(fā)生了在全局作用域中訪問到了,這就是閉包。而閉包最神奇的地方就是能在一個函數(shù)外訪問函數(shù)中的局部變量,把這些變量用閉包的形式放在函數(shù)中便能避免污染。 一、閉包是什么? 《JavaScript高級程序設(shè)計》中寫道:閉包是指有權(quán)訪問另一個函數(shù)作用域中的變量的函數(shù),如果用下定義的觀點看,這句話就是說閉包是函數(shù),我...
閱讀 1175·2021-11-16 11:45
閱讀 1042·2021-09-04 16:41
閱讀 3088·2019-08-29 16:40
閱讀 2865·2019-08-29 15:34
閱讀 2681·2019-08-29 13:11
閱讀 1743·2019-08-29 12:58
閱讀 1735·2019-08-28 18:00
閱讀 1785·2019-08-26 18:26