2017-05-31 19 views
7

Tôi đã tự hỏi trạng thái nào được giữ giữa hai dòng mã JavaScript được gửi đến babel-node. Sự nhầm lẫn của tôi nảy sinh bởi vì nếu bạn viết hai dòng mã, bạn có thể ghi đè định nghĩa biến mà không có lỗi. Ví dụ, với babel-node --presets es2015, bạn có thể làm:Trạng thái nào được giữ giữa các dòng JavaScript?

> const a = 1; 
undefined 
> let a = 2; 
undefined 

Bây giờ nếu bạn viết nó trong một dòng, bạn nhận được một lỗi:

> const a = 1; let a = 2; 
TypeError: repl: Duplicate declaration "a" 
... 

Dường như trong trường hợp đầu tiên, nhà nước mà a được định nghĩa là 1 (const chuyển nhượng biến) bị mất (chưa đến khi nhiệm vụ thứ hai), trong khi trong trường hợp thứ hai, nó được duy trì.

Điều gì gây ra sự khác biệt ở đây? và trạng thái nào được duy trì?

Trả lời

6

constlet là cú pháp mới, họ phải được chuyển thành cơ chế ràng buộc duy nhất có sẵn trước ES6: var. Trong trường hợp đó, var cho phép tất cả các loại chuyển nhượng ngẫu nhiên mà không tạo ra bất kỳ cảnh báo nào.

Vì vậy, khi bạn nhập một biểu thức trong babel-node, babel sẽ di chuyển nó, đánh giá nó, sau đó hiển thị kết quả. Babel có thể kiểm tra việc sử dụng sai số ràng buộc const vào thời gian chuyển phát, đó là lý do bạn thấy lỗi cho const a = 1; let a = 2. Nhưng const a = 1let a = 2, khi được transpiled/đánh giá dưới dạng biểu thức riêng biệt, sẽ không hiển thị lỗi vì babel không thể phát hiện sự cố trong một trong hai biểu thức một mình.


Một cuộc biểu tình trực quan hơn về vấn đề này: Đối với mỗi biểu expr bạn gõ vào babel-node REPL, điều này về cơ bản là những gì đang xảy ra

evaluate(transpile(expr)) 
// => someResult 

Vì vậy, bạn sẽ không thấy một lỗi ở đây

evaluate(transpile('const a = 1')) 
evaluate('var a = 1') 
// bind a to 1 
// return undefined 

evaluate(transpile('let a = 2')) 
evaluate('var a = 2') 
// bind a to 2 
// return undefined 

Nhưng bạn sẽ thấy lỗi tại đây

evaluate(transpile('const a = 1; let a = 2')) 
// ERROR during transpile: const a has already been declared 
2

tôi không sử dụng babel-repl, nhưng nó phải là một cái gì đó để làm với việc chuyển đổi nó đang làm vì mọi thứ hoạt động như mong đợi với REPL thường xuyên:

$ node -v 
v7.4.0 

$ node 
> const a = 1; 
undefined 
> let a = 1; 
SyntaxError: Identifier 'a' has already been declared 

> const b = 1; let b = 1; 
const b = 1; let b = 1; 
        ^
SyntaxError: Identifier 'b' has already been declared 

> .editor 
// Entering editor mode (^D to finish, ^C to cancel) 
const c = 1; 
let c = 1; 

let c = 1; 
     ^
SyntaxError: Identifier 'c' has already been declared 
+1

xác định vị trí bằng 'nút babel 'là thủ phạm cụ thể - nút vani' node' repl không hiển thị vấn đề này. – naomik

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