我很久以前一直愿意将本机阵列和常规对象之间的界限完全模糊,不仅扩展了与ES5中阵列具有相同功能的对象,而且还捆绑了我双方的自定义包装方法。扩展常规对象以支持ES5阵列功能的问题
几个聪明的人想到了这些范式的变化。就像安格斯·克罗尔文章javascript-object-keys-finally中提到:
“此外,随着阵列和有规则物体的模糊之间的界限(通过自定义的getter和setter辅助 ),我们很可能会看到通用 增长“基于阵列像“享受两全其美的对象 - 非数字 标识符和对由Array.prototype定义的丰富API集的访问 EcmaScript 5通过引入 泛型方法明显地抢先了这种趋势,通过一种类型但任何人都可以使用。“
一路上,他获得编码的文章的事情: extending-objects-with-javascript-getters
function extendAsArray(obj) {
if (obj.length === undefined || obj.__lookupGetter__('length')) {
var index = 0;
for (var prop in obj) {
if(!obj.__lookupGetter__(prop)) {
(function(thisIndex, thisProp) {
obj.__defineGetter__(thisIndex, function() {return obj[thisProp]});
})(index, prop)
index++;
}
};
obj.__defineGetter__("length", function() {return index});
}
return obj;
}
var myObj = {
left:50,
top:20,
width:10,
height:10
}
extendAsArray(myObj);
[].map.call(myObj,function(s){return s+' px'}).join(', ');
//"50px ,20px ,10px, 10px"
这种做法是非常有趣的对我。但是,它也似乎遭受了一些严重的问题!
如何使用一些新属性扩展原始myObj模型? 我们是否应该在每次更改物业时都运行
extendAsArray
以更新其涉及的length
属性?当一个属性发生变化时,它不仅仅是相关的
length
属性; 数组索引也应该更新,因为类似数组的属性请求肯定是未定义的。因此,当console.log(myObj.length) -> 4 myObj.zAxis=0
然后
console.log(myObj[4]) // -> undefined! console.log(myObj.length) // -> 4!
我已经相应地修改安格斯代码,因此它支持在请求length
属性的自动更新:
function extendAsArray(obj) {
var index = 0;
for(var prop in obj){
if(!obj.__lookupGetter__(prop)){
(function(thisIndex, thisProp){
Object.defineProperty(obj, thisIndex, {
get: function(){return obj[thisProp]}
, enumerable: true
, configurable: true
, writeable: true
});
})(index, prop)
index++;
}
}
if(!obj.__lookupGetter__('length')){
Object.defineProperty(obj, 'length', {
get: function(){
return extendAsArray(obj);
}
, configurable: true
, writeable: true
});
return obj;
}
else{
return index;
}
}
的问题是:我们如何更新对象的数组索引和它的length
道具属性更改,添加或删除后属于哪个?
我应该用Object.watch
?
还有一个未解决的问题:如何干涉我自己的未修饰的实用程序库,并以一致的方式为对象创建了它?
我使用的是相同的代码库两种类型:z.Object({}).mapEvery
不一样z.Object([]).mapEvery
请避免提及JQuery的,并强调为好。我已经为这两种类型获得了一个全面的自定义方法列表,并且我愿意使用完成的标准和我未修改的标准完成,但我不愿意重构它!
对象和数组之间的区别不仅仅是数组的长度属性。 据我所知:-)有几个ES5枚举方法,如地图,过滤器被添加到最近的浏览器,但IE9也支持它。 这些方法完全无法从本地对象获得。 – 2013-03-13 02:47:55
这是: https://github.com/zludany/enumerable.js – 2013-05-21 02:14:14
Both [* map *](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4。 4.19)和[* filter *](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.20)在ES5中,它们都是“有意通用的”而不是“要求[他们]这个值是一个数组对象“,所以他们将在具有合适属性的任何本地对象上工作。它们不需要与主机对象一起工作(但是在许多浏览器中都可以使用DOM对象)。 – RobG 2013-05-21 02:33:17