您可以在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”。
通过任何机制,有没有办法在可能的情况下做某事?我有兴趣听到的机制包括:
答案 0 :(得分:2)
不幸的是,您当前无法在节点中执行此操作,因为节点跨模块共享相同的内置对象。
这很糟糕,因为它可能带来意想不到的副作用,就像它过去在浏览器历史中发生的那样,这就是为什么现在每个人都大喊大叫“不要扩展内置对象”。
其他commonJS环境遵循更多原始的commonJS规范,因此您不共享内置对象,但每个模块都有自己的。例如在jetpack中,Mozilla SDK用于构建Firefox的附加组件,它以这种方式工作:所以你的内置对象是每个模块,如果你扩展它就不会发生冲突。
无论如何,总的来说,我认为现在扩展内置对象并不是必需的,应该避免使用。
答案 1 :(得分:0)
这是不可能的,因为本机类型只有一个原型的源。一般来说,我会不鼓励使用原生类型的原型。您不仅限制了可移植性(正如您所指出的那样),而且您可能也在不知不觉中覆盖现有属性或未来属性。这也创造了很多魔法"在你的代码中,未来的维护者将难以追踪。这条规则唯一真正的例外是polyfils。如果您的环境尚未实现新功能,那么polyfil可以为您提供此功能。