【发布时间】:2018-08-01 08:21:31
【问题描述】:
我无法扩展这种对象层次结构以防止事情混乱。 我的 HTML 测试文件包含以下 JS
(index.html)
<script type="text/javascript" src="jquery-3.1.0.min.js"></script>
<script type="text/javascript" src="granpa.js"></script>
<script type="text/javascript" src="father.js"></script>
<script type="text/javascript" src="child1.js"></script>
爷爷是个很简单的对象
(granpa.js)
var granpa = {
myname: 'Granpa',
mydata: {age: 80, salary: undefined}
};
此测试侧重于“myname”变量。我包含“mydata”只是为了指出我需要一个深度递归对象扩展。
父亲就像
(father.js)
var father = {
myname: 'Father',
mydata: {age: 50, salary: 30000}
};
Child 1 类似,而且它包含合并对象和显示测试数据的代码。
(child1.js)
var child1 = {
myname: 'Child 1',
mydata: {age: 19, salary: 15000}
};
/* I clone granpa to a temporary object, to be sure not to modify the original*/
var tmpGranpa = $.extend(true, granpa);
/* I clone father to a temporary object, to be sure not to modify the original*/
var tmpFather = $.extend(true, father);
/* Merge all: again producing a brand new obj1, to not mess up the originals */
var obj1 = $.extend(true, tmpGranpa, tmpFather, child1);
$(document).ready(function(){
console.log('Check obj1 result: '+obj1.myname);
console.log('Check granpa was not overridden: '+granpa.myname);
console.log('Check father was not overridden: '+father.myname);
});
输出是
Check obj1 result: Child 1
Check granpa was not overridden: Granpa
Check father was not overridden: Father
请注意我用过
$.extend(true, ...)
按照 jQuery 手册的建议,执行对象的深度递归复制。
如您所见,一切都很好。 现在,让我们添加第二个孩子
(index.html)
<script type="text/javascript" src="jquery-3.1.0.min.js"></script>
<script type="text/javascript" src="granpa.js"></script>
<script type="text/javascript" src="father.js"></script>
<script type="text/javascript" src="child1.js"></script>
<script type="text/javascript" src="child2.js"></script>
孩子 2 文件将是
(child2.js)
var child2 = {
myname: 'Child 2',
mydata: {age: 11, salary: 0}
};
/* I clone granpa to a temporary object, to be sure not to modify the original*/
var tmpGranpa = $.extend(true, granpa);
/* I clone father to a temporary object, to be sure not to modify the original*/
var tmpFather = $.extend(true, father);
/* Merge all: again producing a brand new obj2, to not mess up the originals */
var obj2 = $.extend(true, tmpGranpa, tmpFather, child2);
当然,我重新使用了“tmpFather”和“tmpGranpa”变量。好的。它们是暂时的,我不在乎。
现在,在 child1.js(这是我们的入口点)中,我添加了 child 2 的检查
(child1.js)
console.log('Check obj1 result: '+obj1.myname);
console.log('Check obj2 result: '+obj2.myname);
console.log('Check granpa was not overridden: '+granpa.myname);
console.log('Check father was not overridden: '+father.myname);
输出是
Check obj1 result: Child 2
Check obj2 result: Child 2
Check granpa was not overridden: Granpa
Check father was not overridden: Father
为什么? 有没有办法构建这样的对象(obj1 和 obj2)来扩展父亲和爷爷,而保持原始对象(父亲、爷爷、孩子 1、孩子 2)不受影响,并且不会弄乱所有属性?
提前谢谢你。
“Object.assign()”建议
Object.assign 的问题在于它似乎没有像 $.extend 那样添加缺失的属性。看这个例子
var granpa = {
myname: 'Granpa',
mydata: {age: 80, salary: undefined}
};
var father = {
myname: 'Father',
mydata: {age: 50, salary: 30000}
};
var child1 = {
myname: 'Child 1',
mydata: {salary: 15000} /* Note: "age" property missing!!! */
};
var newObj = Object.assign({}, granpa, father, child1);
console.log(newObj.mydata.age);
输出是
undefined
我需要这样的行为,因为“年龄”就像一个可以被覆盖或不被覆盖的设置。如果 child1 有“age”,那么它应该覆盖父亲和爷爷的,如果 child1 中缺少“age”(如示例中所示),则 child1 应该继承父亲的年龄。
$.extend 像我需要的那样工作。
【问题讨论】:
-
您查看过
Object.assign()吗? developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… -
只需将
$.extend或Object.assign的第一个参数设为空即可:$.extend({}, ....)以避免现有对象的突变。
标签: javascript jquery object clone