變量和函數聲明提高

聲明提高

變量和函數聲明提高發生在JavaScript預編譯階段。函數

所謂的聲明提高,就是說變量或者函數在聲明的時候會被提早到當前做用域的頂部,已經處於可訪問狀態。code

變量聲明提高

var scope = 'global';
function f(){
    console.log(scope);//undefined
    var scope = 'local';
    console.log(scope);//"local"
}

因爲函數體內存在變量聲明提高,因此上面代碼實際運行以下:ip

var scope = 'global';
function f(){
    var scope;    //變量聲明提高到函數頂部
    console.log(scope);
    scope = 'local';    //變量初始化依然保留在原來的位置
    console.log(scope);
}
f();

這裏須要注意,函數體內存在和全局做用域同名的變量scope,做用域鏈查找到當前函數體內發現局部變量scope,不會再去查找全局做用域當中變全局量scope了,簡而言之函數體內的局部變量會覆蓋全局同名變量內存

若是隱式聲明一個變量,那麼該變量是存在於全局做用域當中的。作用域

var scope = 'global';
function f(){
    scope = 'local'; 
}
f();
console.log(scope);//"local"

上面代碼,函數f內至關於對全局變量scope進行賦值get

函數聲明提高

建立函數有兩種方式,函數聲明和函數表達式,只有函數聲明存在提高。編譯器

//函數聲明
f('superman');
function f(name){
    console.log(name);
}

//函數表達式,報錯
f('superman');
var f= function(name){
    console.log(name);
}

看下面代碼:io

var getName = function(){
    console.log(2);
}
function getName (){
    console.log(1);
}
getName();//2

上面代碼實際運行以下:console

var getName;    //變量聲明提高
function getName(){    //函數聲明提高到頂部
    console.log(1);
}
getName = function(){    //變量賦值依然保留在原來的位置
    console.log(2);
}
getName();    // 最終輸出:2

變量和函數聲明提高優先級

函數聲明提高的優先級是高於變量聲明的,這裏的優先級指的是:同名的變量和函數中,函數先提高,再遇到同名的變量或函數,提高都將被編譯器忽略。編譯

//同時聲明變量a和函數a
var a;
function a() {} 
alert(typeof a); //顯示的是"function",初步證實function的優先級高於var。
 
//先聲明函數後聲明變量,證實上邊的例子不是function覆蓋了變量
function a() {}
var a; 
alert(typeof a); //顯示的還是"function",而不是"undefined",即function的優先級高於var。

注意,上面只是說聲明的狀況,若是變量同時賦值,有不同了

//聲明瞭變量的同時賦值
function a() {}
var a = 1;
alert(typeof a); //number,此時不是function了。
//說明:"var a=1"至關於"var a;a=1",即先聲明,後賦值,"a=1"至關於把a從新賦值了,天然就是number!

匿名函數不會向上提高

getName()
var getName = function () {
  alert('closule')
}
function getName() {
  alert('function')
}
getName()

上邊的代碼至關於:

function getName() { //函數向上提高
  alert('function')
}
getName()
var getName = function () {
  alert('closule')
}
getName()

不一樣<script>塊中的函數互不影響

<script>
  getName()
  var getName = function () {
    alert('closule')
  }
<script>
<script>
  function getName() {
    alert('function')
  }
<script>

代碼執行報錯:TypeError: getName is not a function,由於第一個<script>塊中getName()函數未定義,匿名函數又不會向上提高

總結

  • 在JavaScript中變量和函數的聲明會提高到最頂部執行
  • 函數內部若是用var聲明瞭相同名稱的外部變量,函數將再也不向上尋找。
  • 函數的提高高於變量的提高
  • 匿名函數不會提高
  • 不一樣<script>塊中的函數互不影響
相關文章
相關標籤/搜索