一个很奇妙的函数,感觉有点像是反向作用域链的写法,进来一块看下

先看下下面这个函数

function createMathOperation(operator, defaultValue) {
  return (value, other) => { // 这个写法很奇妙,createMathOperation直接调用了operator的参数,在看不出任何引用的情况下,它是如何做到的?
    let result
    if (value === undefined && other === undefined) {  //如果两个参数都不存在,返回defaultValue
      return defaultValue
    }
    if (value !== undefined) { //如果存在value,就返回value
      result = value
    }
    if (other !== undefined) {  //如果存在other
      if (result === undefined) { //如果存在other,且value不存在(这里为什么不写成value === undefined?,看上去是一样的,且value更好理解),返回other
        return other
      }
      if (typeof value == 'string' || typeof other == 'string') { //如果两个参数中有字符串
        value = baseToString(value)
        other = baseToString(other)
      } else {
        value = baseToNumber(value)
        other = baseToNumber(other)
      }
      result = operator(value, other)
    }
    return result
  }
}

const add = createMathOperation((augend, addend) => augend + addend, 0);
add(4,6); // --> 10

我自己猜测是operator(value, other) 是作用域链的关系能访问到了箭头函数的value与other,但最
奇妙的在于它调用的时候:

这个add(4, 6); 发生了什么?4、6作为createMathOperation(){} 的参数可以理解,怎么就被operator(){}拿到了?
求大神指点 传道 受业 解惑

阅读 2.8k
4 个回答

其实就是一个经典闭包吧。你说的operator其实就是(augend, addend) => augend + addend这个function。然后你说你的4和6不是createMathOperation拿到了,而是return出来的function拿到了

function createMathOperation(operator, defaultValue){
    return function(value, other){
        // add的其实就是返回的这个东西
    }
}

clipboard.png

就是个闭包,简化一下:

function func(cb){
  return function(value,value2){
    //这里可以对参数做些判断
    return cb(value,value2)
  }
}
var a = func(function(value,value2){
  return value+value2;
})
a(4,6)//10

没必要写得这么复杂,让人不好理解。
应该是计算器程序的一部分,就是执行个加法。如果传进去的都是数字,返回两个数的和。如果传了字符串,则返回拼接的字符串。
add(4,6) // 10
add("a",1) // "a1"

4,6并不是作为createMathOperation的参数传进去的createMathOperation的参数是一个函数和一个默认值,就是(augend, addend) => augend + addend和0。
add(4,6)的时候,实际上4和6是被作为createMathOperationreturn的函数的参数,这块比较绕,不好理解。这时你的一切疑惑都解开了。

createMathOperation 的返回值是一个闭包函数啦,operator传进去的是一个函数,到时候在执行的

执行顺序是这样的

createMathOperation(<Anonymous Function 1>, 0) -> return <Anonymous Function 2>

所以现在 add = <Anonymous Function 2> = (augend, addend) => augend + addend

因为add两个参数都是数字,所以直接就是跳过内容直接执行了 <Anonymous Function 1> ,也就是 operator

add(4,6) -> return <Anonymous Function 2>(4, 6)

所以执行结果自然就是10啦

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题