1. 程式人生 > >javascript 變量提升

javascript 變量提升

htm 容易 進行 出現 指令 解釋 log 過渡 col

1.JavaScript 變量提升

JavaScript 中,函數及變量的聲明都將被提升到函數的最頂部。

JavaScript 中,變量可以在使用後聲明,也就是變量可以先使用再聲明。

以下兩個實例將獲得相同的結果:

x = 5; // 變量 x 設置為 5

elem = document.getElementById("demo"); // 查找元素 
elem.innerHTML = x;                     // 在元素中顯示 x

var x; // 聲明 x
var x; // 聲明 x
x = 5; // 變量 x 設置為 5

elem = document.getElementById("
demo"); // 查找元素 elem.innerHTML = x; // 在元素中顯示 x

要理解以上實例就需要理解 "hoisting(變量提升)"。

變量提升:函數聲明和變量聲明總是會被解釋器悄悄地被"提升"到方法體的最頂部。

1.1JavaScript 初始化不會提升

JavaScript 只有聲明的變量會提升,初始化的不會。

以下兩個實例結果結果不相同:

var x = 5; // 初始化 x
var y = 7; // 初始化 y

elem = document.getElementById("demo"); // 查找元素 
elem.innerHTML = x + "
" + y; // 顯示 x 和 y
var x = 5; // 初始化 x

elem = document.getElementById("demo"); // 查找元素 
elem.innerHTML = x + " " + y;           // 顯示 x 和 y

var y = 7; // 初始化 y

實例 2 的 y 輸出了 undefined,這是因為變量聲明 (var y) 提升了,但是初始化(y = 7) 並不會提升,所以 y 變量是一個未定義的變量。

實例 2 類似以下代碼:

var x = 5; // 初始化 x
var y;     // 聲明 y

elem 
= document.getElementById("demo"); // 查找元素 elem.innerHTML = x + " " + y; // 顯示 x 和 y y = 7; // 設置 y 為 7

1.2在頭部聲明你的變量

對於大多數程序員來說並不知道 JavaScript 變量提升。

如果程序員不能很好的理解變量提升,他們寫的程序就容易出現一些問題。

為了避免這些問題,通常我們在每個作用域開始前聲明這些變量,這也是正常的 JavaScript 解析步驟,易於我們理解。

    JavaScript 嚴格模式(strict mode)不允許使用未聲明的變量。

2.JavaScript 嚴格模式(use strict)

JavaScript 嚴格模式(strict mode)即在嚴格的條件下運行。

2.1使用 "use strict" 指令

"use strict" 指令在 JavaScript 1.8.5 (ECMAScript5) 中新增。

它不是一條語句,但是是一個字面量表達式,在 JavaScript 舊版本中會被忽略。

"use strict" 的目的是指定代碼在嚴格條件下執行。

嚴格模式下你不能使用未聲明的變量。

    支持嚴格模式的瀏覽器:
Internet Explorer 10 +、 Firefox 4+ Chrome 13+、 Safari 5.1+、 Opera 12+。

2.2嚴格模式聲明

嚴格模式通過在腳本或函數的頭部添加 "use strict"; 表達式來聲明。

"use strict";
x = 3.14;       // 報錯 (x 未定義)
"use strict";
myFunction();

function myFunction() {
    y = 3.14;   // 報錯 (y 未定義)
}

在函數內部聲明是局部作用域 (只在函數內使用嚴格模式):

x = 3.14;       // 不報錯 
myFunction();

function myFunction() {
   "use strict";
    y = 3.14;   // 報錯 (y 未定義)
}

為什麽使用嚴格模式:

    消除Javascript語法的一些不合理、不嚴謹之處,減少一些怪異行為;
  • 消除代碼運行的一些不安全之處,保證代碼運行的安全;
  • 提高編譯器效率,增加運行速度;
  • 為未來新版本的Javascript做好鋪墊。

"嚴格模式"體現了Javascript更合理、更安全、更嚴謹的發展方向,包括IE 10在內的主流瀏覽器,都已經支持它,許多大項目已經開始全面擁抱它。

另一方面,同樣的代碼,在"嚴格模式"中,可能會有不一樣的運行結果;一些在"正常模式"下可以運行的語句,在"嚴格模式"下將不能運行。掌握這些內容,有助於更細致深入地理解Javascript,讓你變成一個更好的程序員。

2.3嚴格模式的限制

不允許使用未聲明的變量:

"use strict";
x = 3.14;                // 報錯 (x 未定義)
    對象也是一個變量。
"use strict";
x = {p1:10, p2:20};      // 報錯 (x 未定義)

不允許刪除變量或對象。

"use strict";
var x = 3.14;
delete x;                // 報錯

不允許刪除函數。

"use strict";
function x(p1, p2) {}; 
delete x;                // 報錯 

不允許變量重名:

"use strict";
function x(p1, p1) {};   // 報錯

不允許使用八進制:

"use strict";
var x = 010;             // 報錯

不允許使用轉義字符:

"use strict";
var x = \010;            // 報錯

不允許對只讀屬性賦值:

"use strict";
var obj = {};
Object.defineProperty(obj, "x", {value:0, writable:false});

obj.x = 3.14;            // 報錯

不允許對一個使用getter方法讀取的屬性進行賦值

"use strict";
var obj = {get x() {return 0} };

obj.x = 3.14;            // 報錯

不允許刪除一個不允許刪除的屬性:

"use strict";
delete Object.prototype; // 報錯

變量名不能使用 "eval" 字符串:

"use strict";
var eval = 3.14;         // 報錯

變量名不能使用 "arguments" 字符串:

"use strict";
var arguments = 3.14;    // 報錯

不允許使用以下這種語句:

"use strict";
with (Math){x = cos(2)}; // 報錯

由於一些安全原因,在作用域 eval() 創建的變量不能被調用:

"use strict";
eval ("var x = 2");
alert (x);               // 報錯

禁止this關鍵字指向全局對象。

function f(){
    return !this;
} 
// 返回false,因為"this"指向全局對象,"!this"就是false

function f(){ 
    "use strict";
    return !this;
} 
// 返回true,因為嚴格模式下,this的值為undefined,所以"!this"為true。

因此,使用構造函數時,如果忘了加new,this不再指向全局對象,而是報錯。

function f(){
    "use strict";
    this.a = 1;
};
f();// 報錯,this未定義

2.4保留關鍵字

為了向將來Javascript的新版本過渡,嚴格模式新增了一些保留關鍵字:

  • implements
  • interface
  • let
  • package
  • private
  • protected
  • public
  • static
  • yield
"use strict";
var public = 1500;      // 報錯

javascript 變量提升