【问题标题】:Extending two instances of objects扩展对象的两个实例
【发布时间】: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 像我需要的那样工作。

【问题讨论】:

标签: javascript jquery object clone


【解决方案1】:

jQuery.extend() 接受多个对象并将属性连接在一起。因此,如果第二个对象包含相同的属性,它将覆盖先前设置的属性。 jQuery.extend() Documentation.

改为使用Object.assign() 传递您的爷爷、孩子和父亲对象。这将使每一个都分开,而不会触及已经完成的事情。

【讨论】:

  • 感谢您的所有回答。请参阅已编辑问题中的““Object.assign()”建议。
【解决方案2】:

好的,正确答案是

var obj1 = $.extend(true, {}, tmpGranpa, tmpFather, child1);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-13
    • 1970-01-01
    • 1970-01-01
    • 2012-07-16
    相关资源
    最近更新 更多