參考 https://www.cnblogs.com/betarabbit/archive/2012/01/28/2330446.html
js的作用域
簡單的理解是他是一種函數(shù)級作用域赞赖,即創(chuàng)建函數(shù)時,就會新開辟一個新的作用域冤灾。
var foo = 100;
function bar(){
console.log(foo); //undefined
if (!foo) {
var foo = 200;
console.log(foo); // 200
}
}
console.log(foo) // 100;
可以理解上面的一段代碼中前域,函數(shù)bar
中的變量foo
與第一行代碼的foo
只是名稱相同,卻不是同一個變量韵吨,他們處在不同的作用域里话侄。簡化一下 ,相當(dāng)于以下代碼
function bar(){...}
var foo;
foo = 100
這樣簡化下学赛,不難理解console.log()
里打印出的數(shù)值年堆。
JS中進入一個作用域有以下幾種方法:
- 語言自身定義(language-defined):所有作用域都默認包含
this,arguments
- 函數(shù)形參(formal parameters): 函數(shù)的形參會進入到函數(shù)的作用域中
- 函數(shù)聲明(function declaration): 函數(shù)聲明
- 變量聲明 (variable declaration)變量聲明
P注意!函數(shù)聲明和變量聲明略有不同盏浇!以上聲明的優(yōu)先級逐漸降低变丧。高優(yōu)先級的會覆蓋低優(yōu)先級的!但僅僅是提升部分的優(yōu)先級绢掰,后面的復(fù)制還是按照順序賦值的痒蓬!這里加了一些自己的代碼試驗。
JS解釋器總是會把函數(shù)聲明滴劲、變量聲明提升到其所在的作用域的頂端攻晒,函數(shù)聲明與變量聲明不同的是,函數(shù)的聲明和內(nèi)容都會被提升班挖,而變量僅僅聲明被提升到頂端鲁捏,內(nèi)容(賦值)卻沒有被提升。
sayHi();
sayHello();
var name = 'Lily'
function sayHi(){
if(!name){
var name = 'LiLi'
}
console.log(name+' Hi')
return;
}
var sayHello = function(){
console.log('Lily'+' Hi')
return;
var content = ' Hello'
}
以上可以改寫成如下代碼萧芙,等價:
function sayHi(){
var name;
if(!name){
name = 'LiLi'
}
console.log(name+' Hi')
return;
}; //函數(shù)的聲明和內(nèi)容都被提升
var sayHello; //變量僅聲明被提升
var name; //變量僅聲明被提升
sayHi(); // LiLi Hi
sayHello(); // sayHello is not a function
name = 'Lily'
sayHello = function(){
console.log('Lily'+' Hi')
var content //無論生效與否都會被提升
return;
content = ' Hello'
}