使用JSON.stringify序列化含子元素的CreateJS Container对象异常
解决CreateJS Container添加Shape后JSON.stringify返回undefined的问题
嘿,我碰到过类似的坑,来给你捋清楚咋回事:
问题根源
你遇到的情况本质是循环引用导致JSON序列化失败。当你把Shape添加到Container后:
- Container的
children数组里包含了这个Shape - 同时Shape的
parent属性又指向了它所在的Container
这就形成了一个闭环,而JSON.stringify()碰到循环引用时,会直接返回undefined(压缩版EaselJS可能没抛出明显错误,直接返回了undefined)。
单独序列化Shape或空Container时,内部还没形成这种循环引用,所以能正常执行。
解决方案
这里有两种实用的解决办法,你可以根据需求选择:
1. 用EaselJS自带的toJSON()方法
EaselJS的DisplayObject(包括Shape、Container)自带了toJSON()方法,专门用来生成可序列化的JSON结构,它会自动处理内部的引用关系,过滤掉JSON无法处理的属性。
修改你的代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Demo JSON Prob</title> <script src="easeljs-0.8.1.min.js"></script> <script> var dummy; var aShape = new createjs.Shape(); // 序列化Shape var jsonObjShape = JSON.stringify(aShape.toJSON()); var aContainer = new createjs.Container(); // 序列化空Container var jsonObjContainer = JSON.stringify(aContainer.toJSON()); aContainer.addChild(aShape); // 序列化带子元素的Container var jsonObjContainerWithChild = JSON.stringify(aContainer.toJSON()); dummy = 0; // 这里加断点查看结果,现在应该能拿到正常的JSON字符串了 </script> </head> <body> </body> </html>
2. 自定义序列化过滤函数(Replacer)
如果你需要更精细地控制序列化的内容,可以用JSON.stringify()的第二个参数——replacer函数,手动过滤掉循环引用的属性和不需要的内部私有属性:
function replacer(key, value) { // 过滤掉导致循环引用的parent属性 if (key === 'parent' || key === '_parent') { return undefined; } // 可以继续添加其他需要过滤的属性,比如内部缓存、事件监听等 if (key === '_cacheCanvas' || key === '_listeners') { return undefined; } return value; } // 使用replacer序列化 var jsonObjContainerWithChild = JSON.stringify(aContainer, replacer);
这个方法适合你只需要序列化对象部分核心属性的场景。
内容的提问来源于stack exchange,提问作者wrcstewart
相关产品推荐
相关产品推荐

