1. 程式人生 > >js--函式提升和變數提升

js--函式提升和變數提升

一:函式提升

console.log(global); // undefined
var global = 'global';
console.log(global); // global
 
function fn () {
  console.log(a); // undefined
  var a = 'aaa';
  console.log(a); // aaa
}
fn();

之所以會是以上的列印結果,是由於js的變數提升,實際上上面的程式碼是按照以下來執行的:

var global; // 變數提升,全域性作用域範圍內,此時只是宣告,並沒有賦值
console.log(global
); // undefined global = 'global'; // 此時才賦值 console.log(global); // 打印出global function fn () {   var a; // 變數提升,函式作用域範圍內   console.log(a);   a = 'aaa';   console.log(a); } fn();

也就是說變數提升後,是會在記憶體中建立一個變數,但是沒有賦值,所以是undefined狀態。

 

瞭解一下js引擎原理:

在JS程式碼執行過程中:

        引擎

負責整個程式碼的編譯以及執行,編譯器則負責詞法分析、語法分析、程式碼生成等工作而作用域則如我們熟知的一樣,負責維護所有的識別符號(變數)。

        當我們執行上面的程式碼時,我們可以簡單的理解為新變數分配一塊兒記憶體,命名為global

,在執行的時候編譯器與引擎還會進行兩項額外的操作:判斷變數是否已經宣告:

        1.首先編譯器對程式碼進行分析拆解,從左至右遇見global

,則編譯器會詢問作用域是否已經存在叫global的變量了,如果不存在,則招呼作用域宣告一個新的變數global,

若已經存在,則繼續向下編譯。

        2.引擎遇見

var global = 'global'

時同樣會詢問在當前的作用域下是否有變數global

,若存在,則將global賦值為global。若不存在,則順著作用域鏈向上查詢,若最終找到了變數global則將其賦值global,若沒有找到,則招呼作用域宣告一個變數global並賦值為global.

 

補充說明,重複定義相同變數,由以上引擎只是可知,不會報錯,只會由後續相同值覆蓋記憶體值。

 

 

二、函式提升

  js中建立函式有兩種方式:函式宣告式和函式字面量式。只有函式宣告才存在函式提升!如:

console.log(f1); // function f1() {}   
console.log(f2); // undefined  
function f1() {}
var f2 = function() {}

只所以會有以上的列印結果,是由於js中的函式提升導致程式碼實際上是按照以下來執行的:

function f1() {} // 函式提升,整個程式碼塊提升到檔案的最開始
console.log(f1);   
console.log(f2);   
var f2 = function() {}