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