JS游戏开发调用对象clone()报is not a function错误求助
你遇到的this[i].clone is not a function报错,核心问题出在你给Object.prototype扩展clone方法的实现逻辑有漏洞:
- 并不是所有
typeof返回object的对象都继承自Object.prototype,比如通过Object.create(null)创建的无原型对象、游戏运行环境的宿主对象(比如画布上下文、WebGL实例、引擎内置对象)、部分引擎创建的特殊实例都无法访问到你挂载的clone方法,调用自然报错。 - 你的clone方法直接挂载在原型上没有设置为不可枚举,所有对象遍历都会多出clone属性,后续很容易引发其他逻辑问题。
- 现有逻辑无法处理Date、RegExp、Map、Set等特殊内置对象,也不支持处理循环引用,遇到这些场景下都会出现异常。
你之前试的JSON.parse(JSON.stringify())方案没用是因为JSON序列化会丢失函数、Symbol、undefined值、循环引用、特殊对象实例信息,游戏开发场景下大量存在这类数据,自然满足不了需求。
修复方案
1. 改用独立的深拷贝工具函数,不要污染原生原型,适配常见场景:
function deepClone(target, cache = new WeakMap()) { // 处理基础类型和null if (target === null || typeof target !== 'object') return target // 处理循环引用避免死循环 if (cache.has(target)) return cache.get(target) // 适配常见内置对象 if (target instanceof Date) return new Date(target) if (target instanceof RegExp) return new RegExp(target) if (target instanceof Map) return new Map(Array.from(target, ([k, v]) => [k, deepClone(v, cache)])) if (target instanceof Set) return new Set(Array.from(target, v => deepClone(v, cache))) // 保留原对象的原型链 const cloneResult = Array.isArray(target) ? [] : Object.create(Object.getPrototypeOf(target)) cache.set(target, cloneResult) // 遍历所有自有属性,包含Symbol键 Reflect.ownKeys(target).forEach(key => { cloneResult[key] = typeof target[key] === 'object' && target[key] !== null ? deepClone(target[key], cache) : target[key] }) return cloneResult }
使用时直接调用deepClone(你要克隆的对象)即可。
2. 优先用游戏引擎自带的克隆方法
如果你使用了Phaser、Cocos、Pixi等游戏引擎,直接调用引擎提供的克隆API即可,这类API已经对引擎内部的实例对象做了适配,兼容性比自己实现的好很多:
- Phaser:直接调用
Phaser.Utils.Objects.DeepCopy(待克隆对象) - Cocos:克隆节点/资源用
cc.instantiate(待克隆对象),普通对象用cc.js.clone(待克隆对象)
内容的提问来源于stack exchange,提问作者Amine
相关产品推荐
相关产品推荐

