记一道面试题
题目如下:
var foo=function (){…}
foo(1)(2)(3).getVal();//返回6
foo(1,2,3).getVal();//返回6
foo(1,8)(2).getVal();//返回11
实现思路:
- 每次函数执行都返回一个函数可以再次执行。
- 每次执行的参数都会存到内存中等待getVal方法的执行。
- 这个函数拥有一个getVal的内置方法。
第一步实现"每次函数执行都返回一个函数可以再次执行":
var foo = function () {
function fn() {
return foo();
}
return fn;
};
现在拿到题目中的参数测试:
foo(1)(2)(3)
foo(1,2,3)
foo(1,8)(2)
发现函数执行结果都会返回一个函数,如下图:
第二步实现"每次执行的参数都会存到内存中等待getVal方法的执行",其实就是在函数体内保存函数参数,以备getVal方式求取总数时使用:
var foo = function (...args) {
function fn() {
let arg = Array.from(arguments);//把fn函数的参数arguments由类数组改为数组
args = args.concat(arg);// 在这里缓存所有函数中的参数,确保参数没有遗漏
console.log(args);
return foo(...args);
}
return fn;
};
现在拿到题目中的参数测试:
foo(1)(2)(3)
发现函数无论执行多少次,都在内部保存了对应的参数,如下图:
第三步实现"这个函数拥有一个getVal的内置方法",函数其实也是一个对象可以给它添加方法:
var foo = function (...args) {
function fn() {
let arg1 = Array.from(arguments);
arg1 = arg1.concat(args);
return foo(...arg1);
}
fn.getVal = function () {
return args.reduce((pre, next) => {
return pre + next;
}, 0);
};
return fn;
};
现在拿到题目中的参数测试:
foo(1)(2)(3).getVal()
foo(1,2,3).getVal()
foo(1,8)(2).getVal()
执行结果如下图:
相关思考
在实际开发过程中树状结构数据根据唯一value查找数据并返回对应的层级链,现在我们有如下数据结构,根据value为1.1.1.1返回从它的父级到它本身层级的名称“选项一/子选项一/子子选项一/子子子选项一”这样的结构:
let treeData = [
{
label: "选项一",
value: "1",
children: [
{
label: "子选项一",
value: "1.1",
children: [
{
label: "子子选项一",
value: "1.1.1",
children: [
{
label: "子子子选项一",
value: "1.1.1.1",
},
],
},
],
},
{
label: "子选项二",
value: "1.2",
children: [
{
label: "子子选项一",
value: "1.2.1",
},
],
},
{
label: "子选项三",
value: "1.3",
},
],
},
{
label: "选项二",
value: "2",
children: [
{
label: "子选项一",
value: "2.1",
},
{
label: "子选项二",
value: "2.2",
},
],
},
];
实现思路:
1.同样需要闭包实现,找到匹配的value值的时候开始从最后一层return,然后不断把数据放在数组中最后返回。
function getNodePathByValue(treeData, value) {
function traverse(treeData, value) {
for(let i=0,z=treeData.length;i<z;i++){
let item = treeData[i];
if(item.value===value){
return [item];// 这里返回数组
}
if(item.children){
let result = traverse(item.children, value);
if(result){
return [item, ...result];
}
}
}
}
let pathItem=traverse(treeData, value)
return pathItem;
}
测试代码如下:
let list=getNodePathByValue(treeData, "1.1.1.1");
let labels=list.map((item)=>{
return item.label
})
console.log('当前label层级',labels);// 输出为:['选项一', '子选项一', '子子选项一', '子子子选项一']