2012-11-29 30 views
6

Trong đoạn mã sau:redeclare JavaScript Biến

var greeting = "hi"; 

function changeGreeting() { 
    if (greeting == "hi") { 
     var greeting = "hello"; 
    } 

    alert(greeting); 
} 

changeGreeting();​ 

... greeting là undefined. Tuy nhiên nếu tôi loại bỏ các var và thay đổi changeGreeting() này:

function changeGreeting() { 
    if (greeting == "hi") { 
     greeting = "hello"; 
    } 

    alert(greeting); 
} 

... tôi nhận được "hello" như mong đợi.

Tôi sẽ không bao giờ redeclare một biến như thế này trong mã của tôi, nhưng tại sao điều này xảy ra?

Trả lời

27

Biến JavaScript có phạm vi chức năng. Do đó, sự hiện diện của hàm var greeting bên trong hàm sẽ khai báo biến số greeting cục bộ, sẽ không được xác định tại thời điểm đề cập trong điều kiện if: biến toàn cầu sẽ không hiển thị bên trong hàm, bị lu mờ bởi hàm cục bộ. Do đó, if không xảy ra, việc gán cho hello không xảy ra, biến vẫn chưa được xác định. Trong ví dụ thứ hai, bạn đang sử dụng biến toàn cầu trong suốt, nó không bị lu mờ bởi biến cục bộ (bởi vì, không có var greeting bên trong hàm) và mọi thứ hoạt động như bạn mong đợi.

+3

+1 Câu trả lời rõ ràng và rõ ràng. – Aesthete

+0

+1 thực sự dành cho bạn thưa bạn. –

+0

@bfavaretto: Tôi giả định 'var greeting' là một lỗi, và được cho là khai báo biến toàn cầu' var currentSize' (sẽ bị lu mờ trong ví dụ đầu tiên, và được sử dụng trong ví dụ thứ hai). Nếu không nó sẽ hoàn toàn không liên quan đến ví dụ. – Amadan

-1

Trong đoạn mã đầu tiên của bạn, bạn đang kiểm tra biến toàn cục, không tồn tại -> không vượt qua nếu điều kiện.

Check-out này trên phạm vi javascript và làm thế nào để làm việc với các biến Javascript garden - function scopes

+1

Đoạn đầu tiên là _not_ đang kiểm tra biến toàn cục, phần thân hàm chứa khai báo 'var' của biến đó, được hoán đổi lên trên cùng. Nó kiểm tra một biến 'var currentLength;' <- undefined cục bộ được định nghĩa sau khi hàm trả về –

+0

Ah, bạn nói đúng. Tôi hoàn toàn blanked các cẩu:/ – rdamborsky

6

Nó rất đơn giản: JS Palăng tờ khai Biến để phía trên cùng của phạm vi hiện tại, nhưng bất kỳ hoạt động (bao gồm cả nhiệm vụ) không hoisted (trong cùng một phạm vi, xem giải thích trường hợp thứ hai), tất nhiên. Vì vậy, đoạn mã của bạn được dịch sang

(function() 
{ 
    var currentSize;//undefined 
    if (currentSize == 'hi')//always false 
    { 
     currentSize = 'hello';//assignment that will never be 
    } 
    alert(currentSize);//alerts undefined, of course 
}()); 

Bằng cách bỏ qua var, tiến hành quét phạm vi (kiểm tra biến được khai báo trong phạm vi toàn cục). Đáng buồn thay, khi làm như vậy, bối cảnh của việc sử dụng đầu tiên của var bị mất (bên trong một nhánh), và nhiệm vụ được hoisted, quá. Toàn cầu ngụ ý được dịch sang số :
Cảm ơn Chúa, điều này không đúng. Tôi cho rằng đó là vì tôi đã thử nghiệm một vài thứ trong bảng điều khiển dường như chứng thực điều này. Trong trường hợp này @amadan là đúng: bạn đang sử dụng biến toàn cục (được gọi là greeting trong đoạn trích của bạn do nhầm lẫn khi tôi đăng bài này). Tôi sẽ để lại mã dưới đây (sửa chữa nó) để hiển thị những gì globals ngụ ý thực sự, hy vọng nó sẽ giúp ai đó đôi khi trong việc hiểu phạm vi/phạm vi quét trong JS.

var currentSize = 'hello'; 
//well, actually implied globals can be deleted, so it's more like 
Object.defineProperty(this,'currentSize',{value:undefined, 
              writable:true, 
              enumerable:true, 
              configurable:true}); 
(function() 
{ 
    if (currentSize == 'hi')//always false 
    {//this still doesn't get executed 
     currentSize = 'hello';//assignment that will never be 
    } 
    alert(currentSize);//alerts undefined 
}()); 
+0

Một câu trả lời độc đáo trên phạm vi biến Tôi đã học được rất nhiều từ nó để sửa chữa khái niệm của tôi về phạm vi biến trong JS –

Các vấn đề liên quan