You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS游戏开发调用对象clone()报is not a function错误求助

你遇到的this[i].clone is not a function报错,核心问题出在你给Object.prototype扩展clone方法的实现逻辑有漏洞:

  1. 并不是所有typeof返回object的对象都继承自Object.prototype,比如通过Object.create(null)创建的无原型对象、游戏运行环境的宿主对象(比如画布上下文、WebGL实例、引擎内置对象)、部分引擎创建的特殊实例都无法访问到你挂载的clone方法,调用自然报错。
  2. 你的clone方法直接挂载在原型上没有设置为不可枚举,所有对象遍历都会多出clone属性,后续很容易引发其他逻辑问题。
  3. 现有逻辑无法处理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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 15:45:03