簡體   English   中英

為什么復制 eval 會改變其行為?

[英]Why does copying eval change its behaviour?

根據rollupjs 文檔

簡單地“復制” eval 為您提供了一個 function 做同樣的事情,但它在全局 scope 而不是本地運行:

var eval2 = eval;
(function () {
   var foo = 42;
   eval('console.log("with eval:",foo)');  // logs 'with eval: 42'
   eval2('console.log("with eval2:",foo)'); // throws ReferenceError
})();

誰能解釋一下這是如何工作的? 我無法在 ECMAScript 規范中找到任何關於eval()的具體內容。

也許eval實際上不是 function,而是一個被 function 替換的魔法令牌,它執行 scope 中的代碼,有點像這樣:

var eval2 = CREATE_EVAL(CURRENT_SCOPE);
(function () {
   var foo = 42;
   CREATE_EVAL(CURRENT_SCOPE)('console.log("with eval:",foo)');  // logs 'with eval: 42'
   eval2('console.log("with eval2:",foo)'); // throws ReferenceError
})();

然而,由於我們在這里處理模塊(commonJS 或 ES6),這意味着eval2實際上在模塊 scope 中運行。 rollupjs 文檔特別說明它在全局 scope 中運行 - 我認為這只是一個疏忽,但是當我測試它時,它實際上似乎在全局 scope 中運行:

var x = 1;
var eval2 = eval;
(function () {
    eval2('console.log("with eval2:", x)'); // throws ReferenceError
})();

這很混亂? 這到底是如何工作的? 為什么復制對 eval 的引用會如此劇烈地改變其行為?

因為ECMAScript 5 語言規范說直接引用eval將在本地 scope 中執行,而間接引用將使用全局 scope。

可以在MDN上找到更友好的英語描述:

如果你間接使用 eval function,通過 eval 以外的引用調用它,從 ECMAScript 5 開始,它在全局 scope 而不是本地 Z31A1FD140BE4BEF2D11E121EC9A18A 中工作。 這意味着,例如,function 聲明創建全局函數,並且正在評估的代碼無法訪問 scope 中的局部變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM