分享三个不那么常见的字节/快手前端手撕题

1. 判断一个对象是否是 Promise(使用TypeScript)

面试写法

function isPromise<T = any>(val: any): val is Promise<T> {
  return (
    val !== null &&
    (typeof val === 'object' || typeof val === 'function') &&
    typeof val.then === 'function'
  )
}

面试讲解要点

  • 核心标准不是 instanceof Promise
  • Promise 的本质:thenable(拥有 then 方法)
  • 所以判断:

判断 Promise 本质是判断 thenable,而不是构造函数实例。

2. 写一个上传图片函数(传入 url + HTMLElement)

面试写法

function uploadImage(url: string, inputEl: HTMLInputElement) {
  const file = inputEl.files?.[0]
  if (!file) return Promise.reject('no file')

  const formData = new FormData()
  formData.append('file', file)

  return fetch(url, {
    method: 'POST',
    body: formData
  }).then(res => res.json())
}

面试讲解要点

流程拆解:

  1. 从 <input type="file"> 获取文件
  2. 使用 FormData 封装
  3. 通过 fetch / axios 发送请求

关键点:

  • input.files[0] 获取文件
  • FormData 用于文件上传(multipart/form-data)
  • 不需要手动设置 Content-Type(浏览器自动处理)

可加分点

// 限制类型
if (!file.type.startsWith('image/')) {
  throw new Error('only image allowed')
}

文件上传核心是 File + FormData + HTTP 请求。

3. "123.456" 转 number 类型

面试写法

function parseNumber(str: string): number {
  return Number(str)
}

面试讲解要点

常见三种方式:

Number("123.456")     // ✅ 推荐
parseFloat("123.456") // ✅ 可用
+"123.456"            // ✅ 简写(不推荐写在面试)

区别(简单讲就够)

  • Number():更严格(推荐)
  • parseFloat():会解析到非法字符前
parseFloat("123abc") // 123
Number("123abc")     // NaN

可加一层校验(加分)

function parseNumber(str: string): number {
  const num = Number(str)
  if (Number.isNaN(num)) {
    throw new Error('invalid number')
  }
  return num
}

Number 更严格,parseFloat 更宽松,面试优先用 Number。

附加要求:禁止直接用 Number ()/parseFloat:需做合法性校验,避免非法字符串返回NAN

/**
 * 字符串数字精确转换为number类型
 * @param numStr 数字字符串(如'123.456')
 * @returns 精确number数字,非法则返回NaN
 */
function stringToNumber(numStr: string): number {
  // 1. 空值校验
  if (!numStr || numStr.trim() === '') return NaN;

  // 2. 正则校验:仅允许数字+小数点(合法数字字符串)
  const numberReg = /^\d+(\.\d+)?$/;
  if (!numberReg.test(numStr)) return NaN;

  // 3. 精确转换为number(parseFloat保留原始小数位)
  const result = parseFloat(numStr);

  // 4. 二次校验:确保转换有效
  return isNaN(result) ? NaN : result;
}

// ------------------- 测试用例 -------------------
console.log(stringToNumber('123.456')); // 123.456 (number类型)
console.log(typeof stringToNumber('123.456')); // number
console.log(stringToNumber('abc')); // NaN(非法字符串)
console.log(stringToNumber('')); // NaN(空字符串)
console.log(stringToNumber('456')); // 456(整数兼容)

透过现象看本质

这三题本质考察的是:

  • 类型判断能力(Promise / thenable)
  • 浏览器 API 使用(File / FormData / fetch)
  • 基础数据处理(字符串转数字 & 边界处理)
#暑期实习##前端八股文##面试##日常实习##秋招#
前端面试准备&amp;技术分享 文章被收录于专栏

目前是一些前端面试相关准备文章的合集

全部评论
感觉都是典型的题型和知识点啊
点赞 回复 分享
发布于 04-08 22:09 陕西

相关推荐

面试时间:4.20晚上7点&nbsp;时长35min面试官很友善,也很年轻,给我很强烈的一种公式的味道,从八股到项目到ai到手撕,特别强烈的公式感1.&nbsp;自我介绍2.&nbsp;讲一下浅拷贝和深拷贝的区别。3.&nbsp;Vue3&nbsp;相比&nbsp;Vue2&nbsp;有哪些优点和升级?4.&nbsp;你怎么理解&nbsp;Vue3&nbsp;里的&nbsp;Hooks&nbsp;/&nbsp;组合式逻辑?5.&nbsp;你有没有自己封装过&nbsp;hooks?适合在什么场景下封装?6.&nbsp;讲一下&nbsp;Vue&nbsp;里的虚拟&nbsp;DOM,它主要解决什么问题?7.&nbsp;从输入&nbsp;URL&nbsp;到页面最终渲染出来,中间发生了什么?8.&nbsp;多人协作开发时,Git&nbsp;分支一般怎么管理?9.&nbsp;如果你往公共分支提交了一段有&nbsp;bug&nbsp;的代码,怎么安全撤回?10.&nbsp;你有了解或使用过&nbsp;React&nbsp;吗?11.&nbsp;介绍一下你的&nbsp;AI&nbsp;对话平台项目,项目规模、页面结构和你负责的部分分别是什么?12.&nbsp;你项目里用了&nbsp;SSE,如果里面混合了文本、图片、视频,你会怎么处理?13.&nbsp;你项目里的本地持久化机制是怎么做的?为什么用&nbsp;Pinia&nbsp;和&nbsp;LocalStorage?14.&nbsp;如果会话数据不断增长,LocalStorage&nbsp;超出容量上限了怎么办?15.&nbsp;如果把&nbsp;SSE&nbsp;改成&nbsp;WebSocket,能力上能不能完全对齐?有哪些差异?16.&nbsp;介绍一下你的通用后台管理系统项目,这个项目的难点是什么?17.&nbsp;你们上传的文件一般是什么类型?18.&nbsp;分片上传的分片策略是怎么设计的?为什么用这个阈值?19.&nbsp;分片是越多越好还是越少越好?怎么权衡?20.&nbsp;讲一下断点续传的完整实现流程。21.&nbsp;秒传是怎么做的?核心判断依据是什么?22.&nbsp;你做的前端性能优化有没有量化效果?怎么测出来的?23.&nbsp;你平时学习前端主要通过哪些渠道?24.&nbsp;你最近有了解哪些前端相关的&nbsp;AI&nbsp;工具?25.&nbsp;你怎么理解&nbsp;Skills?26.&nbsp;手撕:LC20.&nbsp;有效的括号27.&nbsp;反问
查看26道真题和解析
点赞 评论 收藏
分享
评论
7
28
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务