2016-09-17 13 views
6

Tôi gặp phải hành vi lạ khi sử dụng eval trong JS.Chụp Javascript biến

var f = function() { 
    var x = 10; 

    return function() { 
     eval('console.log(x);'); 
     window['eval']('console.log(x);'); 
    } 
}; 

f()(); 

OUTPUT:

10 
undefined:1 
console.log(x); 
      ^
ReferenceError: x is not defined 

Tại sao sử dụng eval rõ ràng nắm bắt được x nhưng global['eval'] không? Và mặc dù global['eval'] không chụp x, tại sao nó không thể thấy sau eval, đã bị bắt giữ x?

+5

câu hỏi tốt hơn là lý do tại sao bạn đang sử dụng eval? eval làm những điều kỳ diệu. tốt nhất là để nó một mình. –

+1

Đôi khi để thử nghiệm từ xa, tôi cần tải nhanh và chạy mã cục bộ của mình. Không cho mã sản xuất :) –

+0

http://stackoverflow.com/a/17281213/1005215 –

Trả lời

6

cửa sổ [ 'eval'] hoạt động ở phạm vi toàn cầu, eval() hoạt động ở phạm vi địa phương.

Từ Javascript tài liệu tham khảo của Mozilla:

Nếu bạn sử dụng chức năng eval gián tiếp, bằng cách gọi nó thông qua một tài liệu tham khảo khác hơn là eval, tính đến ECMAScript 5 nó hoạt động ở phạm vi toàn cầu chứ không phải là phạm vi địa phương; điều này có nghĩa là, ví dụ, chức năng khai báo tạo ra các chức năng toàn cầu và mã được đánh giá là không có quyền truy cập vào các biến cục bộ trong phạm vi nơi nó được gọi.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval

3

Chức năng bên trong của bạn không thực sự nắm bắt tham chiếu của x và do đó không bao giờ được chuyển trực tiếp đến eval.

eval thường hoạt động at the local scope và vì vậy cuộc gọi đầu tiên thành công (vì phạm vi cục bộ chứa khai báo x).

Tuy nhiên, nếu bạn gọi eval theo cách mà bạn không có tham chiếu trực tiếp đến nó, nó sẽ tự gọi trong phạm vi toàn cục, mà var x không phải là một phần của và không thành công.

Chỉ cần không sử dụng eval.

1

Bạn có thể sử dụng để vượt qua Function.prototype.bind()x chức năng trở

var f = function() { 
 
    var x = 10; 
 

 
    function y(n) { 
 
     eval(`console.log(${n})`); 
 
     window["eval"](`console.log(${n})`); 
 
    } 
 

 
    return y.bind(this, x) 
 
}; 
 

 
f()();

+1

Vâng, đây là nội suy chuỗi, bạn thậm chí không cần ràng buộc cho điều này, bạn chỉ có thể nội suy biến trực tiếp trong câu lệnh eval mà không cần sử dụng tham số. 'f = function() {var x = 5; return function() {eval (\ 'console.log ($ {x}) \')}} ' –

1

việc window.eval trong phạm vi toàn cầu.

var variable = 1; 
 

 
(function(){ 
 
    var variable = 100, 
 
     cmd = "++variable"; 
 
    document.write(eval(cmd)+"\n"); // increment local var 100 and output 101 
 
    document.write(window.eval(cmd)+"\n"); // increment global var 1 and output 2 
 
})();

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