[英]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.