Functional programming 全局命名空间中的JavaScript库函数-缺点?

Functional programming 全局命名空间中的JavaScript库函数-缺点?,functional-programming,global-variables,underscore.js,javascript,Functional Programming,Global Variables,Underscore.js,Javascript,JS库(如underline.JS和LoDash.JS)通常通过全局对象提供函数 _.map(...); _.filter(...); 这些基本函数是Python中的全局函数,也是标准库的一部分: map(...) filter(...) 如果我将库函数升级为全局函数 window.map = _.map; window.filter = _.filter; map(...); filter(...); 。。。会有什么负面影响(除了全球命名空间污染) 我是否必须预料到任何性能问题 它会在

JS库(如underline.JS和LoDash.JS)通常通过全局对象提供函数

_.map(...);
_.filter(...);
这些基本函数是Python中的全局函数,也是标准库的一部分:

map(...)
filter(...)
如果我将库函数升级为全局函数

window.map = _.map;
window.filter = _.filter;

map(...);
filter(...);
。。。会有什么负面影响(除了全球命名空间污染)

我是否必须预料到任何性能问题

它会在某些浏览器中导致错误吗?(例如,如果内置JS函数被库函数覆盖,而库函数又依赖于本机函数)


链接仍然有效吗?

有很多缺点,但性能不太可能是其中之一

如果两个库有一个
map()
函数,并且行为略有不同,该怎么办?如果他们都将
map()
放在全局空间中,您将无法访问其中一个。而且您可能无法轻松知道您实际需要的
map()
已被覆盖


顺便说一下,
map()
filter()
是最近ish JS实现的一部分,但即使在那里,它们也是使用它们的对象原型的一部分。所以你有很多缺点,但性能不太可能是其中之一

如果两个库有一个
map()
函数,并且行为略有不同,该怎么办?如果他们都将
map()
放在全局空间中,您将无法访问其中一个。而且您可能无法轻松知道您实际需要的
map()
已被覆盖


顺便说一下,
map()
filter()
是最近ish JS实现的一部分,但即使在那里,它们也是使用它们的对象原型的一部分。所以你有和。

你不需要担心性能;即使在符号查找中添加额外的层,大多数现代JS引擎也会将其别名。您也不应该担心增加本机对象会导致异常——这是允许的。不,最大的问题是名称空间污染,您似乎对此有点不屑一顾

当代码在本机实现这些功能的较新浏览器上运行时会发生什么情况?假设您在2009年编写了这段代码,并在Array.prototype中添加了.map()。如果有人添加了一个需要一个函数签名(本机函数签名)的新库,而得到了一个不同的函数签名(您的),那么您的代码现在就会有一些大问题

如果必须这样做,至少检查全局符号是否已经存在,例如

window.map = window.map || myLib.map;

此外,确保依赖于map实现的任何代码都可以向RequireJS之类的JavaScript依赖关系管理工具发送依赖关系信号,或者确保您已经有了一个健壮的DM系统,并且在执行任何其他代码之前附加了本机重写(例如,不要将代码放在异步脚本标记中,不要将执行延迟到DOMContentLoaded,等等)您不必担心性能;即使您为符号查找添加了额外的层,大多数现代JS引擎也会将其别名。您也不必担心增加本机对象会导致异常——这是允许的。不,最大的问题是名称空间污染,您似乎对此有点不屑一顾

当您的代码在本机实现这些函数的较新浏览器上运行时会发生什么情况?假设您在2009年编写了这段代码,并将.map()添加到Array.prototype。如果有人添加了一个新库,该库需要一个函数签名(本机签名),但得到了一个不同的函数签名(您的),那么您的代码现在将出现一些大问题

如果必须这样做,至少检查全局符号是否已经存在,例如

window.map = window.map || myLib.map;

此外,确保依赖于map实现的任何代码都可以向RequireJS之类的JavaScript依赖关系管理工具发送依赖关系信号,或者确保您已经有了一个健壮的DM系统,并且在执行任何其他代码之前附加了本机重写(例如,不要将代码放在异步脚本标记中,不要将执行延迟到DOMContentLoaded,等等)

以下是避免将许多东西(如
map
filter
作为全局变量的一些原因:

  • 命名与试图执行类似操作但不兼容的其他代码/库冲突。如果所有代码都使用多个全局函数,那么单个全局函数的简单定义可能会完全破坏您的应用程序,因为它将重新定义用于代码中其他地方的函数。这一切这本身就是使用尽可能少的全局库的原因。在团队项目或使用重要的第三方库的项目中,这是不可能管理的,并且将不可避免地导致生产力的损失,或者更糟糕的是,可能不会立即显现的坏错误

  • 当一个符号是全局的时,代码模块就不那么自我描述了。嗯,符号map()从哪里来。这是内置的吗?它是本地定义的吗?它是由某个库定义的吗?知道gutils.map()从哪里来要容易得多(从gutils模块).大量的全局性组件的可维护性比将组件分解为定义良好的模块要差

  • 将函数定义为操作它们的对象上的方法有许多优点(例如ES5
    .map()
    .filter()
    是数组对象上的方法,而不是通用全局方法)。现在,将非标准方法添加到现有内置对象被认为是不好的做法(也是出于命名冲突的原因),但建议添加实现标准行为的多边形填充

  • 有关其他信息,请参阅这些参考资料:


    至于性能问题,它不应该是您首先关心的问题,甚至可能不会是一个问题
    _ = (function(){
    
       lib = {};
    
       lib.function1 = function(){
          //code
       };
       lib.function2 = function(){
         this.function1();
       };
    
       //more code
    
       return lib;
    
    })();
    
    window.function2 = _.function2;
    function2();