如何优雅更改一个N层嵌套对象属性的值
- 看下边的代码,要加工一个嵌套list的属性值,然后再赋值回去,大概只能这样写:
dp.data.treelist = dp.data.treelist.map(...)
- 由于对象嵌套比较深(有可能N层),每次赋值都需要重复这个嵌套过程(dp.data.treelis) 两次
- 而我们希望的是,调用和赋值,可以(至少看起来)一次完成
- 我们可以利用对象中的 this 指向(父级),减少引用对象层级,实现复用
var obj = {
list:{
data:[1,2,3],
update:function(){
this.data = this.data.map(function(x){
return x * x;
})
}
}
}
obj.list.update()
console.log(obj);
- 上边的方法有两个副作用
- 一是,在纯数据对象中,塞入了 update 这个操作方法
- 二是,同时,update 方法也无法在其它对象中使用
- 所以,我们可以把这种模式的对象抽象出来,做为一个公共的类
function List(list,others){
this.list = list;
for(key in others){
this[key] = others[key];
}
}
List.prototype.setList = function(newList){
this.list = newList;
}
List.prototype.mapSetList = function(fn){
this.list = this.list.map(fn);
}
var obj = {
data:new List([1,2,3,4,5],{
count:100,
code:2,
user:{
name:"zk"
}
})
}
obj.data.setList([5,6,7,8,9]);
obj.data.mapSetList(x=>x*x);
console.log(obj);
- 如此一来,我们就拥有了一个功能丰富且可扩展的 List 对象
- 这使得嵌套层级较深的 list 类的属性赋值变得更加简洁明了,更符合函数式编程的习惯
- 而且 list 实例的方法继续自类的原型,在数据对象中不会被显式的遍历,保证了数据的纯洁性