链式调用
题目:现给定如下代码,要求完成 find
函数使得控制台打印要求的内容。
var data = [
{ userId: 8, title: 'title1' },
{ userId: 11, title: 'other' },
{ userId: 15, title: null },
{ userId: 19, title: 'title2' }
];
var find = function (origin) {
// code here
}
var result = find(data).where({
"title": /\d$/
}).orderBy('userId', 'desc');
console.log(result);
// [{ userId: 19, title: 'title2'}, { userId: 8, title: 'title1' }];
这个题出的很好,考察了很多知识点:
-
链式调用实现,一般由返回this自身实现。
-
Object.keys()
-
[].filter()
-
正则表达式
这里要注意,最符合语境的方法是reg.test(str)
,因为它只返回布尔值。但是,这个方法有一个弊端,就是reg如果有g指令,即有lastIndex
属性,在第一次搜索后会增加,导致后面查不到。因此要主动清零。或者使用str.match(reg)
,找到会返回数组,找不到返回null。 -
自定义排序函数
js的自定义排序函数与c++不同,c++是根据返回值的true或false来判断,js是根据返回值与0的关系。并且与c++是反的。
我在第一次遇见这个题的时候,对this绑定机制还不是很熟,因此犯了一些错误,如今已经完全理解。
var find = function (origin) {
return {
data: origin,
where (regObj) {
for (let key of Object.keys(regObj)) {
const regExp = regObj[key];
this.data = this.data.filter(item => {
regExp.lastIndex = 0;
return regExp.test(item[value]);
})
}
return this;
},
orderBy (key, order) {
this.data.sort((a, b) => {
if (order === "desc") {
return b[key] - a[key];
} else {
return a[key] - b[key];
}
});
return this.data;
}
}
}
判断有没有循环引用
题目:
function isHasCircle(obj) {
// code here
}
let obj = {
a: 1,
b: 2
}
obj.c = obj;
isHasCircle(obj); // true
代码:
function isHasCircle(obj) {
let map = new Map();
let isCircle = false;
function loop (obj) {
let keys = Object.keys(obj);
keys.forEach(key => {
let value = obj[key];
if (value && typeof value === "object") {
if (map.has(value)) {
isCircle = true;
return;
} else {
map.set(value);
loop(value);
if (isCircle) return;
map.delete(value);
}
}
});
}
loop(obj);
return isCircle;
}