ES6中块级作用域下的函数声明
生活随笔
收集整理的這篇文章主要介紹了
ES6中块级作用域下的函数声明
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
背景
因為ES5的時候沒有塊級作用域,所以ES5規定不能再if這樣的塊中聲明函數,但是為了兼容各大瀏覽器并沒有嚴格遵守這條規定。
ES6的時候引入了塊級作用域,規定在塊級作用域中聲明函數就相當于使用let來聲明變量一樣。但是又因為瀏覽器端的兼容問題,標準中說明瀏覽器端的實現可以不完全遵守,有自己的行為,如下:
- 允許在塊級作用域內聲明函數。
- 函數聲明類似于var,即會提升到全局作用域或函數作用域的頭部。
- 同時,函數聲明還會提升到所在的塊級作用域的頭部。
上面輸出 undefined這表明了上面兩條,一個是允許在塊級作用域內聲明函數,一個是塊級作用域內聲明類似于var。
if (true) {console.log(a);function a() {} }輸出函數a,這表明了第三條:函數聲明會提升到所在塊級作用域的頭部。
問題和信息
上面現有的理論并不夠解釋下面的現象:
var a;{a = 5;function a() {}a = 0;console.log(a); } console.log(a);chrome最新版輸出的是:第一個console輸出的是0,第二個console輸出的是5。
先陳述下依據已知的三條理論得出上面代碼幾個不合理的現象:
這里打印了a是一個函數,穿透了塊級作用域。上面并沒有解釋這種現象。
解釋上面兩個問題,還需要額外的信息(信息來自stackoverflow高贊回答,原文在參考鏈接中):
function enclosing() {{function compat() {}} }// works the same asfunction enclosing() {var compat? = undefined; // function-scoped{let compat? = function compat() {}; // block-scopedcompat? = compat?;} }上面對塊中的函數聲明引入的額外的概念,更加清晰明了的解釋了底層做了什么。
首先額外引入的信息本身也存在一些問題。少了函數會提升到當前塊作用域頂部,我認為應該如下修改:
function enclosing() {var compat? = undefined; // function-scoped{function compat() {}let compat? = compat; // block-scopedcompat? = compat?;} }這樣就修復了沒有函數提升的問題。
猜想
根據額外補充的知識加上自己的想象力得到如下結果:
var a?;{// 這部分被提升function a() {}let a? = a;a? = a;// 這部分被提升ENDa? = 5;a? = 0;console.log(a?); } console.log(a?);a? 和 a? 都是a在不同位置的不同分身。
參考
- let 和 const 命令
- What are the precise semantics of block-level functions in ES6?
總結
以上是生活随笔為你收集整理的ES6中块级作用域下的函数声明的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 记录一次cookie导致登录失败的惨案
- 下一篇: 【译】nginx关于location部分