Klonujte cokoliv pomocí JavaScriptu

Jedním z témat nebo konceptů, které způsobují zmatek, když vývojáři začínají s JavaScriptem, je myšlenka předávání objektů odkazem; například nastavení dvou proměnných na stejný objekt ve skutečnosti vytvoří odkaz na stejný objekt. Odeslání objektu do funkce a úprava tohoto argumentu ve funkci ve skutečnosti upraví původní objekt. Někdy bychom raději poslali klon něčeho, datum, pole nebo možná objektový doslov. Sada nástrojů Dojo poskytuje vynikající metodu pro klonování téměř čehokoli. Ještě lepší je, že funkci lze snadno vytáhnout z Dojo pro vlastní sadu nástrojů.

JavaScript

Metoda klonování hluboce klonuje uzly, literály objektů, pole, data, regulární výrazy a obecné objekty:

function clone(src) {
	function mixin(dest, source, copyFunc) {
		var name, s, i, empty = {};
		for(name in source){
			// the (!(name in empty) || empty[name] !== s) condition avoids copying properties in "source"
			// inherited from Object.prototype.	 For example, if dest has a custom toString() method,
			// don't overwrite it with the toString() method that source inherited from Object.prototype
			s = source[name];
			if(!(name in dest) || (dest[name] !== s && (!(name in empty) || empty[name] !== s))){
				dest[name] = copyFunc ? copyFunc(s) : s;
			}
		}
		return dest;
	}

	if(!src || typeof src != "object" || Object.prototype.toString.call(src) === "[object Function]"){
		// null, undefined, any non-object, or function
		return src;	// anything
	}
	if(src.nodeType && "cloneNode" in src){
		// DOM Node
		return src.cloneNode(true); // Node
	}
	if(src instanceof Date){
		// Date
		return new Date(src.getTime());	// Date
	}
	if(src instanceof RegExp){
		// RegExp
		return new RegExp(src);   // RegExp
	}
	var r, i, l;
	if(src instanceof Array){
		// array
		r = [];
		for(i = 0, l = src.length; i < l; ++i){
			if(i in src){
				r.push(clone(src[i]));
			}
		}
		// we don't clone functions for performance reasons
		//		}else if(d.isFunction(src)){
		//			// function
		//			r = function(){ return src.apply(this, arguments); };
	}else{
		// generic objects
		r = src.constructor ? new src.constructor() : {};
	}
	return mixin(r, src, clone);

}

Kód poskytovaný Dojo má také schopnost klonovat funkce, ale tato schopnost je z důvodu výkonu zakázána. Funkci mixin jsem umístil do samotného klonu, ale to lze také definovat na stejné úrovni a můžete použít mixin jako obecnou funkci pro slučování objektů. Tato metoda je samozřejmě jen jedním z tisíce užitečných úryvků, které můžete najít v sadě nástrojů Dojo!