首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

前端面试手撕代码(拼多多)

  • 25-04-21 03:01
  • 2405
  • 11344
juejin.cn

前端笔试题(拼多多)

前言

今天面试了拼多多的前端岗位,考了四道笔试题。笔试有点慌,答得一般。分享给同行看看,希望你遇到了能全过!

实现Promise串行执行任务

实现Promise串行执行,并在失败时重试指定次数的函数。如果所有重试都失败,则整个序列会停止执行。

javascript
代码解读
复制代码
function promiseSeries(tasks, retryTimes) { // 内部函数,用于执行单个任务,并重试指定次数 function runTask(task, retryCount) { return new Promise((resolve, reject) => { task() .then(resolve) .catch((error) => { if (retryCount > 0) { console.log(`任务失败,正在重试... 剩余重试次数:${retryCount - 1}`); runTask(task, retryCount - 1).then(resolve).catch(reject); } else { reject(error); } }); }); } // 串行执行任务 let result = Promise.resolve(); tasks.forEach((task) => { result = result.then(() => runTask(task, retryTimes)); }); return result; } // 示例使用 const tasks = [ () => new Promise((resolve, reject) => setTimeout(resolve, 1000, '任务1完成')), () => new Promise((resolve, reject) => setTimeout(reject, 1000, '任务2失败')), () => new Promise((resolve, reject) => setTimeout(resolve, 1000, '任务3完成')) ]; promiseSeries(tasks, 2) .then(() => console.log('所有任务完成')) .catch((error) => console.log(`执行失败:${error}`));

在这个例子中,tasks 是一个包含Promise任务的数组,每个任务都是一个返回Promise的函数。retryTimes 是每个任务失败时重试的次数。如果任务失败并且重试次数用尽,整个序列会停止,并返回一个拒绝的Promise。如果所有任务都成功完成,最终会返回一个解决的Promise。

实现一个compile 函数

实现一个compile函数,支持多级引用变量以及数组,能够解析嵌套的属性和数组索引。下面是一个compile函数实现:

javascript
代码解读
复制代码
function compile(str, obj) { const exp = /\$\{([^}]+)\}/g; function matchFn(match, p1) { let curObj = obj; let value; p1.split(".").forEach((part) => { const arrExp = /(\w+)\[(\d+)\]/; const matchRes = part.match(arrExp); if (matchRes) { const [_, name, index] = matchRes; value = curObj[name] && curObj[name][index]; if (value && typeof value !== "object") { return value; } if (!value) throw new Error(`Property not found: ${match}`); curObj = value; } else { value = curObj[part]; if (value && typeof value !== "object") { return value; } if (!value) throw new Error(`Property not found: ${match}`); curObj = value; } }); return value; } return str.replace(exp, matchFn); } const template = "Hello, ${user.name}! Your balance is${user.balance}. You have ${user.items[0]} in your cart. and${user.items[2].kk}"; const exprObj = { user: { name: "Alice", balance: 100.5, items: ["Item1", "Item2", { kk: 1 }], }, }; const compiledString = compile(template, exprObj); console.log(compiledString);

在这个实现中,我们使用了正则表达式来匹配形如${obj.prop}或${arr[0]}的插值表达式。在replaceMatch函数中,我们首先将变量路径(如user.name或user.items[0])分割成多个部分,然后遍历这些部分,逐步解析出最终的值。 注意,这个实现假设表达式对象exprObj的结构是固定的,并且所有的路径都是有效的。如果路径中的某个属性或索引不存在,函数将返回原始的插值表达式。此外,这个实现不处理循环引用或复杂的对象结构。如果需要处理更复杂的情况,可能需要一个更健壮的路径解析器。

法二:使用with函数实现

javascript
代码解读
复制代码
function compile(template, context) { // 替换模板中的插值表达式为 JavaScript 模板字符串语法 const compiledTemplate = template.replace( /{{(.*?)}}/g, (match, p1) => `\${${p1.trim()}}` ); // 动态生成一个函数,用于替换模板中的插值表达式 const compiledFunction = new Function( "context", ` with (context) { return \`${compiledTemplate}\`; } ` ); // 调用函数并返回结果 return compiledFunction(context); } const template = "Hello, ${user.name}! Your balance is${user.balance}. You have ${user.items[0]} in your cart. and${user.items[2].kk}"; const exprObj = { user: { name: "Alice", balance: 100.5, items: ["Item1", "Item2", { kk: 1 }], }, }; const compiledString = compile(template, exprObj); console.log(compiledString);

使用with函数是非常取巧的,面试如果想要快速实现,可以使用第法二。

ES6 class关键字的实现

用ES6声明一个class,在es5怎么实现。

javascript
代码解读
复制代码
function inheritPrototype(subClass, superClass) { // 复制一份父类的原型 var p = copy(superClass.prototype); // 修正构造函数 p.constructor = subClass; // 设置子类原型 subClass.prototype = p; } function Parent(name, id){ this.id = id; this.name = name; this.list = ['a']; this.printName = function(){ console.log(this.name); } } Parent.prototype.sayName = function(){ console.log(this.name); }; function Child(name, id){ Parent.call(this, name, id); // Parent.apply(this, arguments); } inheritPrototype(Child, Parent);

分析打印结果

给出下列代码的打印结果,分析原因。

javascript
代码解读
复制代码
const temp = {} class Test { a(){} b = () => { } c = 1; d = {}; e = temp; static f = temp } const test1 = new Test(); const test2 = new Test(); console.log(test1.a === test2.a) console.log(test1.b === test2.b) console.log(test1.c === test2.c) console.log(test1.d === test2.d) console.log(test1.e === test2.e) console.log(test1 === test2) console.log(Test.f === Test.f)

以下是给定代码的输出结果及其原因分析:

javascript
代码解读
复制代码
console.log(test1.a === test2.a); // true console.log(test1.b === test2.b); // false console.log(test1.c === test2.c); // true console.log(test1.d === test2.d); // false console.log(test1.e === test2.e); // true console.log(test1 === test2); // false console.log(Test.f === Test.f); // true

原因分析:

  1. console.log(test1.a === test2.a); // true
    • a 是一个在 Test 类原型上定义的方法。由于 test1 和 test2 都是 Test 类的实例,它们会共享原型上的方法,因此 test1.a 和 test2.a 指向同一个函数。
  2. console.log(test1.b === test2.b); // false
    • b 是一个通过赋值创建的箭头函数,它是实例自己的属性,而不是原型上的属性。因此,test1.b 和 test2.b 是两个不同的函数实例。
  3. console.log(test1.c === test2.c); // true
    • c 是一个原始值(在这种情况下是数字),原始值是按值传递的,而不是按引用传递。但是,这里比较的是 test1.c 和 test2.c 的值,由于它们都被赋值为 1,所以比较结果是 true。
  4. console.log(test1.d === test2.d); // false
    • d 是一个对象,它是通过赋值创建的实例自己的属性。test1.d 和 test2.d 是两个不同的对象实例。
  5. console.log(test1.e === test2.e); // true
    • e 被赋值为同一个外部对象 temp 的引用。因此,test1.e 和 test2.e 指向同一个对象。
  6. console.log(test1 === test2); // false
    • test1 和 test2 是 Test 类的两个不同实例,因此它们不相等。
  7. console.log(Test.f === Test.f); // true
    • f 是一个静态属性,它属于 Test 类本身,而不是类的实例。静态属性在类定义时只会被创建一次,因此 Test.f 指向的是同一个对象。
注:本文转载自juejin.cn的eason_fan的文章"https://juejin.cn/post/7475621800783233061"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2491) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top