9
var foo = (function(){ 
    var x = "bar"; 
    return function(){ 
    console.log(x); 
    }; 
})(); 

console.log(foo.toString()); // function() {console.log(x);} 
(foo)(); // 'bar' 
eval('(' + foo.toString()+')()')); // error: x is undefined 

Có một kỹ thuật để giải quyết (sửa đổi) là một chức năng, vì vậy tài liệu tham khảo từ phạm vi bên ngoài trở thành tài liệu tham khảo địa phương, như:Giải quyết tài liệu tham khảo bên ngoài-phạm vi trong một hàm javascript cho serialization

function() {console.log(x);} 

trở thành:

function() {console.log("bar");} 

Hiện tại, hàm này có thể được xâu chuỗi và vận chuyển qua mạng và được thực hiện trong một thời gian chạy khác.

Có thể một người có thể phân tích cú pháp hàm thành Cây cú pháp trừu tượng và sau đó sửa đổi nó? Tham chiếu sẽ luôn nằm ngoài phạm vi (không có sẵn), phải không?

Mục tiêu:

Tôi đang tuần tự hóa chức năng lọc từ thời gian chạy nút thành thời gian chạy postgresql plv8. Ngay bây giờ chức năng lọc có giao diện: dbClient.filter ((hàng, tuổi) => row.age> age), ageFromOuterScope) .then (matches => ...)

Tôi muốn giao diện dbClient.filter ((row) => row.age> age)), sau đó (matches => ...), trong đó tuổi là tham chiếu từ phạm vi bên ngoài.

Cập nhật:

tôi chỉ có thể tưởng tượng được một giải pháp. Phân tích chức năng, phát hiện tài liệu tham khảo cho các biến bên ngoài chức năng, và sau đó viết lại chức năng ban đầu:

function(row) { 
    return row.age > age 
} 

Để:

function(row, age) { 
    return row.age > age 
} 

biến phát hiện cũng nên được thêm vào một chuỗi đại diện cho một mảng, như :

var arrayString = '[age]' 

Và sau đó eval chuỗi:

var functionArgs = eval(arrayString) 

Và cuối cùng:

dbClient.filter(modifiedFunction, ...functionArgs).then(matches => ...) 
+0

Hầu hết các biến như vậy được sửa đổi vào thời gian chạy, do đó chuyển đổi như vậy sẽ thay đổi hành vi mã. –

+1

Hai nhận xét: Một, đây là chủ đề cho Stack Overflow vì nó yêu cầu một thư viện. Hai, đây không phải là cách hoạt động phạm vi hoạt động trong Javascript, cũng không nên, đó là lý do tại sao nó không hoạt động cho bạn. Vì nó không hoạt động theo cách này, làm thế nào một kỹ thuật có thể dự đoán chính xác cách đưa ra quyết định này? Điều này lần lượt làm cho câu hỏi mở rộng cho Stack Overflow. –

+0

Tôi đã sửa đổi câu hỏi. Làm thế nào về việc sử dụng AST? – Jacob

Trả lời

0

Tôi chạy foo codebox hàng đầu của bạn thông qua Closure Compiler của Google, và nó đã cho tôi điều này:

var foo=function(){return function(){console.log("bar")}}();foo; 

không chính xác những gì bạn muốn, nhưng bạn có thể có được những gì bạn muốn từ đó bằng cách sử dụng eval() và/hoặc toString() khi bạn đã được tinkering với rồi.

Tôi không biết điều này mạnh mẽ như thế nào, và nó tạo ra các đoạn mã khác, nhưng đối với các loại chức năng đơn giản mà bạn hiển thị, nó dường như liên tục nội dòng không lặp lại xuất hiện trong mã.

1

Bạn có thể liên kết x với chính đối tượng hàm.

var foo = (function(){ 
 
    var x = "bar"; 
 
    return function(){ 
 
    this.x = x; 
 
    console.log(this.x); 
 
    }; 
 
})(); 
 

 
(foo)() // 'bar' 
 

 
console.log(foo.toString()); // 'function() { this.x = x; console.log(this.x) }' 
 

 
eval('(' + foo.toString()+')()'); // 'bar'

1

Để vạch trần biến tin ngoài phạm vi bạn cần chức năng khác trong phạm vi mà viết lại mô tả phương pháp trả về bởi toString. Sau đó, bạn sử dụng hàm đó thay vì toString để lấy ra mô tả phương thức.

var foo = (function(){ 
    var x = "bar"; 

    var f = function(){ 
    console.log(x); 
    }; 

    f.decl = function() { 
     return f.toString().replace("(x)", "(\""+x+"\")"); 
    } 

    return f; 

})(); 

console.log(foo.decl()); // function() {console.log("bar");} 

eval("("+foo.decl()+")()"); // bar 
Các vấn đề liên quan