Javascript 克隆对象没有参考javascript
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12690107/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Clone Object without reference javascript
提问by EnZo
I have a big object with much data. And i want to clone this in other variable. When i set some param of the instance B has the same result in the original object:
我有一个包含大量数据的大对象。我想在其他变量中克隆它。当我设置实例 B 的一些参数在原始对象中具有相同的结果时:
var obj = {a: 25, b: 50, c: 75};
var A = obj;
var B = obj;
A.a = 30;
B.a = 40;
alert(obj.a + " " + A.a + " " + B.a); // 40 40 40
My output should be 25 30 40. Any ideas?
我的输出应该是 25 30 40。有什么想法吗?
EDIT
编辑
Thanks Everyone. I change the code of dystroy and this is my result:
谢谢大家。我更改了dystroy的代码,这是我的结果:
Object.prototype.clone = Array.prototype.clone = function()
{
if (Object.prototype.toString.call(this) === '[object Array]')
{
var clone = [];
for (var i=0; i<this.length; i++)
clone[i] = this[i].clone();
return clone;
}
else if (typeof(this)=="object")
{
var clone = {};
for (var prop in this)
if (this.hasOwnProperty(prop))
clone[prop] = this[prop].clone();
return clone;
}
else
return this;
}
var obj = {a: 25, b: 50, c: 75};
var A = obj.clone();
var B = obj.clone();
A.a = 30;
B.a = 40;
alert(obj.a + " " + A.a + " " + B.a);
var arr = [25, 50, 75];
var C = arr.clone();
var D = arr.clone();
C[0] = 30;
D[0] = 40;
alert(arr[0] + " " + C[0] + " " + D[0]);
回答by Armel Larcier
If you use an =
statement to assign a value to a var
with an object on the right side, javascript will not copy but reference the object.
如果您使用=
语句将值分配给var
右侧的对象,javascript 将不会复制而是引用该对象。
You can use lodash's clone
method
您可以使用lodash的clone
方法
var obj = {a: 25, b: 50, c: 75};
var A = _.clone(obj);
Or lodash's cloneDeep
method if your object has multiple object levels
或者lodash的cloneDeep
方法,如果你的对象有多个对象级别
var obj = {a: 25, b: {a: 1, b: 2}, c: 75};
var A = _.cloneDeep(obj);
Or lodash's merge
method if you mean to extend the source object
或者lodash的merge
方法,如果你想扩展源对象
var obj = {a: 25, b: {a: 1, b: 2}, c: 75};
var A = _.merge({}, obj, {newkey: "newvalue"});
Or you can use jQuerys extend
method:
或者你可以使用 jQuerysextend
方法:
var obj = {a: 25, b: 50, c: 75};
var A = $.extend(true,{},obj);
Here is jQuery1.11 extend method's source code :
这是jQuery1.11 扩展方法的源代码:
jQuery.extend = jQuery.fn.extend = function() {
var src, copyIsArray, copy, name, options, clone,
target = arguments[0] || {},
i = 1,
length = arguments.length,
deep = false;
// Handle a deep copy situation
if ( typeof target === "boolean" ) {
deep = target;
// skip the boolean and the target
target = arguments[ i ] || {};
i++;
}
// Handle case when target is a string or something (possible in deep copy)
if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
target = {};
}
// extend jQuery itself if only one argument is passed
if ( i === length ) {
target = this;
i--;
}
for ( ; i < length; i++ ) {
// Only deal with non-null/undefined values
if ( (options = arguments[ i ]) != null ) {
// Extend the base object
for ( name in options ) {
src = target[ name ];
copy = options[ name ];
// Prevent never-ending loop
if ( target === copy ) {
continue;
}
// Recurse if we're merging plain objects or arrays
if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
if ( copyIsArray ) {
copyIsArray = false;
clone = src && jQuery.isArray(src) ? src : [];
} else {
clone = src && jQuery.isPlainObject(src) ? src : {};
}
// Never move original objects, clone them
target[ name ] = jQuery.extend( deep, clone, copy );
// Don't bring in undefined values
} else if ( copy !== undefined ) {
target[ name ] = copy;
}
}
}
}
// Return the modified object
return target;
};
回答by I Hate Lazy
While this isn't cloning, one simple way to get your result is to use the original object as the prototype of a new one.
虽然这不是克隆,但获得结果的一种简单方法是使用原始对象作为新对象的原型。
You can do this using Object.create
:
您可以使用Object.create
以下方法执行此操作:
var obj = {a: 25, b: 50, c: 75};
var A = Object.create(obj);
var B = Object.create(obj);
A.a = 30;
B.a = 40;
alert(obj.a + " " + A.a + " " + B.a); // 25 30 40
This creates a new object in A
and B
that inheritsfrom obj
. This means that you can add properties without affecting the original.
这将创建一个新的对象A
,并B
认为继承从obj
。这意味着您可以在不影响原始属性的情况下添加属性。
To support legacy implementations, you can create a (partial)shim that will work for this simple task.
为了支持遗留实现,您可以创建一个(部分)垫片来完成这个简单的任务。
if (!Object.create)
Object.create = function(proto) {
function F(){}
F.prototype = proto;
return new F;
}
It doesn't emulate all the functionality of Object.create
, but it'll fit your needs here.
它不会模拟 的所有功能Object.create
,但它可以满足您的需求。
回答by Denys Séguret
You could define a clone function.
您可以定义一个克隆函数。
I use this one :
我用这个:
function goclone(source) {
if (Object.prototype.toString.call(source) === '[object Array]') {
var clone = [];
for (var i=0; i<source.length; i++) {
clone[i] = goclone(source[i]);
}
return clone;
} else if (typeof(source)=="object") {
var clone = {};
for (var prop in source) {
if (source.hasOwnProperty(prop)) {
clone[prop] = goclone(source[prop]);
}
}
return clone;
} else {
return source;
}
}
var B = goclone(A);
It doesn't copy the prototype, functions, and so on. But you should adapt it (and maybe simplify it) for you own need.
它不会复制原型、函数等。但是您应该根据自己的需要调整它(并可能简化它)。
回答by RobG
A
and B
reference the same object, so A.a
and B.a
reference the same property of the same object.
A
并且B
引用同一个对象,所以A.a
和B.a
引用同一个对象的相同属性。
Edit
编辑
Here's a "copy" function that may do the job, it can do both shallow and deep clones. Note the caveats. It copies all enumerable properties of an object (not inherited properties), including those with falsey values (I don't understand why other approaches ignore them), it also doesn't copy non–existent properties of sparse arrays.
这是一个可以完成这项工作的“复制”功能,它可以执行浅克隆和深克隆。注意注意事项。它复制对象的所有可枚举属性(不是继承的属性),包括那些具有错误值的属性(我不明白为什么其他方法会忽略它们),它也不复制稀疏数组的不存在的属性。
There is no general copy or clone function because there are many different ideas on what a copy or clone should do in every case. Most rule out host objects, or anything other than Objects or Arrays. This one also copies primitives. What should happen with functions?
没有通用的复制或克隆功能,因为对于在每种情况下复制或克隆应该做什么有很多不同的想法。大多数排除主机对象,或除对象或数组以外的任何内容。这个也复制原语。函数应该发生什么?
So have a look at the following, it's a slightly different approach to others.
因此,请查看以下内容,它与其他方法略有不同。
/* Only works for native objects, host objects are not
** included. Copies Objects, Arrays, Functions and primitives.
** Any other type of object (Number, String, etc.) will likely give
** unexpected results, e.g. copy(new Number(5)) ==> 0 since the value
** is stored in a non-enumerable property.
**
** Expects that objects have a properly set *constructor* property.
*/
function copy(source, deep) {
var o, prop, type;
if (typeof source != 'object' || source === null) {
// What do to with functions, throw an error?
o = source;
return o;
}
o = new source.constructor();
for (prop in source) {
if (source.hasOwnProperty(prop)) {
type = typeof source[prop];
if (deep && type == 'object' && source[prop] !== null) {
o[prop] = copy(source[prop]);
} else {
o[prop] = source[prop];
}
}
}
return o;
}