为何lodash cloneDeep无法克隆Blob与File对象?
为什么lodash的cloneDeep无法克隆Blob和File对象,而structuredClone可以?
问题重现
测试时发现cloneDeep处理Blob/File会返回空对象,但structuredClone能正常克隆:
// 修正语法错误后的测试代码 const file = new File([''], 'test', {type:'text/html'}); const blob = new Blob([''], {type: 'text/html'}); expect(cloneDeep(file)).toEqual(file); // cloneDeep 返回空对象 expect(cloneDeep(blob)).toEqual(blob); // cloneDeep 返回空对象
Blob和File对象的特殊之处
- 它们是浏览器专属的原生二进制对象,不是普通JS对象,内部封装了底层存储的二进制数据,还附带了MIME类型、文件名这类环境关联属性。
- 核心属性大多是不可枚举的访问器属性,不是直接挂载在对象上的可枚举键,常规的对象遍历方法(比如
Object.keys、for...in)拿不到这些属性。 - 二进制数据存在浏览器的底层内存里,不是JS引擎的普通堆内存,没法通过常规的对象复制逻辑读取。
cloneDeep无法克隆的原因
lodash的cloneDeep本质是递归遍历复制对象的可枚举属性,它没针对Blob/File这类特殊对象做适配:
- 它只能识别并复制可枚举的属性,而Blob/File的核心数据和属性都是不可枚举的,自然复制不到,最后就返回空对象。
cloneDeep的适配范围只覆盖了常见JS类型(数组、普通对象、Map、Set等),没有处理浏览器提供的二进制对象类型。- 而
structuredClone是浏览器原生实现的API,专门针对Blob/File这类特殊对象做了底层支持,能直接读取内部的二进制数据和关联属性,完成正确克隆。
内容的提问来源于stack exchange,提问作者Iris Dreizen
相关产品推荐
相关产品推荐

