我们可以将浏览器的 JavaScript 的执行上下文从 Window 对象更改为其他内容吗?
Can we change the execution context of the browser's JavaScript from Window object to something else?
假设我有一个名为 module.js
的遗留文件,它是这样的:
a=1;
默认情况下附加到 window
对象,当您在浏览器中执行它时会污染 global
(实际上是 window
)范围。
是否可以在不更改源代码内容的情况下将其附加到不同的对象?
因为唯一真正的问题是执行上下文,没有别的,理想的解决方案是这样的:
change execution context from window to module object;
execute the code;
change execution context from module to window object;
如果这不可能,只要不更改内部内容,向源代码添加包装器(如 IIFE)就可以了。更改内部内容需要对代码进行全面扫描,这很昂贵。
例如,我可以将它包装成这样的函数 (✓):
function module()
{
a=1;
}
如果在严格模式下执行,我可以避免全局作用域污染。但是,我拿不到东西。
我不想做这样的事情(✗):
module = function module()
{
return a=1;
}
因为我们需要在有赋值的地方添加return
,这意味着扫描整个代码。
我只是想看看如何以最少的努力改进适用于浏览器的遗留代码。
第一个问题的答案,不可以更改浏览器中的默认执行上下文。 window
是一个特殊变量,向其分配任何其他内容都不会更改默认执行上下文。请参阅 MDN 中的 Global Object。这是一个插图
(function() {
window = {}
a = 5 // leaking declaration
var b = 10
})()
console.log(a) // a is on global scope
//console.log(b) // exception b is not defined in this scope
var b = 5
window = new Object()
window.c = 5
console.log(window.b) // 5
console.log(c) // 5
关于如何使用遗留代码的第二部分的答案,有许多工具可以进行 AST 转换,根据您的目标,您可能应该使用其中的一个或多个。
- jscodeshift 允许您编写
codemods
这些函数接收代码并对其应用转换。这可能是该类别中最强大的工具。
- ESLint 允许您设置规则(例如没有全局变量)并有一个
--fix
选项,该选项将在某些情况下应用自动修复,例如从单引号更改为双引号(这是主要用于样式相关规则)。
- prettier 是一个只关心代码外观的代码格式化程序:缩进、空格等。
- AST Explorer 一个在线工具,可让您查看上述所有工具的内部结构,这对于了解其工作原理和在小示例上尝试编写代码非常有用。
假设我有一个名为 module.js
的遗留文件,它是这样的:
a=1;
默认情况下附加到 window
对象,当您在浏览器中执行它时会污染 global
(实际上是 window
)范围。
是否可以在不更改源代码内容的情况下将其附加到不同的对象?
因为唯一真正的问题是执行上下文,没有别的,理想的解决方案是这样的:
change execution context from window to module object;
execute the code;
change execution context from module to window object;
如果这不可能,只要不更改内部内容,向源代码添加包装器(如 IIFE)就可以了。更改内部内容需要对代码进行全面扫描,这很昂贵。
例如,我可以将它包装成这样的函数 (✓):
function module()
{
a=1;
}
如果在严格模式下执行,我可以避免全局作用域污染。但是,我拿不到东西。
我不想做这样的事情(✗):
module = function module()
{
return a=1;
}
因为我们需要在有赋值的地方添加return
,这意味着扫描整个代码。
我只是想看看如何以最少的努力改进适用于浏览器的遗留代码。
第一个问题的答案,不可以更改浏览器中的默认执行上下文。 window
是一个特殊变量,向其分配任何其他内容都不会更改默认执行上下文。请参阅 MDN 中的 Global Object。这是一个插图
(function() {
window = {}
a = 5 // leaking declaration
var b = 10
})()
console.log(a) // a is on global scope
//console.log(b) // exception b is not defined in this scope
var b = 5
window = new Object()
window.c = 5
console.log(window.b) // 5
console.log(c) // 5
关于如何使用遗留代码的第二部分的答案,有许多工具可以进行 AST 转换,根据您的目标,您可能应该使用其中的一个或多个。
- jscodeshift 允许您编写
codemods
这些函数接收代码并对其应用转换。这可能是该类别中最强大的工具。 - ESLint 允许您设置规则(例如没有全局变量)并有一个
--fix
选项,该选项将在某些情况下应用自动修复,例如从单引号更改为双引号(这是主要用于样式相关规则)。 - prettier 是一个只关心代码外观的代码格式化程序:缩进、空格等。
- AST Explorer 一个在线工具,可让您查看上述所有工具的内部结构,这对于了解其工作原理和在小示例上尝试编写代码非常有用。