3

您可以在 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
  • 节点.js
  • Node.js 的 C++ 扩展
4

2 回答 2

2

不幸的是,您目前无法在 node 中执行此操作,因为 node 跨模块共享相同的内置对象。

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

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

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

于 2013-07-22T06:51:49.667 回答
0

这是不可能的,因为原生类型的原型只有一个来源。一般来说,我不鼓励使用原生类型的原型。您不仅限制了您的可移植性(正如您所指出的),而且您还可能在不知不觉中覆盖了现有属性或未来属性。这也会在你的代码中创造很多“魔法”,未来的维护者将很难追踪。这条规则唯一真正的例外是 polyfils。如果您的环境尚未实现新功能,那么 polyfil 可以为您提供此功能。

于 2013-07-22T06:20:08.357 回答