참조 자바 스크립트가없는 객체 복제
데이터가 많은 큰 객체가 있습니다. 그리고 다른 변수에서 이것을 복제하고 싶습니다. 인스턴스 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
내 결과는 25 30 40이어야합니다. 어떤 아이디어?
편집하다
고마워요 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]);
=
명령문을 사용 var
하여 오른쪽에 오브젝트가 있는 값을 지정하면 javascript는 오브젝트를 복사하지 않고 참조합니다.
lodash의 clone
방법을 사용할 수 있습니다
var obj = {a: 25, b: 50, c: 75};
var A = _.clone(obj);
또는 cloneDeep
객체에 여러 객체 레벨이있는 경우 lodash의 방법
var obj = {a: 25, b: {a: 1, b: 2}, c: 75};
var A = _.cloneDeep(obj);
또는 merge
소스 객체를 확장하려는 경우 lodash의 방법
var obj = {a: 25, b: {a: 1, b: 2}, c: 75};
var A = _.merge({}, obj, {newkey: "newvalue"});
또는 jQuerys extend
메소드를 사용할 수 있습니다 .
var obj = {a: 25, b: 50, c: 75};
var A = $.extend(true,{},obj);
다음은 jQuery 1.11 extend 메소드의 소스 코드입니다.
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;
};
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
:
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 inherits from obj
. This means that you can add properties without affecting the original.
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.
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.
A
and B
reference the same object, so A.a
and B.a
reference the same property of the same object.
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;
}
참고URL : https://stackoverflow.com/questions/12690107/clone-object-without-reference-javascript
'programing tip' 카테고리의 다른 글
열 이름으로 사용 된 예약어를 어떻게 이스케이프합니까? (0) | 2020.06.26 |
---|---|
Rails 직렬화를 사용하여 해시를 데이터베이스에 저장 (0) | 2020.06.26 |
같은 클래스의 다른 생성자에서 생성자 호출 (0) | 2020.06.26 |
numpy 배열이 비어 있는지 여부를 어떻게 확인할 수 있습니까? (0) | 2020.06.26 |
URL과 파일 이름을 안전하게하기 위해 문자열을 삭제 하시겠습니까? (0) | 2020.06.26 |