2014-07-02 15 views
5

Tôi đang cố gắng tìm hiểu JavaScript từ cuốn sách Rhino. Tôi đã cố gắng thực thi đoạn mã sau đây từ cuốn sách liên quan đến eval(). Tôi đang sử dụng node.js (v0.10.29) để thực thi các ví dụ.Node.js toàn cầu eval, ném ReferenceError

var geval = eval;     // aliasing eval to geval 
var x = 'global';     // two global variables 
var y = 'global'; 

function f() { 
    var x = 'local';     // define a local variable 
    eval('x += "changed";');   // direct eval sets the local variable 
    return x; 
} 

function g() { 
    var y = 'local';     // define a local variable 
    geval('y += "changed";');  // indirect eval sets global variable 
    return y; 
} 

console.log(f(), x);    // => expected 'localchanged global' 
console.log(g(), y);    // => expected 'local globalchanged' 

Tuy nhiên, tôi nhận được một ReferenceError bên trong g() chức năng khi có một nỗ lực để sử dụng geval() bí danh:

undefined:1 
y += "changed"; 
^ 
ReferenceError: y is not defined 
    at eval (eval at g (/Users/codematix/Learning/learnjs/expressions.js:148:3), <anonymous>:1:1) 
    at eval (native) 
    at g (/Users/codematix/Learning/learnjs/expressions.js:148:3) 
    at Object.<anonymous> (/Users/codematix/Learning/learnjs/expressions.js:153:3) 
    at Module._compile (module.js:456:26) 
    at Object.Module._extensions..js (module.js:474:10) 
    at Module.load (module.js:356:32) 
    at Function.Module._load (module.js:312:12) 
    at Function.Module.runMain (module.js:497:10) 
    at startup (node.js:119:16) 

Từ những gì tôi hiểu, khi tôi bí danh eval() như geval(), mã trong chuỗi được truyền được đánh giá trong phạm vi toàn cục theo ES5. Tuy nhiên, tôi đang chạy vào số ReferenceError và không thể hiểu tại sao.

Mặc dù tôi không xem xét eval() là một tính năng quan trọng, tôi chắc chắn muốn hiểu lý do tại sao tôi gặp phải hành vi này.

P.S. Khi tôi cố gắng thực thi cùng một mã trong Google Chrome, nó có vẻ hoạt động như một sự quyến rũ! Lạ thật!

Trả lời

4

Vấn đề là bạn đang chạy mã này từ mô-đun, trong đó var y = global; thực sự xác định y trong phạm vi mô-đun, không phải phạm vi toàn cầu.

Trong trình duyệt, phạm vi cấp cao nhất là phạm vi toàn cầu. Điều đó có nghĩa rằng trong các trình duyệt nếu bạn đang ở trong thế giới phạm vi var một cái gì đó sẽ xác định một biến toàn cầu . Trong Node, điều này khác. Phạm vi cấp cao nhất không phải là phạm vi toàn cầu; var một cái gì đó bên trong một module Node sẽ địa phương để mô-đun đó.

http://nodejs.org/api/globals.html#globals_global

Vì vậy, hai cách có thể để có được điều này để làm việc trong Node là:

  1. Run nó như là trong nút REPL
  2. Run nó trong một mô-đun, nhưng thay thế var y = global; chỉ với y = global;
+0

Sau đó tại sao 'console.log (f(), x);' hoạt động? – thefourtheye

+2

Bởi vì trong trường hợp đó, 'eval' được gọi là * trực tiếp *, vì vậy nó thực hiện trong phạm vi tương tự mà 'var x = 'địa phương';.' Được định nghĩa trong (Xem http://perfectionkills.com/global-eval- gì-là-the-options/cho sự phân biệt giữa gọi 'eval' trực tiếp và gián tiếp.) – Emmett

+2

Nhờ đó trả lời câu hỏi. Vì vậy, một 'var y = 'global';' thực sự tạo ra một biến mô-đun phạm vi và do đó 'geval ('y + =" thay đổi ";')' thực sự không thể tìm thấy 'y' trong phạm vi toàn cục. – codematix

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