official - extensión profunda(como jQuery) para nodeJS
npm jquery (11)
Estoy luchando con copias profundas de objetos en nodeJS. mi propio alcance es una mierda. la extensión del subrayado es plana. aquí hay variantes de extensiones bastante simples en stackexchange, pero ninguna está ni cerca de jQuery.extend (true, {}, obj, obj, obj) ... (la mayoría son terribles y arruinan los beneficios del código asnyc).
por lo tanto, mi pregunta: ¿hay una buena copia profunda para NodeJS? Alguien ha portado jQuery''s?
En Node.js, puede usar Extendify para crear una función _.extend que admita la extensión de objetos anidados (extensión profunda) y también sea inmutable a sus parámetros (por lo tanto, clonación profunda).
_.extend = extendify({
inPlace: false,
isDeep: true
});
Esto funciona para la extensión de objetos profundos ... ten en cuenta que reemplaza las matrices en lugar de sus valores, pero que obviamente se puede actualizar a tu gusto. Debe mantener las capacidades de enumeración y todas las otras cosas que probablemente desee que haga
function extend(dest, from) {
var props = Object.getOwnPropertyNames(from), destination;
props.forEach(function (name) {
if (typeof from[name] === ''object'') {
if (typeof dest[name] !== ''object'') {
dest[name] = {}
}
extend(dest[name],from[name]);
} else {
destination = Object.getOwnPropertyDescriptor(from, name);
Object.defineProperty(dest, name, destination);
}
});
}
Por favor use el módulo de utilidades incorporado:
var extend = require(''util'')._extend;
var merged = extend(obj1, obj2);
Quieres jQuery, así que solo úsalo:
function extend() {
var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {},
i = 1,
length = arguments.length,
deep = false,
toString = Object.prototype.toString,
hasOwn = Object.prototype.hasOwnProperty,
push = Array.prototype.push,
slice = Array.prototype.slice,
trim = String.prototype.trim,
indexOf = Array.prototype.indexOf,
class2type = {
"[object Boolean]": "boolean",
"[object Number]": "number",
"[object String]": "string",
"[object Function]": "function",
"[object Array]": "array",
"[object Date]": "date",
"[object RegExp]": "regexp",
"[object Object]": "object"
},
jQuery = {
isFunction: function (obj) {
return jQuery.type(obj) === "function"
},
isArray: Array.isArray ||
function (obj) {
return jQuery.type(obj) === "array"
},
isWindow: function (obj) {
return obj != null && obj == obj.window
},
isNumeric: function (obj) {
return !isNaN(parseFloat(obj)) && isFinite(obj)
},
type: function (obj) {
return obj == null ? String(obj) : class2type[toString.call(obj)] || "object"
},
isPlainObject: function (obj) {
if (!obj || jQuery.type(obj) !== "object" || obj.nodeType) {
return false
}
try {
if (obj.constructor && !hasOwn.call(obj, "constructor") && !hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
return false
}
} catch (e) {
return false
}
var key;
for (key in obj) {}
return key === undefined || hasOwn.call(obj, key)
}
};
if (typeof target === "boolean") {
deep = target;
target = arguments[1] || {};
i = 2;
}
if (typeof target !== "object" && !jQuery.isFunction(target)) {
target = {}
}
if (length === i) {
target = this;
--i;
}
for (i; i < length; i++) {
if ((options = arguments[i]) != null) {
for (name in options) {
src = target[name];
copy = options[name];
if (target === copy) {
continue
}
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 : {};
}
// WARNING: RECURSION
target[name] = extend(deep, clone, copy);
} else if (copy !== undefined) {
target[name] = copy;
}
}
}
}
return target;
}
y una pequeña prueba para demostrar que hace copias profundas
extend(true,
{
"name": "value"
},
{
"object": "value",
"other": "thing",
"inception": {
"deeper": "deeper",
"inception": {
"deeper": "deeper",
"inception": {
"deeper": "deeper"
}
}
}
}
)
Pero recuerde proporcionar la atribución: https://github.com/jquery/jquery/blob/master/src/core.js
Sé que esta es una vieja pregunta, pero me gustaría incluir la fusión de Lodash en la mezcla como una buena solución. Recomiendo lodash para funciones de utilidad en general :)
También puede usar mi versión del complemento extensible https://github.com/maxmara/dextend
Una respuesta rápida y sucia a las copias profundas es solo hacer trampa con un poco de JSON. No es el más eficiente, pero hace el trabajo extremadamente bien.
function clone(a) {
return JSON.parse(JSON.stringify(a));
}
Versión whet.extend llamada whet.extend
Reescribo node-extend con CoffeeScript y agrego el paquete de pruebas travis-ci, porque necesito un profundo manejo en Node para mí, así que ahora está aquí.
Y sí, creo que en algún caso es absolutamente correcto utilizar una fusión profunda, por ejemplo, la uso en las funciones de configuración, cuando necesitamos fusionar las ramas predeterminadas y de usuario juntas.
Ya ha sido portado. node-extend
Tenga en cuenta que el proyecto no tiene pruebas y no tiene mucha popularidad, por lo tanto, use bajo su propio riesgo.
Como se mencionó, probablemente no necesite copias en profundidad. Intenta cambiar tus estructuras de datos para que solo necesites copias superficiales.
Pocos meses después
Escribí un módulo más pequeño en su lugar, le recomiendo que use xtend . No tiene una implementación que contenga jQuery baggage ni tiene errores como node-extend does.
node-extend hace profundo y tiene una sintaxis jQuery familiar