我需要在我的网站上包含对第三方编写的JavaScript的引用.遗憾的是,编写此脚本的开发人员决定全局定义其所有功能.你知道,像这样:
function AwesomeStringHelper() {
  // ...
}
function MyGreatFunction() {
  // ...
}
当我使用<script>标记引用此脚本时,这两个方法都将添加到window对象中.
由于我不想污染全局范围,有没有办法可以更改外部脚本的范围?理想情况下,我希望能够引用类似于ExternalLibrary.MyGreatFunction()等的这些方法.我无法修改第三方脚本,因为它是在外部托管的,并且它经常更改.
如果您的第三方模块window直接分配给对象(例如window.myGlobal = someValue),并且您可以手动下载源代码,那么您应该能够将整个脚本"包装"在window对象已经重载的函数中:
function wrapModule(code) {
  // create a "fake" window object that inherits from the global object
  var fakeWindow = Object.create(window);
  // create a function wrapping the code
  // note that "window" is a parameter name in this function, shadowing
  // the global object
  var func = Function("window", code);
  // call function
  func.call(fakeWindow, fakeWindow);
  // return fake window object
  return fakeWindow;
}
// run code
const fakeWindow = wrapModule(`
  var x = 0;    // local variable (will not be exported)
  y = 1;        // global variable (will still be leaked)
  window.z = 2; // assignment to window
  this.w = 3;   // assignment to this
`);
// check what variables are exposed
console.log('window.x', typeof x); // window.x undefined
console.log('window.y', typeof y); // window.y number
console.log('window.z', typeof z); // window.z undefined
console.log('window.w', typeof w); // window.w undefined
// check what variables are exposed in fakeWindow
console.log('fakeWindow.x', typeof fakeWindow.x); // fakeWindow.x undefined
console.log('fakeWindow.y', typeof fakeWindow.y); // fakeWindow.y number
console.log('fakeWindow.z', typeof fakeWindow.z); // fakeWindow.z number
console.log('fakeWindow.w', typeof fakeWindow.w); // fakeWindow.w number首先,尝试将第三方开发人员告知如何正确编写模块.
如果这不起作用,请执行以下操作:
var ExternalLibrary = ExternalLibrary || window;
在代码的顶部.
然后,您可以ExternalLibrary.MyGreatFunction()在整个过程中使用它们来引用它们的功能(即使它们在全局window范围内仍然可见),然后一旦第三方开发人员修复了它们的范围问题,那么最多需要一行更改以保持兼容性(或者不完全改变,如果他们碰巧使用与ExternalLibrary你相同的名字).
或者,在<script>标记的任一侧使用两个简单的代码片段来记住window对象的键,然后将新出现的键移动到一个新对象中(同时从中删除它们window):
预载:
var ExternalLibrary = { _current: Object.keys(window) };
后负荷:
Object.keys(window).forEach(function(key) {
    if (ExternalLibrary._current.indexOf(key) < 0) {
        ExternalLibrary[key] = window[key];
        delete window[key];
    }
});
delete ExternalLibrary._current;
我过去曾经使用过类似的方法(在严格模式之前很常见)来检查泄漏的全局变量.