函數&做用域提高

  • 當即執行函數表達式(IIFE)
var a = 2;
(function foo() {
  var a = 3;
  console.log(a);//3
})();//IIFE
console.log(a);//2

輸出:3 2
foo綁定在函數表達式自身的函數中而不是所在做用域,使值爲3的變量a只能在{..}內被訪問。 且foo變量名不會污染外部做用域。函數


var a=2;
(function IIFE(global) {//參數名爲global
  var a=3;
  console.log(a);//3
  console.log(global.a);//2
})(window);//將window對象的引用傳遞進去
console.log(a);//2

輸出:3 2 2
當即執行函數表達式的傳參版本。code

//倒置代碼運行順序
var a=2;
(function iife(def) {
  def(window);
})(function def(global) {
  var a=3;
  console.log(a);//3
  console.log(global.a);//2
});
console.log(a);

輸出:3 2 2
同上。對象


  • 做用域
try {
  undefined();//執行一個非法操做來製造異常
} catch(err) {
  console.log(err);//TypeError: undefined is not a function
}
console.log(err);//Uncaught ReferenceError: err is not defined

說明:err僅存在catch分句內部。ip


var foo=true;
if(foo) {
  let bar=foo*2;
  var b = foo*3;
  console.log(b);
  console.log(bar);
}
console.log(b);
console.log(bar);

輸出:
3
2
3
Uncaught ReferenceError: bar is not defined
let關鍵字將變量綁定到所在做用域,因此在全局做用域找不到變量bar。作用域

for(var i=0; i<10; ++i) {
  console.log(i);
}
console.log(i);

輸出:1 2 3 4 5 6 7 8 9 10io

for(let i=0; i<10; ++i) {
  console.log(i);
}
console.log(i);

輸出:1 2 3 4 5 6 7 8 9 Uncaught ReferenceError: i is not definedconsole


var foo=true;
if(foo) {
  var a=2;
  const b=3;
  console.log(a);
  console.log(b);
  a=3;
  b=4;
}
console.log(a);
console.log(b);

輸出:2 3 Uncaught TypeError: Assignment to constant variable.
在爲b賦值時直接報錯,由於const的值是固定的,試圖修改會引發錯誤。編譯

若是將b=4;註釋掉,則
輸出:2 3 3 Uncaught ReferenceError: b is not defined
constlet同樣,將變量綁定到所在做用域。function


  • 做用域提高

總結:變量和函數聲明被提高到最上面,函數表達式不會被提高。變量

a=2;
var a;
console.log(a);
console.log(b);
var b=2;
/*以上代碼至關於
var a;
var b;
a=2;
console.log(a);
console.log(b);
b=2;*/

輸出:2 undefined
var a;定義聲明編譯 階段進行
a=2;賦值聲明在原地等待 執行 階段
變量a的定義聲明var a;被提高到最上面,即 a=2 以前,因此沒有報錯undefined.


foo();//1
var foo;
function foo() {
  console.log(1);
}
foo=function() {
  console.log(2);
}
/*以上代碼至關於
function foo() {
 console.log(1);
}
foo();
foo=function() {
 console.log(2);
}

輸出:1
函數foo的聲明var foo;被提高到最上面。
注:函數首先被提高,而後是變量。且,函數聲明可覆蓋。


代碼引用自《你不知道的JavaScript》系列,部分有更改。
相關文章
相關標籤/搜索