2014-07-01 34 views
10

Tôi có một trang HTML có mã JavaScript sau được đính kèm.Biến JavaScript không xác định và không được xác định

alert(box); 
box = "Thinking outside the box"; 

Trong giao diện điều khiển tôi nhận được "ReferenceError chưa gặp: hộp không được định nghĩa"

khi tôi thay đổi nó để:

alert(box); 
var box = "Thinking outside the box"; 

Cảnh báo được gọi và cho thấy không xác định. Tôi cần phải giải thích điều này, tôi có một ý tưởng mơ hồ về lý do tại sao điều này xảy ra. Tôi biết rằng khi tôi sử dụng var, JavaScript biết biến là có trước khi cảnh báo được thực thi, nhưng không nhất thiết phải gán một giá trị cho nó? Tôi có cách nào ở đây không? Cần một số trợ giúp để hiểu điều này.

+4

Đọc về hộp "hoisting" – elclanrs

+0

gọi, trước khi bạn đã xác định hộp, nó không tồn tại, nó chỉ tồn tại khi bạn xác định nó, cho dù 'nó' có giá trị hay không. – saj

+0

Hiểu biết của bạn là khá nhiều ở đó :) –

Trả lời

9

Khi bạn xác định một biến với var, khai báo biến được "hoisted" lên đầu phạm vi và do đó biến được xác định cho toàn bộ phạm vi. Việc khởi tạo biến (gán giá trị ban đầu của nó) vẫn ở cùng một vị trí trong mã.

Vì vậy, trong ví dụ thứ hai của bạn, khi bạn thực hiện alert(box), biến số box đã được khai báo do tuyên bố hoán đổi var. Ví dụ thứ hai của bạn:

alert(box); 
var box = "Thinking outside the box"; 

về cơ bản là tương đương với này (khai báo của biến box được kéo lên đến đỉnh của phạm vi):

var box; 
alert(box); 
box = "Thinking outside the box"; 

Điều này làm cho biến box tuyên bố (mặc dù không được khởi tạo) trước câu lệnh alert(box) của bạn và do đó bạn nhận được kết quả phù hợp với biến được khai báo, nhưng không có giá trị (báo cáo alert()undefined đó là những gì xảy ra khi biến tồn tại, nhưng chưa được khởi tạo).

Ví dụ đầu tiên của bạn không sử dụng var và do đó không có cẩu ở điểm bạn làm alert(box), không có biến nào ở tất cả có tên box và do đó bạn nhận được uncaught reference error.

Có rất nhiều, nhiều bài đăng ở đây trên SO mô tả chi tiết của cẩu. Bạn có thể thấy một danh sách dài của chúng ở đây: https://stackoverflow.com/search?q=javascript+variable+hoisting nơi bạn sẽ tìm thấy giải thích thêm về cẩu nâng.

Lưu ý: các khai báo chức năng cũng được treo để một số bài đăng bạn tìm thấy sẽ về khai báo hàm thay vì khai báo biến, mặc dù khái niệm này khá giống nhau.

+0

Ill kiểm tra câu trả lời này là chính xác trong 3 phút. lol Cảm ơn, tôi đánh giá cao sự giải thích. –

+1

Tôi đoán lý do tôi gặp khó khăn khi tìm một bài đăng khác là vì tôi không hiểu thuật ngữ kéo dài. Bây giờ tôi đang tìm nhiều câu hỏi. –

+2

@EricB - vâng, đôi khi bạn chỉ cần biết từ tìm kiếm tác vụ. – jfriend00

2

Điều này phải làm với cẩu nâng. Điều này có nghĩa là, khai báo biến (và khai báo nói chung) được xử lý trước khi bất kỳ mã nào được thực hiện, khai báo một biến ở bất kỳ đâu trong mã tương đương với khai báo nó ở trên cùng. Điều này cũng có nghĩa là một biến có thể xuất hiện được sử dụng trước khi nó được khai báo.

Khi bạn làm như sau:

alert(box) 
var box = "Thinking outside the box" 

này được ngầm hiểu là:

var box; 
alert(box); 
box = "Thinking outside the box" 

Trong trường hợp đầu tiên, bạn đã không khai báo biến, và do đó không được kéo lên, tại lúc đó hộp điểm là undefined

Tại sao điều này xảy ra?

Như Stoyan Stefanov giải thích trong cuốn sách của ông "JavaScript Patterns", cẩu là kết quả của việc thực hiện các dịch viên JavaScript:

For completeness, let’s mention that actually at the implementation level things are a little more complex. There are two stages of the code handling, where variables, function declarations, and formal parameters are created at the first stage, which is the stage of parsing and entering the context. In the second stage, the stage of runtime code execution, function expressions and unqualified identifiers (undeclared variables) are created. But for practical purposes, we can adopt the concept of hoisting, which is actually not defined by ECMAScript standard but is commonly used to describe the behaviour.

- Stoyan Stefanov, "JavaScript Patterns"

Là một đọc phụ, liên kết this bài báo từ Safe Shepherd.

+0

Đây là một câu trả lời tuyệt vời và tôi muốn cảm ơn bạn đã dành thời gian cho nó và tham khảo cuốn sách tuyệt vời này. Tôi đã nghe về cuốn sách các mẫu JavaScript của Stoyan và trên radar của tôi khi tôi tìm hiểu thêm về JavaScript. Cảm ơn câu trả lời, tôi đã đánh dấu jfriend là chính xác rồi, nhưng tôi sẽ 1up câu trả lời của bạn và một lần nữa cảm ơn bạn vì nó! –

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