有时,我们可能想要创建一个对象,该对象包含一组数据。如果仅仅是集合,我们可以使用数组。但是有时,需要存储 更多状态,可能就需要存储更多集合相关的元数据。
一种方式是创建这类对象的新版本,添加元数据属性和方法,我们可以在对象上添加属性和方法,包括数组。然而这种方法效率低,且单调乏味。
我们如何使用简单对象,并加上我们需要的方法。处理集合的方法在Array对象上,如何引入到我们的自定义的对象上呢?
<input id="first">
<input id="second">
<script>
console.log('---------------------------复用内置的数组函数--------------------------');
const elems = {
//用于模拟数组长度,存储集体中元素的数量
length: 0,
add: function (elem) {
//实现向集合添加元素的add方法。数组的原型方法既然已经实现,那么为什么不直接使用它。
Array.prototype.push.call(this, elem);
},
gather: function (id) {
//实现通过ID查找元素并添加集合中的方法
this.add(document.getElementById(id));
},
find: function (callback) {
//复用数组的find方法,实现在集合中查找元素的方法
return Array.prototype.find.call(this, callback);
}
};
elems.gather("first");
if (elems.length === 1 && elems[0].nodeType) {
console.log("element[0]'s nodeType:" + elems[0].nodeType + ",id:" + elems[0].id);
console.log("Verify that we have an element in our stash");
}
elems.gather("second");
if (elems.length === 2 && elems[1].nodeType) {
console.log("element[1]'s nodeType:" + elems[1].nodeType);
console.log("Verity the other insertion");
}
let founds = elems.find(elem => elem.id === 'second');
console.log("founds:" + JSON.stringify(founds));
if (founds && founds[0].id === 'second') {
console.log("We have found our element");
}
</script>
出现的问题?
为什么elems.find(elem => elem.id === 'second')没有执行成功?
在本例中,我们创建对象,并模拟一些数组的行为。首先定义length属性用于存储元素的数量,与数组类似。然后定义在末尾添加元素的add方法:
add: function (elem) {
//实现向集合添加元素的add方法。数组的原型方法既然已经实现,那么为什么不直接使用它。
Array.prototype.push.call(this, elem);
}
复用Javascript数组的方法:Array.prototype.push,而不是自己编写代码。
通常,Array.prototype.push方法通过自身函数上下文执行数组。但是,我们通过使用call方法,将上下文改为我定义的对象。push方法增加length属性(类似于数组的length属性),为所添加的元素增加编号。通过这种方式,该对象的行为是颠覆性的,也说明可变对象上下文的用途。
add方法接收一个待添加到对象中的元素作为参数。有时可能没有类似的元素,因此,我们又定义了一个gather方法,该方法更为方便,可以通过ID查找到元素并添加到对象中。
gather: function (id) {
//实现通过ID查找元素并添加集合中的方法
this.add(document.getElementById(id));
}
最后,利用内置的数组方法find方法实现自定义对象的find方法,用于查找自定义对象中任意元素。
find: function (callback) {
//复用数组的find方法,实现在集合中查找元素的方法
return Array.prototype.find.call(this, callback);
}
参考《JavaScript忍者秘籍》