JavaScript命名冲突不可避免?( 二 )


  • ES6的方法最初是与JavaScript框架MooTools(错误报告)
    .String.prototype.includes.contains全局添加的方法相冲突 。
  • ES2016的方法最初是与MooTools(错误报告 )
    .Array.prototype.includes.contains添加的方法相冲突 。
  • ES2019的方法最初是和MooTools(错误报告,博客文章)
    .Array.prototype.flat.flatten相冲突 。
修改内置原型并不总是糟糕的
你可能会对MooTools的创建者的粗心大意感到疑惑 。但是,向内置原型添加方法并不总是糟糕的 。在ES3(1999年12月)和ES5(2009年12月)之间,JavaScript是一种停滞不前的语言 。MooTools和Prototype等框架改进了它 。这些方法的缺点只有在JavaScript的标准库再次增加之后才会凸显出来 。
 
冲突源2:检查一个属性的存在ES2022的方法最初是.NET的 。因为以下库检查属性以确定对象是否是一个html集合(而不是一个数组),所以它必须被重新命名:Magic360、YUI 2、YUI 3
.Array.prototype.at.item.item
 
冲突源3:检查全局变量是否存在自ES2020以来,我们可以通过globalThis访问全局对象 。Node.js一直使用该名称来实现此目的 。最初的计划是为所有平台标准化该名称.global
然而,以下模式经常被用来确定当前平台:
if (typeof global !== 'undefined') { // We are not running on Node.js}如果浏览器也有一个名为.global的全局变量,这种模式(以及类似的模式)就会失效 。因此,标准化的名称被改为.globalglobalThis
JavaScript命名冲突不可避免?

文章插图
冲突源4:通过创建局部变量with语句
JavaScript的声明with语句
长期以来,人们一直不鼓励使用JavaScript的with语句,甚至在ES5中引入的严格模式中也被定为非法 。在其他地方,严格模式在ECMAScript模块中是活跃的 。
该语句将一个对象的属性变成局部变量:with
cons t myObject = { ownProperty: 'yes',};with (myObject) { // Own properties become local variables assert.equal( ownProperty, 'yes' ); // Inherited properties become local variables, too assert.equal( typeof toString, 'function' );}由with语句引起的冲突
框架Ext.js使用的代码与下面的片段有些相似点:
function myFunc(values) { with (values) { console.log(values); // (A) }}myFunc([]); // (B)当ES6方法被添加到JavaScript中时,如果用Array(B行)来调用它,它就会失效 。该语句将Array的所有属性变成了局部变量 。其中一个是继承的属性 。因此,A行中的语句已记录,不再是参数(错误报告1,错误报告2)
Array.prototype.valuesmyFuncwithvalues.valuesArray.prototype.valuesvalue
Unscopables:防止with导致的冲突
公共符号Symbol.unscopables允许对象隐藏语句中的某些属性 。它只在标准库中使用一次,对于Array.prototype:with
assert.deepEqual( Array.prototype[Symbol.unscopables], { __proto__: , at: true, copyWithin: true, entries: true, fill: true, find: true, findIndex: true, flat: true, flatMap: true, includes: true, keys: true, values: true, }); 
结论以上提出了JavaScript结构与现有代码发生名称冲突的四种方式:
  • 向内置原型添加方法
  • 检查属性是否存在
  • 检查全局变量是否存在
  • 创建局部变量with
冲突的某些来源很难预测,但存在以下一些一般规则:
  • 不要更改全局数据 。
  • 避免检查是否存在全局数据 。
  • 请注意,内置值将来可能会获得其他属性(自己的或继承的属性) 。
对于库来说,为JavaScript值提供功能的最安全方法是通过函数 。如果JavaScript得到一个pipe operator,我们也可以像方法一样使用它们 。
参考资料:
https://2ality.com/2022/03/naming-conflicts.html
—END—
 




推荐阅读