angular.copy 深拷貝源碼

深拷貝

  1. copyElement 簡單類型(非對象)直接返回
  2. 緩存裏面有沒有,有直接返回
  3. copyType Boolean Date等return new source.constructor(source.valueOf());
  4. RegExp: new RegExp(source.source, source.toString().match(/[^/]*$/)[0])
  5. cloneNode: 是dom return source.cloneNode(true);
  6. 數組或對象:destination = isArray(source) ? [] : Object.create(getPrototypeOf(source));
  7. copyRecurse 遞歸:若是是數組或者對象執行for循環或for in循環。
var toString          = Object.prototype.toString,
	getPrototypeOf    = Object.getPrototypeOf;
var isArray = Array.isArray;

function isObject(value) {
	// http://jsperf.com/isobject4
	return value !== null && typeof value === 'object';
}


function isValidObjectMaxDepth(maxDepth) {
	return isNumber(maxDepth) && maxDepth > 0;
}


function isBlankObject(value) {
	return value !== null && typeof value === 'object' && !getPrototypeOf(value);
}

function isFunction(value) {return typeof value === 'function';}

function isNumber(value) {return typeof value === 'number';}



function copy(source, destination, maxDepth) {
	var stackSource = [];
	var stackDest = [];
	maxDepth = isValidObjectMaxDepth(maxDepth) ? maxDepth : NaN;

	if (destination) {

		stackSource.push(source);
		stackDest.push(destination);
		return copyRecurse(source, destination, maxDepth);
	}

	return copyElement(source, maxDepth);

	function copyRecurse(source, destination, maxDepth) {
		maxDepth--;
		if (maxDepth < 0) {
			return '...';
		}
		var key;
		if (isArray(source)) {
			for (var i = 0, ii = source.length; i < ii; i++) {
				destination.push(copyElement(source[i], maxDepth));
			}
		} else if (isBlankObject(source)) {
			// createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
			for (key in source) {
				destination[key] = copyElement(source[key], maxDepth);
			}
		} else if (source && typeof source.hasOwnProperty === 'function') {
			// Slow path, which must rely on hasOwnProperty
			for (key in source) {
				if (source.hasOwnProperty(key)) {
					destination[key] = copyElement(source[key], maxDepth);
				}
			}
		} else {
			// Slowest path --- hasOwnProperty can't be called as a method for (key in source) { if (hasOwnProperty.call(source, key)) { destination[key] = copyElement(source[key], maxDepth); } } } return destination; } function copyElement(source, maxDepth) { // Simple values if (!isObject(source)) { return source; } // Already copied values var index = stackSource.indexOf(source); if (index !== -1) { return stackDest[index]; } var needsRecurse = false; var destination = copyType(source); if (destination === undefined) { destination = isArray(source) ? [] : Object.create(getPrototypeOf(source)); needsRecurse = true; } stackSource.push(source); stackDest.push(destination); return needsRecurse ? copyRecurse(source, destination, maxDepth) : destination; } function copyType(source) { switch (toString.call(source)) { case '[object Int8Array]': case '[object Int16Array]': case '[object Int32Array]': case '[object Float32Array]': case '[object Float64Array]': case '[object Uint8Array]': case '[object Uint8ClampedArray]': case '[object Uint16Array]': case '[object Uint32Array]': return new source.constructor(copyElement(source.buffer), source.byteOffset, source.length); case '[object ArrayBuffer]': // Support: IE10 if (!source.slice) { // If we're in this case we know the environment supports ArrayBuffer
					/* eslint-disable no-undef */
					var copied = new ArrayBuffer(source.byteLength);
					new Uint8Array(copied).set(new Uint8Array(source));
					/* eslint-enable */
					return copied;
				}
				return source.slice(0);

			case '[object Boolean]':
			case '[object Number]':
			case '[object String]':
			case '[object Date]':
				return new source.constructor(source.valueOf());

			case '[object RegExp]':
				var re = new RegExp(source.source, source.toString().match(/[^/]*$/)[0]);
				re.lastIndex = source.lastIndex;
				return re;

			case '[object Blob]':
				return new source.constructor([source], {type: source.type});
		}

		if (isFunction(source.cloneNode)) {
			return source.cloneNode(true);
		}
	}
}
	

複製代碼
相關文章
相關標籤/搜索