每个JS意见领袖都说扩展原生对象是一种不好的做法.但为什么?我们是否获得了性能?他们是否害怕有人以"错误的方式"做到这一点,并添加了可枚举的类型Object,几乎破坏了任何对象上的所有循环?
以TJ Holowaychuk的should.js为例.他增加了一个简单的getter来Object,一切工作正常(来源).
Object.defineProperty(Object.prototype, 'should', {
set: function(){},
get: function(){
return new Assertion(Object(this).valueOf());
},
configurable: true
});
Run Code Online (Sandbox Code Playgroud)
这真的很有道理.例如,可以扩展Array.
Array.defineProperty(Array.prototype, "remove", {
set: function(){},
get: function(){
return removeArrayElement.bind(this);
}
});
var arr = [0, 1, 2, 3, 4];
arr.remove(3);
Run Code Online (Sandbox Code Playgroud)
是否有任何反对扩展本机类型的论据?
谷歌JavaScript风格指南建议不要扩展Array.prototype.但是,我Array.prototype.filter = Array.prototype.filter || function(...) {...}在浏览器中使用它(和类似方法)的方式不存在.MDN实际上提供了类似的例子.
我知道Object.prototype问题,但Array不是哈希表.
扩展时会出现什么问题,这会让Array.prototypeGoogle提出反对意见?
我已经阅读了一些文章,建议在JavaScript中扩展内置对象是一个坏主意.比方说我添加一个first函数Array...
Array.prototype.first = function(fn) {
return this.filter(fn)[0];
};
Run Code Online (Sandbox Code Playgroud)
太好了,所以现在我可以根据谓词得到第一个元素.但是当ECMAScript-20xx决定首先添加到规范并以不同方式实现时会发生什么? - 好吧,突然之间,我的代码假定了一个非标准的实现,开发人员失去信心等等.
那么我决定创建自己的类型......
var Enumerable = (function () {
function Enumerable(array) {
this.array = array;
}
Enumerable.prototype.first = function (fn) {
return this.array.filter(fn)[0];
};
return Enumerable;
}());
Run Code Online (Sandbox Code Playgroud)
所以现在,我可以将一个数组传递给一个新的Enumerable,然后在Enumerable实例上调用它.大!我尊重ECMAScript-20xx规范,我仍然可以做我想做的事情.
然后发布了ES20XX + 1规范,它引入了Enumerable一种甚至没有第一种方法的类型.现在发生了什么?
本文的关键归结为此; 扩展内置类型有多糟糕,以及我们如何在将来避免实现冲突?
注意:命名空间的使用可能是解决这个问题的一种方法,但话说回来,它不是!
var Collection = {
Enumerable: function () { ... }
};
Run Code Online (Sandbox Code Playgroud)
当ECMAScript规范引入时会发生什么Collection?
最近,鉴于对ECMAScript 5中定义属性的更改,我重新讨论了是否可以安全地扩展本机JavaScript原型的问题.事实上,我一直在扩展像Array和Function这样的原型,但出于显而易见的原因,我避免使用Object.在使用Jasmine的单元测试中,通过将Object.prototype规范添加到我自己的个人框架的规范中,使用非可枚举函数扩展Object.prototype 似乎是安全的.但是,像"type"属性这样的数据属性,使用任何异常处理的getter/setter都会产生意想不到的后果.仍然存在与其他图书馆发生冲突的可能性 - 尽管在我的工作中,几乎没有出现过.然而,只要函数不可枚举,看起来扩展Object.prototype就可以是安全的.
你怎么看?现在扩展Object.prototype是否安全?请讨论.
Ember使用类似的东西:
val: function(){
...
}.property()
Run Code Online (Sandbox Code Playgroud)
和类似的东西:
func: function(){
}.observes('someValue')
Run Code Online (Sandbox Code Playgroud)
我认为你可以在一个函数的末尾添加一个属性的事实非常简洁,并希望复制它.但是,我无法找到源中的任何一个实现,并且我想知道是否有人知道?
另外,更重要的是,究竟发生了什么?
我有一个'自定义'目录,我想存储对内置对象原型的任何更改.每个被修改的内置对象都有自己的文件(即custom/String.js任何修改String.prototype).
除了这些文件之外,我还将调用一个文件custom/All.js来导出要使用的自定义功能.
All.js
export * from './String'
export {Multiply} from './Array'
Run Code Online (Sandbox Code Playgroud)
main.js
import * from './custom/All'
Run Code Online (Sandbox Code Playgroud)
String.js
// something like this
export String.prototype.doSomething = function() {}
Run Code Online (Sandbox Code Playgroud)
可以这样做吗?
javascript ×6
prototype ×2
coding-style ×1
ecmascript-5 ×1
ecmascript-6 ×1
ember.js ×1
es6-modules ×1