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