我们可以将浏览器JavaScript的执行上下文从Window对象更改为其他内容吗?

时间:2018-05-05 09:05:56

标签: javascript browser legacy-code

假设我有一个名为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,这意味着要扫描整个代码。

我只是想方设法用最少的努力来改进用于浏览器的遗留代码。

1 个答案:

答案 0 :(得分:1)

第一个问题的答案,不可能无法在浏览器中更改默认执行上下文。 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一个在线工具,可让您查看上述所有工具的内部结构,这些工具非常有用,可以了解其工作原理并尝试使用小例子代码。