js 關(guān)于變量提升的兩道“變態(tài)”面試題,你能做對么?
點擊上方 前端瓶子君,關(guān)注公眾號
回復算法,加入前端編程面試算法每日一題群
老版本瀏覽器沒有塊級上下文的概念
老版本瀏覽器中,放在{}【排除:函數(shù)、對象】中的function在變量提升階段 都是聲明+定義
新版本瀏覽器中
1. 如果function出現(xiàn)在除函數(shù)、對象的大括號中,則在變量提升截斷,只聲明不定義了!
2.如果除了函數(shù)和對象的大括號中,只要出現(xiàn)let/const/function關(guān)鍵詞,都會產(chǎn)生塊級私有上下文【對var無效】
注意:var是不受塊的影響的
// 題1
// EC(G)
// 變量提升;
var a;
fn=0x000;[[scope]:EC(G)]
console.log(a); //undefined
var a=12;
function fn(){
// EC(FN)
// 作用域鏈:<EC(FN),EC(G)>
// 形參賦值:--
// 變量提升: var a;
console.log(a); //undefind
var a=13;
}
fn();
console.log(a); // 12
// 題2
// EC(G)
// 變量提升;
var a;
fn=0x000;[[scope]:EC(G)]
console.log(a); //undefined
var a=12;
function fn(){
// EC(FN)
// 作用域鏈:<EC(FN),EC(G)>
// 形參賦值:--
// 變量提升: --
console.log(a);//->不是自己的私有變量,是EC(G)中的全局變量 12
a=13;
}
fn();
console.log(a); //->13
// EC(G)
// 變量提升;
// fn=0x000;[[scope]:EC(G)]
console.log(a); //->Uncaught ReferenceError: a is not defined
a=12;
function fn(){
console.log(a);
a=13;
}
fn();
console.log(a);
console.log(foo); //->undefined
{
console.log(foo);//->foo() {}
function foo() {}
foo = 1;//->私有的foo=1
console.log(foo);//->1
}
console.log(foo);//->? foo() {}

// EC(G)
// 變量提升:
// function foo;
// function foo;
console.log(foo); //->undefined
{
// EC(BLOCK)
// 作用域鏈<EC(BLOCK,EC(G))>
// 變量提升:
// foo = 0x001;[[scope]:EC(BLOCK)]
// foo = 0x002;[[scope]:EC(BLOCK)]
// ------
// foo=0x002;
\
console.log(foo);//函數(shù){2}
function foo() {1}//把之前對foo的操作映射給EC(G)一份=>全局foo=0x002
console.log(foo);//函數(shù){2}
foo = 1; //把私有的foo=1
console.log(foo);//->1
function foo() {2}//把之前對foo的操作映射給EC(G)一份=>全局foo=1
console.log(foo); //->1
}
console.log(foo);//->1

下面看一下三塊代碼的運行結(jié)果,比較一下區(qū)別

當代新版本瀏覽器
一方面兼容ES5語法 一方面還要兼容ES6新語法
機制:如果當前函數(shù)使用了ES6中的形參賦值默認值【不論是否生效】,并且函數(shù)體中有基于let/const/var聲明 的變量【無論變量名稱是否和形參一致(注意let/const是不允許重復聲明的),則函數(shù)在執(zhí)行的時候,除了形成一個私有的上下文,而且還會把函數(shù)體{}當作一個私有的塊級上下文[并且塊級上下文的上級上下文是私有的那個上下文]
如果函數(shù)體中聲明的變量和形參變量一直,最開始的時候,會把形參變量的值,同步給私有變量一份
// 符合條件
// 符合條件
function fn(x,y=10){
var m =20;
}
fn(1,2)
盡可能不要使用形參賦值默認值
var x = 1;
function func(x,y=function anonymous1(){x =2}){
var x = 3;
var y = function anonymous1(){x = 4}
console.log(x);
}
func(5);
console.log(x);
// 分析
var x = 1;
function func(x,y=function anonymous1(){x =2}){
// EC(FUNC)
// 作用域鏈<EC(FUNC),EC(G)>
// 初始化this:window
// 形參賦值:
// x=5;
// y=0x001;[[scope]:EC(FUNC)]
// EC(BLOCK)
// 作用域鏈<EC(BLOCK),EC(FUNC)>
// 變量提升:
// var x; ->copy 5 ->3 ->4
// var y; ->copy 0x001 ->0x002 [[scope]:EC(BLOCK)]
var x = 3;
var y = function anonymous1(){x = 4}
console.log(x); // =>4
}
func(5);
console.log(x); //=>1

前端路漫漫其修遠兮,吾將上下而求索,一起加油,學習前端吧!
轉(zhuǎn)自:貍不開
https://juejin.cn/post/6994620925501177863
最后
評論
圖片
表情
