摘要:函數(shù)作用域和塊作用域前面講了是詞法作用域,那么什么時(shí)候會(huì)創(chuàng)建作用域呢主要是基于函數(shù)級(jí)別的作用域,也就是每一個(gè)函數(shù)都會(huì)創(chuàng)建一個(gè)作用域。函數(shù)會(huì)被當(dāng)作函數(shù)表達(dá)式而不是一個(gè)標(biāo)準(zhǔn)的函數(shù)聲明來處理。
什么是作用域
來一段《你不知道的JavaScript-上卷》中的原話:
幾乎所有編程語言最基本的功能之一,就是能夠儲(chǔ)存變量當(dāng)中的值,并且能在之后對(duì)這個(gè) 值進(jìn)行訪問或修改,這些變量住在哪里?換句話說,它們儲(chǔ)存在哪里?最重要的是,程序需要時(shí)如何找到它們?這些問題說明需要一套設(shè)計(jì)良好的規(guī)則來存儲(chǔ)變量,并且之后可以方便地找到這些變量。這套規(guī)則被稱為作用域
總之就是作用域就是一套規(guī)則,這個(gè)規(guī)則規(guī)定了程序如何去找到變量
詞法作用域先看一個(gè)例子:
function func1() { console.log(index) } function func2() { var index = 10 func1() } var index = 100 func2() // 100
為啥是100而不是10呢???
因?yàn)镴avaScript是詞法作用域
詞法作用域簡單地說就是:函數(shù)的作用域在聲明的時(shí)候就決定好了。和詞法作用域相對(duì)的是動(dòng)態(tài)作用域,動(dòng)態(tài)作用域關(guān)注函數(shù)從何處調(diào)用
上面的代碼中,聲明func1時(shí),它就處于全局作用域中,所以index就是100,即使執(zhí)行func1時(shí)也是。
前面講了JavaScript是詞法作用域,那么什么時(shí)候會(huì)創(chuàng)建作用域呢???
JavaScript主要是基于函數(shù)級(jí)別的作用域,也就是每一個(gè)函數(shù)都會(huì)創(chuàng)建一個(gè)作用域。為什么說主要呢?因?yàn)閣ith和try-catch語句也實(shí)現(xiàn)了塊作用域,當(dāng)然了用的很少。
var flag = true; if (flag) { var num = 10 } console.log(num) // 10
如果有塊級(jí)作用域的話,此時(shí)打印num應(yīng)該報(bào)錯(cuò)
function funcLevelScope() { var index = 10 } console.log(index); // ReferenceError
因?yàn)槭呛瘮?shù)級(jí)別的作用域,所以在函數(shù)外面訪問不到函數(shù)內(nèi)部的變量
如何模擬塊作用域當(dāng)然了,第一反應(yīng)就是在代碼外面加上包裝函數(shù)不就行了,比如這樣子:
function scope() { var flag = true; if (flag) { var num = 10 } } console.log(num) // ReferenceError
但是此時(shí)的問題就是多了一個(gè)函數(shù)包裝,且我們可以隨意的去運(yùn)行scope函數(shù),這可能會(huì)造成不好的影響。
自執(zhí)行函數(shù)解決了這個(gè)問題:
(function scope() { var flag = true; if (flag) { var num = 10 } })() scope() // ReferenceError console.log(num) // ReferenceError
包裝函數(shù)的聲明以 (function... 而不僅是以 function... 開始。盡管看上去這并不 是一個(gè)很顯眼的細(xì)節(jié),但實(shí)際上卻是非常重要的區(qū)別。函數(shù)會(huì)被當(dāng)作函數(shù)表達(dá)式而不是一個(gè)標(biāo)準(zhǔn)的函數(shù)聲明來處理。
作用域內(nèi)聲明提升變量聲明提升
首先明確的是
var x = 10
像這樣一句代碼可以分為聲明和賦值兩句:
var x x = 10
明確這個(gè)概念再繼續(xù)學(xué)習(xí)
console.log(x) // undefined var x = 10
為什么不直接報(bào)錯(cuò)呢?
因?yàn)樯厦娴拇a片段等于:
var x // 聲明提前 console.log(x) x = 10
注意到變量的聲明提前到了當(dāng)前作用域的最前面
函數(shù)聲明提升
hoist() // hoist! function hoist() { console.log("hoist!") }
為啥函數(shù)會(huì)成功執(zhí)行了,因?yàn)樯厦娴拇a片段相當(dāng)于:
function hoist() { console.log("hoist!") } hoist()
函數(shù)聲明被提升到了作用域的最前面
那么函數(shù)表達(dá)式會(huì)被提升嗎??
hoist() // TypeError var hoist = function () { console.log("hoist") }
因?yàn)檫@個(gè)相當(dāng)于:
var hoist hoist() // TypeError hoist = function () { console.log("hoist") }
變量聲明提升和函數(shù)聲明提升的優(yōu)先級(jí)
先說結(jié)論:函數(shù)會(huì)首先被提升,然后才是變量
看例子:
console.log(x) var x = 10 function x() { console.log("func x") }
顯然此時(shí)打印的x是一個(gè)函數(shù)
這是因?yàn)樯厦娴拇a片段相當(dāng)于:
function x() { console.log("func x") } var x console.log(x) // f x(){...} x = 10
所以打印的是函數(shù)
參考資料:
JavaScript深入之詞法作用域和動(dòng)態(tài)作用域
你不知道的JavaScript-上卷
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/94868.html
摘要:閉包確實(shí)是一個(gè)說爛了的概念,校招社招都會(huì)被問到,今天總結(jié)一番。先下定義,閉包是函數(shù)和該函數(shù)的詞法作用域的組合。在這個(gè)栗子里,函數(shù)以及它對(duì)變量的引用就構(gòu)成了閉包。閉包和作用域?qū)τ陂]包和作用域的關(guān)系,我的理解是閉包其實(shí)就是作用域的延伸。 閉包確實(shí)是一個(gè)說爛了的概念,校招社招都會(huì)被問到,今天總結(jié)一番。先下定義,閉包是函數(shù)和該函數(shù)的詞法作用域的組合。其實(shí)這個(gè)定義是比較教條的,可以直白的理解為閉...
摘要:昨天總結(jié)了一些作用域的知識(shí)前端工程師手冊(cè)之作用域,但是發(fā)表完發(fā)現(xiàn)忘記了一些東西,今天拾個(gè)遺。循環(huán)完畢之后,,且此時(shí)生成了個(gè)匿名函數(shù),由于這個(gè)匿名函數(shù)處在同一個(gè)詞法作用域中,所以他們引用同一個(gè),所以當(dāng)他們執(zhí)行時(shí),自然而然就會(huì)打出。 昨天總結(jié)了一些作用域的知識(shí)【前端工程師手冊(cè)】JavaScript之作用域,但是發(fā)表完發(fā)現(xiàn)忘記了一些東西,今天拾個(gè)遺。昨天說到了JavaScript中沒有塊級(jí)作...
摘要:之前總結(jié)了的一些常見綁定情況前端工程師手冊(cè)之的筆記,但是還有一些沒有說到,今天繼續(xù)學(xué)習(xí)一下。參考資料箭頭函數(shù)你不知道的上卷 之前總結(jié)了this的一些常見綁定情況(【前端工程師手冊(cè)】JavaScript之this的筆記),但是還有一些沒有說到,今天繼續(xù)學(xué)習(xí)一下。 es6箭頭函數(shù) 先說結(jié)論:箭頭函數(shù)沒有自己的this,它是根據(jù)外層(函數(shù)或者全局,后面會(huì)說到箭頭函數(shù)作為某個(gè)對(duì)象的方法時(shí)的情況...
摘要:如果不指定,默認(rèn)為當(dāng)前文檔的主機(jī)不包含子域名。標(biāo)識(shí)指定了主機(jī)下的哪些路徑可以接受該路徑必須存在于請(qǐng)求中。具體的使用參考教程和類似,但是可以直接使用來操作,具體的參看參考聊一聊前端存儲(chǔ)那些事兒聊一聊 cookie 為什么會(huì)有cookie http協(xié)議的無狀態(tài),所謂無狀態(tài)即是服務(wù)器并不是知道這次的請(qǐng)求和上次的請(qǐng)求是不是同一個(gè)client發(fā)來的,就好比你經(jīng)常去一家超市買東西,老板并不記得你是...
摘要:本文是面向前端小白的,大手子可以跳過,寫的不好之處多多分鐘搞定常用基礎(chǔ)知識(shí)前端掘金基礎(chǔ)智商劃重點(diǎn)在實(shí)際開發(fā)中,已經(jīng)非常普及了。 JavaScript字符串所有API全解密 - 掘金關(guān)于 我的博客:louis blog SF專欄:路易斯前端深度課 原文鏈接:JavaScript字符串所有API全解密 本文近 6k 字,讀完需 10 分鐘。 字符串作為基本的信息交流的橋梁,幾乎被所有的編程...
閱讀 2289·2019-08-30 15:53
閱讀 2505·2019-08-30 12:54
閱讀 1373·2019-08-29 16:09
閱讀 776·2019-08-29 12:14
閱讀 805·2019-08-26 10:33
閱讀 2560·2019-08-23 18:36
閱讀 3023·2019-08-23 18:30
閱讀 2184·2019-08-22 17:09