JS深拷贝与对象比较简单实现

最近在看《现代JavaScript库开发》,第一章深拷贝函数如下:

function clone(source) {
	const aType = type(source);
	if (aType !== 'array' && aType !== 'object') {
		return source;
	}
	let target;
	if (aType === 'object') {
		target = {};
		for(let k in source){
			if (source.hasOwnProperty(k)) {
				target[k] = clone(source[k]);
			}
		}
	} else {
		target = [];
		for (let i in source) {
			target[i] = clone(source[i]);
		}
	}
	return target;

}

function type(a) {
	return Object.prototype.toString.call(a).slice(8, -1).toLowerCase();
}

const a = {age: 14, name: 'zs'};
const b = clone(a);
a.age = 28;
a.name = 'ls';

console.log(b)

这是个基础版,不过还是很有学习空间的,于是自己接着这个思路也Mock了一个isEqual函数:

function equal(c1, c2) {
	const c1Type = type(c1);
	const c2Type = type(c2);

	if (c1Type !== c2Type) {
		return false;
	}

	if (c1Type !== 'array' && c1Type !== 'object') {
		return c1 === c2;
	}

	if (!compareKeysArray(Object.keys(c1), Object.keys(c2))) {
		return false;
	}

	for (let k in c1) {
		if (!equal(c1[k], c2[k])) {
			return false;
		}
	}

	return true;

}

function compareKeysArray(arr1, arr2) {

	arr1.sort();
	arr2.sort();
	if (arr1.length !== arr2.length) {
		return false;
	}

	for (let [i, v] of arr1.entries()) {
		if (v !== arr2[i]) {
			return false;
		}
	}
	return true;
}

function type(a) {
	return Object.prototype.toString.call(a).slice(8, -1).toLowerCase();
}


const obj1 = { a: 1, b: 2, c: undefined };
const obj2 = { b: 2, d: undefined, a: 1 };
console.log(equal(obj1, obj2));

这个只是beta版,感觉还有很多优化空间。后续有更新了再补充。

还有一种流传的方法就是使用JSON.stringify,但是当key的顺序不一样的时候就尴尬了:

const obj1 = { a: 1, b: 2, c: undefined };
const obj2 = { b: 2, c: undefined, a: 1 };
console.log(JSON.stringify(obj1) === JSON.stringify(obj2)); // false

你可能感兴趣的:(1024程序员节,javascript)