JS返回值题一直都是考察重点,面试和笔试之中也经常涉及到,说一说我最近遇到的一些有意思的JS返回函数问题。

之前见到过一道有意思的问题,说有一个sum函数,用户可以通过sum(2,3)来取到2+3 = 5 的结果,但是有的用户会出现失误的操作,有可能错误的写成sum(2)(3),现在要求增加客户的容错率,让sum(2)(3)也能够正确的返回结果。

思路:sum(2,3)就是函数传入了两个参数2和3然后能够返回2+3这个结果,而sum(2)(3)则是传入2之后得到一个结果,然后再次传入3最后得到2+3这个正确结果,也就是说函数要多执行一次,因此如果传入2就要返回一个函数,这里可以这么写:

 

function sum(num1,num2)
{
if(num2 == undefined){
return function(num){
return num1 + num;
}
}else{
return num1 + num2;
}
}

console.log(sum(2,3)); //5
console.log(sum(2)(3)); //5


还有一道比较有意思的问题是说once这个只执行一次的函数,题目要求传入一个函数对它进行包装,要求返回的结果不管执行几次只会返回第一次的结果。例如:

g = once(func);
g(2); //func(2)的结果
g(3); //还是func(2)的结果

思路:这道题不用说肯定需要一个全局变量来判断函数时候执行过,需要一个数据来存放第一次执行的结果,根据前一个变量来判断是否执行过,如果没有执行后返回结果,如果执行过则不需要再次执行,直接返回第一次的结果。这题一个考察点是全局变量的控制,还有一个考察点就是怎么利用这个传入的func来得到结果。话不多说,直接上代码:
function fn(num)
{
return num*num;
}
function once(func)
{
if(typeof func != "function"){
alert("请传入函数类型");
}
flag =true;
window.result;
return function() {
if (flag) {
result = func.apply(this, arguments);
flag = false;
return result;
} else {
return result;
}
}
}

g = once(fn);
console.log(g(2)); //4
console.log(g(3)); //4

这里注意运用apply传入arguments来调用func,arguments是一个function特有的属性,表示的是传入的所有参数,是一个类数组但不是真正意义上的数组,如果想将它转换成数组可以使用:

Array.prototype.slice.call(arguments);

这里还要说一下关于apply的相关知识,函数一般改变this上下文有三种方法:call()、apply()和bind()
call()和apply()差不多,如果都是传入一个参数的话它俩是一样的,如果传入多个参数,apply(this,arr)的第二个参数是一个数组,也就是你需要传入的各个参数组成的数组,而call(this,a,b)后面跟的是需要传入的各个属性。这两个最后得到的是改变this之后函数的执行结果。
bind()是ES5中加入的一个方法这个是直接将一个对象绑定到函数中,返回一个新的函数,这个函数里面的this属性会始终指向绑定的对象。