看到别人在网上贴出来的笔试题,觉得很有趣,研究一下~
add(2, 3)
add(2, 3) 没什么好说,就是函数内两个参数相加。
function add(x, y) {
return x + y
}
add(2, 3) // 5
但是你这样写是没有扩展性的,如果让你实现add(2, 3, 4)的话就要修改函数了。
所以,arguments
了解一下。
arguments
是对应于传递给函数的参数,它是一个类数组对象。
你可以使用arguments
对象在函数中引用函数的参数。此对象包含传递给函数的每个参数的条目,第一个条目的索引从0开始。
arguments
对象不是一个 Array
。它类似于Array
,但除了length属性和索引元素之外没有任何Array
属性。例如,它没有 pop
方法。但是它可以被转换为一个真正的Array
:
var args = Array.prototype.slice.call(arguments)
实现:
function add () {
var res = 0
for (var i = 0; i < arguments.length; i++) {
res = res + arguments[i]
}
return res
}
add(1, 2, 3) // 6
add(2)(3)
看到add(2)(3)的时候就觉得这肯定是需要返回一个函数的,返回的函数也就是add(2)
,于是思来想去加上各种尝试想到了一个笨办法。
function add(x) {
let res = 0
res = res + x
return function (y) {
res = res + y
return res
}
}
add(2)(3) // 5
这个办法是把函数的参数相加作为结果返回,并没有延伸性,如果想要得到add(2)(3)(4)
的值,这段代码就不能用了,代码要改成如下
function add(x) {
let res = 0
res = res + x
return function (y) {
res = res + y
return function (z) {
res = res + z
return res
}
}
}
add(2)(3)(4) // 9
很明显这么写是没有尽头的,仔细观察上面的代码,我们可以发现有重复的部分,函数add
不断的返回函数,然后进行参数相加。
function add(x) {
let res = 0
res = res + x
return function temp(y) {
res = res + y
return temp
}
}
但是console.log(add(1)(2)(3))
执行后发现返回的结果是一个函数,并不是我们想要的总和。
那么怎么把结果输出呢?
第一种方法
利用我们上面学习的arguments
,判断参数输入,如果没有参数输入的话,就返回总和,而不是返回函数。
function add(x) {
let res = 0
res = res + x
return function temp(y) {
if (arguments.length === 0) {
return res
} else {
res = res + y
return temp
}
}
}
由于最后返回的是一个函数,所以调用的时候要这么调用
add(1)(2)(3)() // 6
第二种方法
第二种方法就是重写add
函数的toString
和valueOf
方法
function add(x) {
let res = 0
res = res + x
var temp = function (y) {
res = res + y
return temp
}
temp.toString = temp.valueOf = function() {
return res
}
return temp
}
add(1)(2)(3) // 6
关于toString和valueOf的知识,比较多而且繁杂,就下一篇文章在讲啦~