每天一题,坚持思考
题目
实现mixin
函数,该方法类似于Object.assign
,递归合并其他来源对象自身和继承的可枚举属性到 target
目标对象。
var a = {a: 1};
mixin(a, {b: 2}, {c: 3});
console.log(a); // {a: 1, b: 2, c: 3}
具体实现
// 判断是否为对象类型
function isObj(value) {
return value != null && (typeof value === 'object' || typeof value === 'function');
}
// 遍历obj上的每一个属性,调用copy方法,绑定this的指向
function forIn(obj, fn, thisArg) {
for (var key in obj) {
if (fn.call(thisArg, obj[key], key, obj) === false) {
break;
}
}
}
// 判断属性值非'__proto__'、'constructor'、'prototype'
function isValidKey(key) {
return key !== '__proto__' && key !== 'constructor' && key !== 'prototype';
};
// 拷贝对象
function copy(val, key) {
if (!isValidKey(key)) {
return;
}
var obj = this[key];
if (isObj(val) && isObj(obj)) {
mixin(obj, val);
} else {
this[key] = val;
}
}
// 合并多个对象,改变target的值
function mixin(target) {
var length = arguments.length,
index = 0;
while (++index < length) {
var obj = arguments[index];
if (isObj(obj)) {
forIn(obj, copy, target);
}
}
return target;
}
实现思路
参数:
-
target
(Object):需要合并的对象;
步骤:
- 使用
while
遍历arguments
的成员,开始位置是1;如果是当前遍历的值类型是对象,则调用forIn
方法,否则就跳过。 - 调用
forIn
方法的时候,会把当前对象进行遍历去调用copy
复制方法 copy
方法中判断对应的属性值,如果不是'__proto__'、'constructor'、'prototype'
这三个中的其中一种,则返回true
,否则返回false
。如果当前需要拷贝的值是对象,那么会递归调用mixin
方法,这里的this
指向其实就是mixin
的需要合并的那个对象,最后执行完mixin
方法后会把一开始的target值给改变。
如果读者发现有不妥或者可以改善的地方,欢迎在评论区指出。如果觉得写得不错或者对你有所帮助,可以点赞、评论、转发分享,谢谢~