-
-
Save duzun/32101d04cc089c45d0d59806f858a811 to your computer and use it in GitHub Desktop.
JavaScript: clona o extiende un objeto
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Creates a deep copy of an object | |
* @param {Any} from: Source object to clone | |
* @param {Object} dest: (Optional) destination object to merge with | |
* @return {Any} The cloned object | |
*/ | |
var clone = (function() { | |
var _toString = Object.prototype.toString; | |
function _clone (from, dest, objectsCache) { | |
var prop; | |
// determines whether @from is a primitive value or a function | |
if (from === null || typeof from !== "object") return from; | |
// checks if @from refers to an object created previously | |
if (_toString.call(from) === "[object Object]") { | |
if (objectsCache.filter(function (item) { | |
return item === from; | |
}).length) return from; | |
// keeps reference to created objects | |
objectsCache.push(from); | |
} | |
// determines whether @from is an instance of any of the following constructors | |
if (from.constructor === Date || from.constructor === RegExp || from.constructor === Function || | |
from.constructor === String || from.constructor === Number || from.constructor === Boolean) { | |
return new from.constructor(from); | |
} | |
if (from.constructor !== Object && from.constructor !== Array) return from; | |
// creates a new object and recursively iterates over its properties | |
dest = dest || new from.constructor(); | |
for (prop in from) { | |
// TODO: allow overwrite existing properties | |
dest[prop] = (typeof dest[prop] === "undefined" ? | |
_clone(from[prop], null, objectsCache) : | |
dest[prop]); | |
} | |
return dest; | |
} | |
return function (from, dest) { | |
var objectsCache = []; | |
return _clone(from, dest, objectsCache); | |
}; | |
}()); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Creates a deep copy of an object | |
* @param {Any} from: Source object to clone | |
* @param {Object} dest: (Optional) destination object to merge with | |
* @return {Any} The cloned object | |
*/ | |
var clone = (() => { | |
const _toString = Object.prototype.toString; | |
function _clone(from, dest, objectsCache) { | |
let prop; | |
// determines whether @from is a primitive value or a function | |
if (from === null || typeof from !== 'object') return from; | |
// checks if @from refers to an object created previously | |
if (_toString.call(from) === '[object Object]') { | |
if (objectsCache.filter((item) => item === from).length) return from; | |
// keeps reference to created objects | |
objectsCache.push(from); | |
} | |
// determines whether @from is an instance of any of the following constructors | |
if (from.constructor === Date || from.constructor === RegExp || from.constructor === Function || | |
from.constructor === String || from.constructor === Number || from.constructor === Boolean) { | |
return new from.constructor(from); | |
} | |
if (from.constructor !== Object && from.constructor !== Array) return from; | |
// creates a new object and recursively iterates over its properties | |
dest = dest || new from.constructor(); | |
for (prop in from) { | |
// TODO: allow overwrite existing properties | |
dest[prop] = (typeof dest[prop] === 'undefined' ? | |
_clone(from[prop], null, objectsCache) : | |
dest[prop]); | |
} | |
return dest; | |
} | |
return (from, dest) => { | |
const objectsCache = []; | |
return _clone(from, dest, objectsCache); | |
}; | |
})(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Freeman() { | |
this.name = "Gordon Freeman"; | |
this.character = "Freeman"; | |
this.game = "Half-Life"; | |
this.friends = []; | |
} | |
var freeman, david; | |
freeman = new Freeman(); | |
david = { | |
name: "David Rivera", | |
character: "jherax", | |
friends: [], | |
languages: new RegExp(/javascript|jquery|c#|sql|java|vb/i), | |
greeting: function() { return "Hi, I am " + this.name; }, | |
info: { | |
job: "programmer", | |
birth: new Date() | |
} | |
}; | |
//creamos la referencia circular | |
freeman.friends = [david, "Barney Calhoun"]; | |
david.friends = [freeman, "John Carmack"]; | |
//clonamos el objeto @david | |
var cloned = clone(david); | |
//modificamos propiedades del objeto original | |
david.name = david.name + " (jherax)"; | |
david.friends.push("Jim Rynor"); | |
//vemos que @clone no fue modificado | |
console.log("original:", david.name, david.friends); | |
console.log("clonado:", cloned.name, cloned.friends); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment