Java|JavaScript命名冲突不可避免?
【CSDN 编者按】从1995年开始 , 本文作者Dr.Axel Rauschmayer就专门从事Java和Web开发 , 已经有30多年了 。 2010年 , 他获得慕尼黑大学信息学博士学位 。 自2011年以来 , 他一直在2ality.com写博客 , 并写了几本关于Java的书 , 比如《Java for impatient programmers》、《Deep Java: Theory and techniques》等 。 今天这篇文章就来自于他的博客 , 介绍了在Java命名冲突时 , 现有代码如何强制对提议的功能进行重命名 。
整理 | 章雨铭 责编 | 张红月
出品 | CSDN(ID:CSDNnews)
不断发展的Java:不要破坏web!
Java的一个发展核心原则就是"不要破坏Web":在将新特性添加到语言中后 , 所有现有代码都必须能够继续运行 。
这样有一个坏处 , 就是不能从语言中删除现有的quirks 。 但这样做益处多多 , 比如旧的代码可以继续运行 , 而且升级到新的ECMA版本很简便等等 。
在为新特征(如方法名称)选择名称时 , 需要进行一个重要的测试 , 即在浏览器的nightly版本(早期预发布版本)中添加该特征 , 并检查是否有任何网站出现错误 。
接下来将介绍过去案例中的的四个冲突源 , 当产生这四种冲突时 , 就必须重命名特征 。
冲突源1:向内置原型添加方法
在Java中 , 我们可以通过改变其原型来为内置值添加方法:
神奇的是 , 语言可以通过这种方式改变 。 这种运行时的修改被称为猴子补丁(monkey patch) 。
什么是猴子补丁?
如果我们给内置原型添加方法 , 我们就是在运行时修改一个软件系统 。 这样的修改被称为猴子补丁 。 简单来说 , 对其含义有两种可能的解释 。
这个叫法起源于Zope框架 , 人们在修正Zope的Bug的时候经常在程序后面追加更新部分 , 这些被称作是“杂牌军补丁(guerilla patch)” , 后来guerilla就渐渐的写成了gorllia((猩猩) , 再后来就写了monkey(猴子) , 所以猴子补丁的叫法是这么莫名其妙的得来的 。
另一种说法是 , 它指的是搞乱(monkeying about)代码 。
反对改变内置原型的原因
对任何类型的全局命名 , 都会存在名称冲突的风险 。 如果有解决冲突的机制 , 就能规避风险 。 例如:
- 可以通过将符号添加到Java中 , 以避免方法之间的名称冲突 。 例如 , 任何对象都可以通过添加一个键为.NET的方法而成为可迭代的 。 由于每个符号都是唯一的 , 所以这个键永远不会与任何其他属性键 . Symbol.iterator 发生冲突 。
- 不同的库可能会对他们添加到 .Array.prototype 的方法使用相同的名字 。
- 如果一个名字已经被某个库使用了 , 那么这个名称就不能用于命名Java标准库的一个新特性 。
如果我们要实现一个polyfill(模拟原生Web平台功能) , 将新的Java方法添加到不支持它的引擎中 , 那么这个技术就能发挥作用 。 (顺便说一下 , 这是修改内置原型的一个合法用例 。 也许是唯一的一个) 。
然而 , 如果我们对一个普通库的方法使用这种技术 , 然后Java获取具有相同名称的方法 , 那么这两种实现的工作方式就不一样了 , 并且使用库方法的所有代码在使用内置方法时都会中断 。
必须更改名称的原型方法示例
- ES6的方法最初是与Java框架MooTools( 错误报告 ) .String.prototype.includes.contains 全局添加的方法相冲突 。
- ES2016的方法最初是与MooTools( 错误报告 ) .Array.prototype.includes.contains 添加的方法相冲突 。
- ES2019的方法最初是和MooTools( 错误报告,博客文章 ) .Array.prototype.flat.flatten 相冲突 。
你可能会对 MooTools的创建者的 粗心大意感到疑惑 。 但是 , 向内置原型 添加方法并不总是糟糕的 。 在ES3(1999年12月)和ES5(2009年12月)之间 , Java是一种停滞不前的语言 。 MooTools和Prototype等框架改进了它 。 这些方法的缺点只有在Java的标准库再次增加之后才会凸显出来 。
冲突源2:检查一个属性的存在
ES2022的方法最初是.NET的 。 因为以下库检查属性以确定对象是否是一个HTML集合(而不是一个数组) , 所以它必须被重新命名:Magic360、YUI 2、YUI 3.Array.prototype.at.item.item
冲突源3:检查全局变量是否存在
自ES2020以来 , 我们可以通过globalThis 访问全局对象 。 Node.js一直使用该名称来实现此目的 。 最初的计划是为所有平台标准化该名称.global
然而 , 以下模式经常被用来确定当前平台:
冲突源4:通过创建局部变量with 语句
【Java|JavaScript命名冲突不可避免?】Java的声明with 语句
长期以来 , 人们一直不鼓励使用Java的with语句 , 甚至在ES5中引入的严格模式中也被定为非法 。 在其他地方 , 严格模式在ECMA模块中是活跃的 。
该语句将一个对象的属性变成局部变量:with
// Inherited properties become local variables, tooassert.equal(typeoftoString, 'function');}
由with语句引起的冲突
框架Ext.js使用的代码与下面的片段有些相似点:
Array.prototype.valuesmyFuncwithvalues.valuesArray.prototype.values value
Unscopables:防止with导致的冲突
公共符号 Symbol.unscopables 允许对象隐藏语句中的某些属性 。 它只在标准库中使用一次 , 对于Array.prototype:with
以上提出了Java结构与现有代码发生名称冲突的四种方式:
- 向内置原型添加方法
- 检查属性是否存在
- 检查全局变量是否存在
- 创建局部变量with
- 不要更改全局数据 。
- 避免检查是否存在全局数据 。
- 请注意 , 内置值将来可能会获得其他属性(自己的或继承的属性) 。
参考资料:https://2ality.com/2022/03/naming-conflicts.html
— END—
《新程序员001-004》全面上市 , 对话世界级大师 , 报道中国IT行业创新创造
— 推荐阅读 —
? “全宇宙首个”用中文编写的操作系统!作者还自创了甲、乙、丙编程语言?
?Firefox 更新:下拉搜索菜单中 , 移除俄罗斯搜索引擎 Yandex 和 Mail.ru
? “当了十年IT程序员 , 我转型做自动驾驶开发的这五年!”
推荐阅读
- Hello|测试 C、Python、Java 等 16 种编程语言的 Hello World:7 种存在 Bug?
- 卢伟|【搞事】卢伟冰要打脸了?Redmi骁龙870新机或命名为K40S
- IT|雪佛兰纯电Blazer高性能版预告图发布 新车或仍以SS命名
- 古生物学界|“鱿鱼鼻祖”被命名为“拜登”
- 网页|曾经“杀手级”的桌面语言 Java 将要退隐江湖?
- 字符|[原]UTF-8字符集成为Java 18默认字符集?发布周期将至,Java 18现身
- Web|[原]JavaScript遭嫌弃,“反JS”主义者兴起
- 语言|[转]曾经“杀手级”的桌面语言Java将要退隐江湖
- 硬件|福特将电动汽车业务命名Model E,曾让马斯克求之不得
- 步骤|文件批量重命名怎么加下划线?