Node.js에서 객체 복제
node.js에서 객체를 복제하는 가장 좋은 방법은 무엇입니까예를 들어 다음과 같은 상황을 피하고 싶습니다.
var obj1 = {x: 5, y:5};
var obj2 = obj1;
obj2.x = 6;
console.log(obj1.x); // logs 6
객체에는 속성으로 복잡한 유형이 포함될 수 있으므로 간단한 for (var x in obj1)로는 해결되지 않습니다. 재귀 복제본을 직접 작성해야합니까 아니면 보이지 않는 것이 내장되어 있습니까?
가능성 1
프릴이 적은 사본 :
var obj2 = JSON.parse(JSON.stringify(obj1));
가능성 2 (더 이상 사용되지 않음)
주의 :
이제이 솔루션은
에서 더 이상 사용되지 않는 것으로 표시됩니다 .
util._extend () 메소드는 내부 Node.js 모듈 외부에서 사용되도록 설계되지 않았습니다. 커뮤니티는 어쨌든 그것을 찾아서 사용했습니다.더 이상 사용되지 않으며 새 코드에서 사용해서는 안됩니다. JavaScript는 Object.assign ()을 통해 매우 유사한 내장 기능을 제공합니다.
원래 답변 :
:얕은 사본의 경우 노드의 내장
util._extend()
기능을 사용하십시오.
var extend = require('util')._extend;
var obj1 = {x: 5, y:5};
var obj2 = extend({}, obj1);
obj2.x = 6;
console.log(obj1.x); // still logs 5
노드
_extend
기능 의 소스 코드 는 다음에 있습니다 :
https://github.com/joyent/node/blob/master/lib/util.js
exports._extend = function(origin, add) {
// Don't do anything if add isn't an object
if (!add || typeof add !== 'object') return origin;
var keys = Object.keys(add);
var i = keys.length;
while (i--) {
origin[keys[i]] = add[keys[i]];
}
return origin;
};
Object.assign
언급되지 않은 것이 놀랍습니다 .
let cloned = Object.assign({}, source);
사용 가능한 경우 (예 : Babel)
사용할 수 있습니다 .
let cloned = { ... source };
Object.defineProperty(Object.prototype, "extend", {
enumerable: false,
value: function(from) {
var props = Object.getOwnPropertyNames(from);
var dest = this;
props.forEach(function(name) {
if (name in dest) {
var destination = Object.getOwnPropertyDescriptor(from, name);
Object.defineProperty(dest, name, destination);
}
});
return this;
}
});
사용할 수있는 확장 방법을 정의합니다. 이 기사에서 코드가 나온다
var obj2 = JSON.parse(JSON.stringify(obj1));
JQuery에서 확장 기능을 사용할 수 있습니다.
var newClone= jQuery.extend({}, oldObject);
var deepClone = jQuery.extend(true, {}, oldObject);
Node.js 플러그인도 있습니다 :
https://github.com/shimondoodkin/nodejs-clone-extend
JQuery 또는 플러그인없이 수행하려면 여기를 읽으십시오.
http://my.opera.com/GreyWyvern/blog/show.dml/1725165
확인하십시오 . 그것은
및
과 다른 많은 유용한 기능을 가지고 있습니다.이것은 유용 할 수 있습니다 :
"자신의 롤"을 원하지 않는 경우 일부 노드 모듈이 있습니다. 이것은 좋아 보인다 :
https://www.npmjs.com/package/clone
순환 참조를 포함하여 모든 종류의 물건을 처리하는 것처럼 보입니다. 로부터
페이지 :
복제 마스터는 개체, 배열, 날짜 개체 및 RegEx 개체를 복제합니다. 모든 것이 재귀 적으로 복제되므로 예를 들어 객체의 배열에서 날짜를 복제 할 수 있습니다. [...] 순환 참조? 네!
이 코드는 작동하는 원인이기도합니다.
Object.create ()
메서드는 지정된 프로토 타입 객체와 속성으로 새 객체를 만듭니다.
var obj1 = {x:5, y:5};
var obj2 = Object.create(obj1);
obj2.x; //5
obj2.x = 6;
obj2.x; //6
obj1.x; //5
NodeJS에서 객체를 복제하는 간단하고 빠른 방법은 Object.keys (obj) 메소드를 사용하는 것입니다
var a = {"a": "a11", "b": "avc"};
var b;
for(var keys = Object.keys(a), l = keys.length; l; --l)
{
b[ keys[l-1] ] = a[ keys[l-1] ];
}
b.a = 0;
console.log("a: " + JSON.stringify(a)); // LOG: a: {"a":"a11","b":"avc"}
console.log("b: " + JSON.stringify(b)); // LOG: b: {"a":0,"b":"avc"}
Object.keys 메소드에는 JavaScript 1.8.5가 필요합니다. nodeJS v0.4.11은이 방법을 지원합니다물론 중첩 객체의 경우 재귀 기능을 구현해야합니다.
다른 솔루션은 기본 JSON (JavaScript 1.7에서 구현 됨)을 사용하는 것이지만 이전보다 훨씬 느립니다 (~ 10 배 느림)
var a = {"a": i, "b": i*i};
var b = JSON.parse(JSON.stringify(a));
b.a = 0;
Github에는보다 직접적인 포트를 목표로하는 프로젝트도 있습니다
jQuery.extend()
.
https://github.com/dreamerslab/node.extend
에서 수정 된 예 :
var extend = require('node.extend');
var object1 = {
apple: 0,
banana: {
weight: 52,
price: 100
},
cherry: 97
};
var object2 = {
banana: {
price: 200
},
durian: 100
};
var merged = extend(object1, object2);
There is another library lodash, it has clone and cloneDeep, also many other useful function.
Looking for a true clone option, I stumbled across ridcully's link to here:
http://my.opera.com/GreyWyvern/blog/show.dml/1725165
I modified the solution on that page so that the function attached to the Object
prototype is not enumerable. Here is my result:
Object.defineProperty(Object.prototype, 'clone', {
enumerable: false,
value: function() {
var newObj = (this instanceof Array) ? [] : {};
for (i in this) {
if (i == 'clone') continue;
if (this[i] && typeof this[i] == "object") {
newObj[i] = this[i].clone();
} else newObj[i] = this[i]
} return newObj;
}
});
Hopefully this helps someone else as well. Note that there are some caveats... particularly with properties named "clone". This works well for me. I don't take any credit for writing it. Again, I only changed how it was being defined.
You can also use SugarJS in NodeJS.
They have a very clean clone feature: http://sugarjs.com/api/Object/clone
If you're using coffee-script, it's as easy as:
newObject = {}
newObject[key] = value for own key,value of oldObject
Though this isn't a deep clone.
None of the answers satisfied me, several don't work or are just shallow clones, answers from @clint-harris and using JSON.parse/stringify are good but quite slow. I found a module that does deep cloning fast: https://github.com/AlexeyKupershtokh/node-v8-clone
There is no built-in way to do a real clone (deep copy) of an object in node.js. There are some tricky edge cases so you should definitely use a library for this. I wrote such a function for my simpleoo library. You can use the deepCopy
function without using anything else from the library (which is quite small) if you don't need it. This function supports cloning multiple data types, including arrays, dates, and regular expressions, it supports recursive references, and it also works with objects whose constructor functions have required parameters.
Here is the code:
//If Object.create isn't already defined, we just do the simple shim, without the second argument,
//since that's all we need here
var object_create = Object.create;
if (typeof object_create !== 'function') {
object_create = function(o) {
function F() {}
F.prototype = o;
return new F();
};
}
/**
* Deep copy an object (make copies of all its object properties, sub-properties, etc.)
* An improved version of http://keithdevens.com/weblog/archive/2007/Jun/07/javascript.clone
* that doesn't break if the constructor has required parameters
*
* It also borrows some code from http://stackoverflow.com/a/11621004/560114
*/
function deepCopy = function deepCopy(src, /* INTERNAL */ _visited) {
if(src == null || typeof(src) !== 'object'){
return src;
}
// Initialize the visited objects array if needed
// This is used to detect cyclic references
if (_visited == undefined){
_visited = [];
}
// Ensure src has not already been visited
else {
var i, len = _visited.length;
for (i = 0; i < len; i++) {
// If src was already visited, don't try to copy it, just return the reference
if (src === _visited[i]) {
return src;
}
}
}
// Add this object to the visited array
_visited.push(src);
//Honor native/custom clone methods
if(typeof src.clone == 'function'){
return src.clone(true);
}
//Special cases:
//Array
if (Object.prototype.toString.call(src) == '[object Array]') {
//[].slice(0) would soft clone
ret = src.slice();
var i = ret.length;
while (i--){
ret[i] = deepCopy(ret[i], _visited);
}
return ret;
}
//Date
if (src instanceof Date) {
return new Date(src.getTime());
}
//RegExp
if (src instanceof RegExp) {
return new RegExp(src);
}
//DOM Element
if (src.nodeType && typeof src.cloneNode == 'function') {
return src.cloneNode(true);
}
//If we've reached here, we have a regular object, array, or function
//make sure the returned object has the same prototype as the original
var proto = (Object.getPrototypeOf ? Object.getPrototypeOf(src): src.__proto__);
if (!proto) {
proto = src.constructor.prototype; //this line would probably only be reached by very old browsers
}
var ret = object_create(proto);
for(var key in src){
//Note: this does NOT preserve ES5 property attributes like 'writable', 'enumerable', etc.
//For an example of how this could be modified to do so, see the singleMixin() function
ret[key] = deepCopy(src[key], _visited);
}
return ret;
};
npm install node-v8-clone
Fastest cloner, it open native clone method from node.js
var clone = require('node-v8-clone').clone;
var newObj = clone(obj, true); //true - deep recursive clone
Another solution is to encapsulate directly in the new variable using: obj1= {...obj2}
You can prototype object and then call object instance every time you want to use and change object:
function object () {
this.x = 5;
this.y = 5;
}
var obj1 = new object();
var obj2 = new object();
obj2.x = 6;
console.log(obj1.x); //logs 5
You can also pass arguments to object constructor
function object (x, y) {
this.x = x;
this.y = y;
}
var obj1 = new object(5, 5);
var obj2 = new object(6, 6);
console.log(obj1.x); //logs 5
console.log(obj2.x); //logs 6
Hope this is helpful.
참고URL : https://stackoverflow.com/questions/5055746/cloning-an-object-in-node-js
'programing' 카테고리의 다른 글
MVC 컨트롤러 및 액션 메서드를 호출하는 HTML 버튼 (0) | 2020.05.15 |
---|---|
특성을 사용하여 특정 작업에 대해 ASP.NET MVC에서 캐싱 방지 (0) | 2020.05.15 |
누군가 매우 간단한 그래픽 방식으로 코사인 유사성의 예를 제시 할 수 있습니까? (0) | 2020.05.15 |
파일 중간에 특정 줄을 표시하는 빠른 유닉스 명령? (0) | 2020.05.15 |
명령 줄의 숭고한 텍스트 (0) | 2020.05.15 |