最近看到一个比较有意思的题就是编写add函数 然后 add(1)(2)(3)(4) 输出10 再考虑拓展性
function doAdd(n) {
var fn = function(m) {
return doAdd(n + m);
};
fn.valueOf = function() {
return n;
}
fn.toString = function() {
return '' + n;
}
return fn;
}
var a = +doAdd(1)(2)(3)(4);//10
console.log(typeOf a);//number
复制代码
doAdd(1)(2)(3)(4)可以解析为doAdd(1)返回函数A
A(2)返回函数B
B(3)返回函数C
C(4)返回函数D
doAdd函数执行后返回一个函数对象,这个函数对象执行后再返回一个新的函数,这样一直执行下去 可以发现返回的函数执行的逻辑都是一样的,所以使用链式调用的方法让函数返回后返回自身
由于每次返回的都是一个函数对象,所以需要将对象转换为原始值(利用js中的对象到原始值的转换规则)
当一个对象转换成原始值时,先检查对象是否有alueof方法,如果有并且返回值是一个原始值,那么
直接返回这个值,若没有valueOf或返回的并不是原始值,那么调用toString方法,返回字符串表示
所以就为函数对象添加一个valueOf方法和toString方法
调用时+doAdd() 的+号是为了将结果转换为number类型 否则是function
复制代码
拓展:
doAdd2(2,3);//5
doAdd2(2)(3);//5
function doAdd2(num1,num2) {
if (arguments.length == 1) {
return function(y) {
return num1 + y;
}
} else {
return num1 + num2;
}
}
console.log(doAdd2(2,3));
console.log(doAdd2(2)(3));
复制代码