有没有一种方法可以在javascript中隔离本机对象扩展

Is there a way to isolate native-object extensions in javascript?

本文关键字:javascript 隔离 本机 扩展 对象 方法 一种 有没有      更新时间:2023-09-26

您可以在javascript中扩展本机对象。例如,sugar.js扩展了Array、String和Function等。本机对象扩展可能非常有用,但本质上会破坏封装——也就是说,如果有人使用相同的扩展名(覆盖另一个扩展),就会破坏封装。

如果您可以为特定的范围扩展对象,那将是非常好的。例如,能够在node.js:中做这样的事情

// myExtension1.js
Object.prototype.x = 5
exports.speak = function() {
  var six = ({}.x+1)
  console.log("6 equals: "+six)
}
// myExtension2.js
Object.prototype.x = 20
exports.speak = function() {
  var twenty1 = ({}.x+1)
  console.log("21 equals: "+twenty1)
}

并拥有这项工作的权利:

// test.js
var one = require('myExtension1')
var two = require('myExtension2')
one.speak(); // 6 equals: 6
two.speak(); // 21 equals: 21

当然,在现实中,这将打印出第一个"6等于:21"。

有没有办法,通过任何机制,在可能的地方做一些事情?我感兴趣的机制包括:

  • 纯javascript
  • Node.js
  • Node.js的C++扩展

不幸的是,目前在节点中无法做到这一点,因为节点在模块之间共享相同的内置对象。

这很糟糕,因为它可能会带来意想不到的副作用,就像过去浏览器历史上发生的那样,这就是为什么现在每个人都在大喊"不要扩展内置对象"。

其他commonJS环境更多地遵循原始的commonJS规范,因此您不共享内置对象,但每个模块都有自己的对象。例如,在构建Firefox插件的Mozilla SDK jetpack中,它是这样工作的:所以内置对象是每个模块的,如果扩展一个,就不会发生冲突。

无论如何,总的来说,我认为现在扩展内置对象并不是真正必要的,应该避免。

这是不可能的,因为本机类型的原型只有一个源。总的来说,我不鼓励与原生类型的原型打交道。你不仅限制了你的可移植性(正如你所指出的),而且你可能在不知不觉中覆盖了现有的属性或未来的属性。这也在您的代码中创造了许多"魔力",未来的维护人员将很难找到这些"魔力"。这个规则唯一真正的例外是polyfils。如果您的环境尚未实现新功能,那么polyfil可以为您提供此功能。