今天我們來做下作用域和變量提升的面試題;
答案我會寫在最下面,大家先開始自己嘗試下
//第1題
console.log(a);
var a=12;
function fn(){
console.log(a);
var a=13;
}
fn();
console.log(a);
//第2題
console.log(a);
var a=12;
function fn(){
console.log(a);
a=13;
}
fn();
console.log(a);
//第3題
console.log(a);
a=12;
function fn(){
console.log(a);
a=13;
}
fn();
console.log(a);
//第4題
var foo=1;
function bar(){
if(!foo){
var foo=10;
}
console.log(foo);
}
bar();
//第5題
var n=0;
function a(){
var n=10;
function b(){
n++;
alert(n);
}
b();
return b;
}
var c=a();
c();
alert(n);
//第6題
var a=10,b=11,c=12;
function test(a){
a=1;var b=2;c=3;
}
test(10);
alert(a); alert(b); alert(c);
//第7題
if(!("a" in window)){
var a=1;
}
alert(a);
//第8題
var a=4;
function b(x,y,a) {
alert(a);
arguments[2]=10;
alert(a);
}
a=b(1,2,3);
alert(a);
//第9題
var foo='hello';
(function(foo){
console.log(foo);
var foo = foo ||'world';
console.log(foo);
})(foo);
console.log(foo);
//第10題
var a=9;
function fn(){
a=0;
return function(b){ return b+a++; }
}
var f=fn()
var m=f(5);
alert(m);
var n=fn()(5);
alert(n);
var x=f(5);
alert(x);
下面是答案:
//第1題
console.log(a);
var a=12;
function fn(){
console.log(a);
var a=13;
}
fn();
console.log(a);
/*
解答:
1.在代碼執行前,會進行變量提升(帶var 和 函數)
2.代碼從上向下執行時,會跳過fn函數的聲明,因為變量提升時已進行定義和聲明
3.fn() 開始執行,會走函數的執行過程:
1)形成私有作用域
2) 形參指派
3) 變量提升
4)代碼從上到下執行
5)作用域是否銷毀
結果:
//undefined undefined 12
*/
//第2題
console.log(a);
var a=12;
function fn(){
console.log(a);
a=13;
}
fn();
console.log(a);
/*
解答:
1.變量提升 a(隻聲明) fn(聲明+定義)
2.代碼從上到下執行 跳過fn的定義代碼段,因為變量提升時已經執行過
3.fn() 執行函數的執行過程;沒有私有變量那麼a 會沿着作用域鍊查找變量
結果:
//undefined 12 13
*/
//第3題
console.log(a);
a=12;
function fn(){
console.log(a);
a=13;
}
fn();
console.log(a);
/*
解答:
1.變量提升階段 a 不會提升,是以在之前調用會報錯 隻有進行var 修飾符 聲明的變量才會變量提升
結果:
//程式報錯 Uncaught ReferenceError: a is not defined
*/
//第4題
var foo=1;
function bar(){
if(!foo){
var foo=10;
}
console.log(foo);
}
bar();
/*
解答:
1.變量提升 foo (隻聲明) bar(聲明+定義)
2.function bar 代碼段會跳過
3.bar() 執行函數的執行過程
函數的私有作用域:
1.無論條件是否成立都會進行變量提升
2.undefined 轉 boolean 是 false (資料類型轉boolean的false幾種類型)
3.false 取反 true 是以代碼從上到下執行 會執行 var foo = 10
結果:
//10
*/
//第5題
var n=0;
function a(){
var n=10; //11 12
function b(){
n++;
alert(n);
}
b();
return b;
}
var c=a(); //11
c(); //12
alert(n); //0
/*
解答:
1.變量提升 n (隻聲明) a(聲明+定義) c(隻聲明)
2.代碼執行 先跳過 function a(){}
3. c 等于 a() 的執行結果
1).函數的執行過程
2).函數作用域不銷毀的條件
1.函數的傳回值為引用類型
2.傳回值被其他變量使用
結果:
var c=a(); //11
c(); //12
alert(n); //0
*/
//第6題
var a=10,b=11,c=12;
function test(a){
a=1;var b=2;c=3;
}
test(10);
alert(a); alert(b); alert(c);
/*
解答:
1.變量提升 a b c (隻聲明) test(聲明+定義)
2.代碼從上到下執行 跳過 function test(a) {}
3.test(10) 函數執行過程:
1.形成私有作用域
2.形參指派(也是私有變量)
3.變量提升
4.代碼從上到下執行
5.作用域是否銷毀
4.作用域鍊查找非私有變量
結果:
//10 11 3
*/
//第7題
if(!("a" in window)){
var a=1;
}
alert(a);
/*
解答:
1.變量提升;
1.無論條件是否成立都會進行變量提升
2. a為undefined "a" in window 傳回 true
3.是以不會執行 var a = 1;這段代碼
結果:
//undefined
*/
//第8題
var a=4;
function b(x,y,a) {
alert(a);
arguments[2]=10;
alert(a);
}
a=b(1,2,3); //3 10
alert(a); //undefined
/*
解答:
1.變量提升 a(隻聲明) b(聲明+定義)
2.function b(){}跳過
3.函數的執行過程
4.把 b(1,2,3) 的執行結果指派給 a
結果:
*/
//第9題
var foo='hello';
(function(foo){
console.log(foo);
var foo = foo ||'world';
console.log(foo);
})(foo);
console.log(foo);
/*
解答:
1.變量提升 foo
1.自執行函數不進行變量提升
2.自執行函數執行 函數執行過程
1.形成私有作用域
2.形參指派
3.變量提升
1.如果變量名重複,不再進行重複聲明,但要重新定義;
結果:
//hello hello hello
*/
//第10題
var a=9;
function fn(){
a=0; //全局變量 0 1 0 1 2
return function(b){ return b+a++; }
}
var f=fn()
var m=f(5);
alert(m); //5
var n=fn()(5);
alert(n); //5
var x=f(5); //6
alert(x); //2
/*
解答:
1.變量提升 a(定義) fn(聲明+定義) f m n x (定義)
2.function fn() {} 跳過
3. 執行 var f = fn() 傳回fn()的傳回值
1.函數的執行過程
2.函數作用域不銷毀
3.作用域鍊
結果:
// 5 5 6 2
*/
歡迎大家,貼題讨論。共同進步