谈谈一道字节前端原题(Add sumOf)

前言

最近学弟去面了字节跳动,但是由于面试经验少,面试的时候紧张了,一时之间没有写出来,之后来我交流了一下。那我就来分析分析这道题目。

image-20200906001022824

正文

这题的规则是这样的

给定有一个 Add 函数,要支持以下形式的调用

Add(1)(2)(3).sumOf(); // 输出 6  
Add(1,2)(3)(4).sumOf(); // 输出 10  
Add(1,2,...)(3)(4)(...).sumOf();  // ...

拿到这种题目,我先来说说我自己的做题流程,一般会去找它最简单的形态。我们一步一步来拆解。

先去掉 sumOf() 变成了以下形态

Add(1,2,...)(3)(4)(...)

嗯....有点熟悉...但是还是有点复杂,那我们再去掉无限调用这个限制。

Add(1,2,...)(3)(4)

唔,还是有点难呀...没关系,再砍, 不要传入多个参数。

Add(1)(2)(3)

有....有....有那味了....这....这不就是柯里化吗....

有些小朋友可能没有听过,对于大朋友而言耳熟能详,融会贯通。

我们还是来介绍一下。

在《javascript高级程序设计》这本书中有如下介绍:

与函数绑定紧密相关的主题是函数柯里化,它用于创建已经设置好的一个或者多个参数的函数。函数柯里化的基本方法和函数绑定是一样的:使用一个闭包返回一个函数。两者的区别在于,当函数被调用时,返回的函数还需要设置一些传入的参数。

我们来写写看:

function Add(x) {
    return function (y) {
        return return functio (z) {
            return x + y + z;
        }
    }
}
// 简洁写法  
const Add = x => y => z => x+y+z;

执行一下

Add(1)(2)(3) // 6 

是我们要的那味~

那么我们既然已经写出了这个形态,我们就一步一步反推。

这个时候千万别紧张,我们从最低级的形态出发,写出一个最基本的形态,能够有效地帮助我们建立自信心,吃下定心丸,按照这种方式,哪怕我们最终没有写出完美的结果,让面试官看到你思考解题的过程,也是一种加分。

好,接着说~

那我们接下来需要实现这个样子。

Add(1,2,...)(3)(4)

传入参数不止一个

我们知道,对于不确定参数个数,我们可以使用 arguments 这个对象来获取到所有的入参,但是 arguments 不是一个 Array,但是我们可以使用 ES6 中的 Spread syntax展开语法)去将他变成一个数组。表演继续。

function Add() {
    const nums = [...arguments];
    return function() {
        nums.push(...arguments);
        return function() {
            nums.push(...arguments);
            return nums.reduce((a, b) => a + b);
        }
    }
}

nice!已经离我们最终的形态越来越近了。接下来是这个函数能够无限的进行调用。

Add(1,2,...)(3)(4)(...)

那么怎么样才能无限调用呢?没错,用递归。

function Add() {
    const nums = [...arguments];
    function AddPro() {
        nums.push(...arguments);
    return AddPro;
    }
    return AddPro;
}

嗯,其实我们写到这里发现了... 由于是无限递归,我们没办法确定最后一次函数调用,因此我们需要最后显式调用一个结束的方法来打印出最后的数据。

很自然地,我们可以在 AddPro 添加一个方法 sumOf 来解决这个问题。

学弟就是卡在这里地方,被函数添加上一个方法搞懵了。你是否知道呢?
function Add() {
    const nums = [...arguments];
    function AddPro() {
        nums.push(...arguments);
    return AddPro;
    }
    AddPro.sumOf = () => {
        return nums.reduce((a, b) => a + b);
    }
    return AddPro;
}

好啦好啦,结束啦。

等等

在最后,我再来补充一种方案,function 不仅可以继续挂载 function ~ 还可以挂载变量哦~

function Add() {
    if (!Add.nums) {
      Add.nums = [];
  }
  Add.nums.push(...arguments);
  return Add;
}
Add.sumOf = () => {
    return Add.nums.reduce((a, b) => a + b);
}

如果上述回答有更优解,请公众号后台回复,留下你的微信,红包相送。

