• Web前端面试题:写一个mul函数


    问题:写一个mul函数调用时将生成以下输出:

    console.log(mul(2)(3)(4)); // output : 24

    console.log(mul(4)(3)(4)); // output : 48

    回答:时允

    这个应该是题主想要的答案,支持任意次数调用。主要是考察了对递归的理解,和 valueOf 的使用。
    function mul(x) {
    	const result = (y) => mul(x * y); 
    	result.valueOf = () => x;
    	return result;
    }
    

    console.log(mul(3))
    -> 3
    console.log(mul(3)(2))
    -> 6
    console.log(mul(3)(2)(4))
    -> 24
    console.log(mul(3)(2)(4)(5))
    -> 120

    涉及到的知识点大概有:

    1.const

    2.function类型

    3.lambda表达式

    4.valueOf

    5.递归

    1.const是es6的新语法,用法基本和var一样(这里换成var或者let也可以运行)。在本答案中有一个精妙的点是result本身由于是const,不能被重复赋值,但是result作为一个object(Function Object),他的每一个key是不受保护的,所以result的valueOf是可以被重写的。

    const

    2.当使用typeof查看一个function的类型的时候,结果是"function" 然而所有的function其实都是Object(Function Object), 这也是为什么它会调用到Object.prototype.valueOf()的原因

    Every Object is a function and every function is Object - Which is Correct?

    3.lambda表达式(Lambda Expression or Arrow Function),是es6提供的新语法,

    () => x 可以看做是 function(){ return x; }

    (y) => mul(x * y) 可以看做是 function(y){ return mul(x * y) }

    Arrow functions

    4.valueOf在这里是Object的一个方法,这个方法没有参数并返回了一个基本类型。在所有对object的取值过程都会被调用。前面说了function其实也是一个Object,所以在对这个function进行取值(比如做乘法)的时候,就会调用这个valueOf,如果是正常使用,他返回的其实是mul()这个function本身。

    Object.prototype.valueOf()

    5.递归比较难说明,我试着举例说明,

    当运行mul(3)的时候,3作为参数被传入,这个函数的返回值其实是

    function(y){ return mul(3 * y);}

    然而!!这个函数被取值的时候,调用了的是valueOf方法,而这个函数的valueOf方法是

    function(){ return 3;}, 所以你尝试输出他的时候,得到的值是3.

    当运行mul(3)(2)的时候,由于前面说过函数的返回值是一个匿名函数

    function(y){return mul(3 * y)}
    

    在这里就是(mul(3))(2), 也就是function(2){ return mul(3 * 2);},

    所以当在最后被取值的时候,运行的其实是mul(3*2)的valueOf方法,也就是

    function() { return 3 * 2; }
    

    所以得到的结果是6.

    另外有看到别的评论有提到在nodejs环境,和firefox浏览器下,console.log()并不调用valueOf,我做了个实验。如图:

    证明在nodejs环境下,console.log()的确不调用valueOf,所以题主的答案应该视当时情况而定。

    地址:https://www.zhihu.com/question/54822257/answer/141698567

     

    一辈子很短,努力的做好两件事就好;第一件事是热爱生活,好好的去爱身边的人;第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱;
  • 相关阅读:
    图解HTTP学习笔记——简单的HTTP协议
    Java编程思想学习笔记——类型信息
    Java编程思想学习笔记——字符串
    Java编程思想学习笔记——接口
    Java编程思想学习笔记——复用类
    Java编程思想学习笔记——类的访问权限
    ESLint
    关于常见继承的几种方法
    flux,redux,vuex状态集管理工具之间的区别
    商品放大镜效果
  • 原文地址:https://www.cnblogs.com/yangsg/p/15628815.html
Copyright © 2020-2023  润新知