7

我可以在创建对象时在该对象内部保留一个对象的副本吗

这是我创建一个新学生对象的函数:

function student(id, name, marks){
    this.id = id;
    this.name = name;
    this.marks = marks;
}

我想在对象内部初始化时创建对象的副本:我想出了这个:

function student(id, name, marks){
    this.id = id;
    this.name = name;
    this.marks = marks;
    this.baseCopy = this;
}

但问题是它给了我baseCopy中当前对象副本的无限循环;而且,当我更新对象的任何属性时,它也会自动更新。

1. 这怎么可能,我可以在创建对象时在该对象内部保留具有初始值的对象的副本?

4

3 回答 3

7

由于您已经在使用 jQuery,通用答案是:

this.baseCopy = $.extend(true, {}, this);

将生成当时存在的任何属性值的“深层”副本,而不会递归地引用自身。

注意- 我确实包含了一些通用的 JS 代码,但是 OP 完全改变了这个问题,所以恢复到只使用 jQuery 会更简单。这当然会复制直接存在于对象上的任何方法,尽管如果编写得当,这些方法将位于对象的原型上。

于 2012-12-20T09:02:51.380 回答
2

一个没有 jQuery 的替代方案:(
你知道它也可以不用。)

function student(id, name, marks){
    this.id = id;
    this.name = name;
    this.marks = marks;

    var tempCopy = {}; // Initialize a temporary variable to copy the student to.
    for(key in this){   // Loop through all properties on this (student)
        if(this.hasOwnProperty(key)){ // Object.prototype fallback. I personally prefer to keep it in, see Alnitak's comment.
            tempCopy[key] = this[key]; // Copy the property
        }
    }
    this.baseCopy = tempCopy; // "Save" the copy to `this.baseCopy`
}

var s = new student(1, 'Jack', [5,7]);
s.marks = s.marks.concat([6,8]); // Jack's gotten 2 new marks.

console.log(s.name + "'s marks were: ", s.baseCopy.marks);
console.log(s.name + "'s marks are: ", s.marks);
// Logs:
// Jack's marks were:  [5, 7]
// Jack's marks are:  [5, 7, 6, 8]

这样做的好处是它会自动复制学生的所有属性,而不必baseCopy手动“设置”它们。
此外,由于它不使用 jQuery,因此速度更快。在处理大量数据时,这可能很重要。

于 2012-12-20T09:10:38.007 回答
1

以下方法对我有用(可能不是最好的解决方案,可能还有另一种涉及对象原型的方法)

function BaseStudent(id, name, marks) {
    this.id = id;
    this.name = name;
    this.marks = marks;
}

function Student(id, name, marks) {
    this.baseCopy = new BaseStudent(id, name, marks);
    BaseStudent.call(this, id, name, marks);
}

var s = new Student(1, 'Name', 100);

console.log(s.id); // logs 1
console.log(s.name); // logs 'Name'
console.log(s.marks); // logs 100

s.name = 'AnotherName';

console.log(s.name); // logs 'AnotherName'
console.log(s.baseCopy.name);​ // logs 'Name'
于 2012-12-20T09:16:42.210 回答