我们总结一下,小小的面试题涉及到的基础知识。

闭包、递归、作用域、函数与对象

基础就是基础,永远是你爸爸,掌握好基础,以不变应万变。

一个彩蛋

function Add() {
    const nums = [...arguments];
    return () => {
        nums.push(...arguments);
        return () => {
            nums.push(...arguments);
            return nums.reduce((a, b) => a + b);
        }
    }
}
// 如果我上述代码中间换成箭头函数又会怎么样呢~

后记

也许你觉得这题有点简单,通过简单的重复练习就能轻松记住,但是最主要的是思路,很多事情都是一样,掌握事情的方法和方向是最重要的。毕竟淘宝也不是一蹴而就的~ 但是只要方向正确了,都会好起来的。

最后

如果我的文章有帮助到你,希望你也能帮助我,欢迎关注我的微信公众号 秋风的笔记,回复好友 二次,可加微信并且加入交流群,秋风的笔记 将一直陪伴你的左右。

image


蓝色的秋风
分享是一种态度,帮助是一种品质,码字是一种快乐。一个简单而又快乐的地方。

JavaScript开发爱好者,全栈工程师。

2.9k 声望
3.9k 粉丝
0 条评论
推荐阅读
用Colab免费部署自己的AI绘画云平台—— Stable Diffusion
AI绘画门槛又又又降低了,从最开始需要花半天时间折腾的 Disco-Diffusion ,紧接着 Stable Diffusion 在 github 上开源,各家平台都推出了云平台,让用户通过轻松的点击、选择、输入就能生成一张张AI图。

程序员秋风8阅读 3.3k评论 4

封面图
从零搭建 Node.js 企业级 Web 服务器(零):静态服务
过去 5 年,我前后在菜鸟网络和蚂蚁金服做开发工作,一方面支撑业务团队开发各类业务系统,另一方面在自己的技术团队做基础技术建设。期间借着 Node.js 的锋芒做了不少 Web 系统,有的至今生气蓬勃、有的早已夭折...

乌柏木149阅读 12.2k评论 10

正则表达式实例
收集在业务中经常使用的正则表达式实例,方便以后进行查找,减少工作量。常用正则表达式实例1. 校验基本日期格式 {代码...} {代码...} 2. 校验密码强度密码的强度必须是包含大小写字母和数字的组合,不能使用特殊...

寒青54阅读 7.8k评论 11

JavaScript有用的代码片段和trick
平时工作过程中可以用到的实用代码集棉。判断对象否为空 {代码...} 浮点数取整 {代码...} 注意:前三种方法只适用于32个位整数,对于负数的处理上和Math.floor是不同的。 {代码...} 生成6位数字验证码 {代码...} ...

jenemy46阅读 5.9k评论 12

从零搭建 Node.js 企业级 Web 服务器(十五):总结与展望
总结截止到本章 “从零搭建 Node.js 企业级 Web 服务器” 主题共计 16 章内容就更新完毕了,回顾第零章曾写道:搭建一个 Node.js 企业级 Web 服务器并非难事,只是必须做好几个关键事项这几件必须做好的关键事项就...

乌柏木66阅读 6.1k评论 16

再也不学AJAX了!(二)使用AJAX ① XMLHttpRequest
「再也不学 AJAX 了」是一个以 AJAX 为主题的系列文章,希望读者通过阅读本系列文章,能够对 AJAX 技术有更加深入的认识和理解,从此能够再也不用专门学习 AJAX。本篇文章为该系列的第二篇,最近更新于 2023 年 1...

libinfs39阅读 6.3k评论 12

封面图
从零搭建 Node.js 企业级 Web 服务器(一):接口与分层
分层规范从本章起,正式进入企业级 Web 服务器核心内容。通常,一块完整的业务逻辑是由视图层、控制层、服务层、模型层共同定义与实现的,如下图:从上至下,抽象层次逐渐加深。从下至上,业务细节逐渐清晰。视图...

乌柏木43阅读 7.3k评论 6

JavaScript开发爱好者,全栈工程师。

2.9k 声望
3.9k 粉丝
宣传栏