I'm trying to apply the object properties from objA to objB but I realised Ext.apply is flawed (or blessing?) in a way where it only applies first level objects together.
Example:
var objA = {
name: 'objA',
baseParams: {
cols: [1,2,3,4,5]
}
};
//used in subclass
var objB = {
name: 'objB',
baseParams: {
limit: 50,
sort: 'name'
}
};
//used in baseclass
var objC = {
name: 'objC',
baseParams: {
as_hash: true,
limit: 20
}
};
Ext.apply(objB,objA); //used in subclass
Ext.apply(objC,objB); //used in baseclass
Example will output:
obj = {
name: 'objA',
baseParams: {
cols: [1,2,3,4,5]
}
};
I'd like this output instead (expected output):
obj = {
name: 'objA',
baseParams: {
cols: [1,2,3,4,5],
as_hash: true,
limit: 50,
sort: 'name'
}
};
How can I achieve this without 开发者_开发知识库doing this?
// subclass:
var bpTemp = {};
bpTemp.baseParams = Ext.apply(objB.baseParams, objA.baseParams);
Ext.apply(objB,objA);
Ext.apply(objB,bpTemp);
// base class:
var bpTemp = {};
bpTemp.baseParams = Ext.apply(objC.baseParams, objB.baseParams);
Ext.apply(objC,objB);
Ext.apply(objC,bpTemp);
You can change up the way Ext.apply() works so that a 4th argument can be a boolean implying "deep" apply -- this will work with your example (deep defaults to true):
Ext.apply = function(o, c, defaults, deep){
deep = deep!==false;
// no "this" reference for friendly out of scope calls
if(defaults){
Ext.apply(o, defaults);
}
if(o && c && typeof c == 'object'){
for(var p in c){
o[p] = (deep && Ext.isObject(o[p]) && Ext.isObject(c[p])) ? Ext.apply(o[p], c[p]) : c[p];
}
}
return o;
};
You can try a recursive solution, with a few special cases, as below:
function deepApply(receiver, config, defaults) {
if (defaults) {
deepApply(receiver, defaults);
}
if (receiver && config && typeof config == 'object') {
for (var p in config) {
if (typeof config[p] != 'object' || Ext.isArray(config[p])) {
receiver[p] = config[p];
} else {
if (typeof receiver[p] != 'object') {
receiver[p] = {};
}
deepApply(receiver[p], config[p]);
}
}
}
return receiver;
}
精彩评论