首页 > 分享三个不那么常见的字节/快手前端手撕题
头像
前端小圆
发布于 03-31 18:23 新加坡
+ 关注

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

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)
  • 基础数据处理(字符串转数字 & 边界处理)

全部评论

(1) 回帖
加载中...
话题 回帖