前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分享两个前端面试题

分享两个前端面试题

作者头像
yma16
发布2024-07-18 17:48:52
140
发布2024-07-18 17:48:52
举报
文章被收录于专栏:前端javascript
前言

近期遇到两个有意思的面试题目,所以给大家分享这两个前端题。

问题1

在node环境实现一个相加的函数add,add函数有两个参数(a,b),返回的结果是a+b,要求该函数实现a+b时如果已经计算过一次a+b,那么从上一次的计算结果拿。

解析:

由于是node环境不能使用window全局对象,优先考虑使用闭包函数来实现,闭包可以让变量运行不销毁。

什么是闭包

在JavaScript中,闭包(Closure)是一个非常重要的概念,它涉及到函数和词法作用域。闭包可以定义为:

当一个函数可以记住并访问在其外部定义的变量时,即使在其外部函数已经返回后,这个函数就形成了一个闭包。

换句话说,闭包是由函数和与其相关联的词法环境组合而成的实体。当一个函数在另一个函数内部定义时,它可以访问外部函数的变量和参数,即使外部函数已经执行完毕并且从调用栈中弹出,这些变量仍然对内部函数可见。这种现象是因为内部函数在创建时捕获了外部函数的词法环境,使得它可以在以后的任何时候访问这些变量,即便是在外部函数已经返回之后。

闭包的形成主要依赖于以下几点:

  1. 函数嵌套:内部函数定义在外部函数内部。
  2. 变量访问:内部函数可以访问外部函数作用域中的变量和参数。
  3. 持久化:即使外部函数执行结束,内部函数仍然可以访问和修改外部函数作用域中的变量。

闭包的使用场景包括但不限于:

  • 创建私有变量,保护数据不被直接访问或修改。
  • 避免全局变量的污染。
  • 实现异步编程,如回调函数和事件处理程序。
  • 构建模块化的代码,通过暴露公共接口同时隐藏内部实现。

然而,闭包也可能会导致一些问题,例如:

  • 内存泄漏:由于闭包保持对变量的引用,可能导致垃圾回收器无法回收不再使用的变量,从而占用额外的内存。
  • 性能影响:过多的闭包使用可能会增加内存使用量,特别是在循环中创建大量闭包时。

理解闭包对于有效地编写和优化JavaScript代码至关重要。

使用闭包来实现add函数的代码如下:

代码语言:javascript
复制
function createAddFunction() {
    const cache = {}; // 创建一个对象用于缓存结果

    function add(a, b) {
        // 生成一个唯一的键,用于在缓存中查找或存储结果
        const key = `${a},${b}`;
        // 检查缓存中是否已经有这个计算结果
        if (cache[key] !== undefined) {
            return cache[key]; // 如果存在,则直接返回缓存的结果
        } else {
            console.log('读取缓存计算:', a, b)
        }
        // 如果缓存中没有结果,进行计算并将结果存储到缓存中
        const result = a + b;
        cache[key] = result;
        return result;
    }
    return add; // 返回add函数,它现在具有缓存功能
}
// 使用createAddFunction创建具有缓存能力的add函数
const add = createAddFunction();
// 测试add函数
console.log(add(1, 2)); // 第一次计算1+2,结果会被缓存
console.log(add(1, 2)); // 第二次调用,直接从缓存获取结果
console.log(add(3, 4)); // 计算3+4,结果会被缓存
console.log(add(3, 4)); // 直接从缓存获取3+4的结果

执行结果

问题2

众所周知js中的promise.all 会并发执行多个promise,只要其中一个promise失败就catch该promise失败的结果。

现在需要实现一个allRun的方法,接受多个promise,按顺序返回所有的执行结果。

解析:使用 reduce 函数来构建一个 Promise 链,每个 Promise 在链中按顺序执行。我们维护一个 results 数组和一个 index 变量,用于记录每个 Promise 的执行结果。每个 Promise 要么 resolve 并将结果添加到 results 数组中,要么 reject 并将错误添加到数组中。最后,当我们完成所有 Promise 的处理后,返回一个包含所有结果的 results 数组

代码语言:javascript
复制
function allRun(promises) {
    const results = [];
    let index = 0;
    return promises.reduce((chain, promise) => {
            return chain.then(() => {
                return promise
                    .then(value => {
                        results[index++] = { status: 'fulfilled', value };
                    })
                    .catch(reason => {
                        results[index++] = { status: 'rejected', reason };
                    });
            });
        }, Promise.resolve())
        .then(() => results);
}
// 使用示例
const promise1 = Promise.resolve('Success 1');
const promise2 = Promise.reject(new Error('Error 2'));
const promise3 = Promise.resolve('Success 3');
allRun([promise1, promise2, promise3])
    .then(results => {
        results.forEach((result, index) => {
            if (result.status === 'fulfilled') {
                console.log(`Promise ${index + 1} resolved with:`, result.value);
            } else {
                console.log(`Promise ${index + 1} was rejected with:`, result.reason);
            }
        });
    })
    .catch(console.error);

执行结果:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-07-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据结构框架学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档