题目1:
const input = {
a: 1,
b: [1, 2, { c: true }, [3]],
d: { e: 2, f: 3 },
g: null,
}
function flatten(input) {
// 需要实现的代码
}
console.log(flatten(input));
// 返回
// {
// "a": 1,
// "b[0]": 1,
// "b[1]": 2,
// "b[2].c": true,
// "b[3][0]": 3,
// "d.e": 2,
// "d.f": 3,
// // "g": null, 值为null或者undefined,丢弃
// }
这道题是在深拷贝的基础上记录下key的层级,下面的答案中附上生拷贝和防止爆栈的优化答案
const input1 = {
a: 1,
b: [1, 2, { c: true }, [3]],
d: { e: 2, f: 3 },
g: null,
}
function flatten(input) {
// 需要实现的代码
let res = arguments[1] ? arguments[1] : {};
let keyStr = arguments[2] ? arguments[2] : '';
if (Reflect.toString.call(input) === '[object Array]') {
input.forEach((item, index) => {
if (typeof item === 'object') {
flatten(item, res, `${keyStr}[${index}]`)
} else {
res[`${keyStr}[${index}]`] = item
}
})
} else {
for (let key in input) {
let tmp = keyStr ? `${keyStr}.${key}` : key;
if (typeof input[key] === 'object') {
flatten(input[key], res, tmp)
} else {
res[tmp] = input[key]
}
}
}
return res
}
function deepClone(obj) {//深拷贝
let finObj = arguments[1] ? arguments[1] : {};
for (let i in obj) {
if (typeof obj[i] === 'object') {
finObj[i] = obj[i] instanceof Array ? [] : {};
deepClone(obj[i], finObj[i])
} else {
finObj[i] = obj[i]
}
}
return finObj
}
//都做下尾递归优化处理(转成循环), 防止爆栈
function tco(fn) {
let active = false;
let argumentsArr = [];
let value;
return function () {
if (!active) {
argumentsArr.push(arguments);
while (argumentsArr.length) {
value = fn.apply(this, argumentsArr.shift());
active = true;
}
}
active = false;
return value;
}
}
let _faltten = tco(function (input) {
let res = arguments[1] ? arguments[1] : {};
let keyStr = arguments[2] ? arguments[2] : '';
if (Reflect.toString.call(input) === '[object Array]') {
input.forEach((item, index) => {
if (typeof item === 'object') {
_faltten(item, res, `${keyStr}[${index}]`)
} else {
res[`${keyStr}[${index}]`] = item
}
})
} else {
for (let key in input) {
let tmp = keyStr ? `${keyStr}.${key}` : key;
if (typeof input[key] === 'object') {
_faltten(input[key], res, tmp)
} else {
res[tmp] = input[key]
}
}
}
return res
})
let _deepClone = tco(function(obj) {
//let finObj = arguments[1] ? arguments[1] : {};
let finObj
if (arguments[1]) {
finObj = arguments[1]
} else {
// console.log('obj,', obj)
if (obj instanceof Array === true) {//第一次的时候是什么结构就返回什么解构
finObj = []
} else {
finObj = {}
}
}
for (let i in obj) {
if (typeof obj[i] === 'object') {
finObj[i] = obj[i] instanceof Array ? [] : {};
_deepClone(obj[i], finObj[i])
} else {
finObj[i] = obj[i]
}
}
return finObj
})
console.log(_flatten(input1));//扁平化的结果
console.log(_deepClone(input1));//深拷贝的结果
题目2
// 8. 实现一种自定义事件机制:
class EventEmitter {
/* 在此处填写实现 */
}
const emitter = new EventEmitter();
const handler = function (evt) {
console.log(1, evt);
};
emitter.on('foo', handler);
emitter.once('foo', function (evt) {
console.log(2, evt);
});
emitter.fire({ type: 'foo', value: 'hello' });
emitter.fire({ type: 'foo', value: 'world' });
emitter.off('foo', handler);
emitter.fire({ type: 'foo', value: 'test' });
// 实现如下方法:
// 1. on,添加事件,可以给某个事件添加多个处理函数,这些函数可以被多次触发
// 2. once,添加一次性事件,在触发过一次之后不再触发
// 4. fire,触发特定事件
// 5. off,移除特定的事件处理函数
答案
// 8. 实现一种自定义事件机制:
class EventEmitter {
/* 在此处填写实现 */
constructor() {
this.target = {};
}
on(type, handler) {
this.target[type] = this.target[type] || [];
this.target[type].push(handler);
}
off(type, handler) {
let self = this;
this.target[type] = this.target[type] || [];
this.target[type].splice(self.target[type].indexOf(handler), 1);
}
fire({type, value}) {
this.target[type].forEach((item, index, arr) => {
item.call(this, value);
})
}
once(type, handler) {
let self = this;
function fn() {
handler.apply(this, arguments)
self.off(type, handler)
}
this.on(type, fn);
}
}
const emitter = new EventEmitter();
const handler = function (evt) {
console.log(1, evt);
};
const handler2 = function (evt) {
console.log('handler2', evt);
};
const handler3 = function (evt) {
console.log('handler3', evt);
};
emitter.on('foo', handler);
emitter.on('foo', handler2);
emitter.on('foo', handler3);
emitter.once('foo', function (evt) {
console.log(2, evt);
});
emitter.fire({ type: 'foo', value: 'hello' });
// emitter.fire({ type: 'foo', value: 'world' });
// emitter.off('foo', handler);
// emitter.fire({ type: 'foo', value: 'test' });
// 实现如下方法:
// 1. on,添加事件,可以给某个事件添加多个处理函数,这些函数可以被多次触发
// 2. once,添加一次性事件,在触发过一次之后不再触发
// 4. fire,触发特定事件
// 5. off,移除特定的事件处理函数