Node服务端通过Jade传递自定义类对象,客户端调用方法报错
问题原因分析
你遇到的问题核心在于 JSON.stringify()的局限性:它只能序列化对象的可枚举自有属性,类的原型方法(比如你的getFoo())不会被包含在序列化后的JSON字符串里。所以客户端通过!{JSON.stringify(object)}拿到的只是一个普通的JavaScript对象(只有foo: "bar"这个属性),并不是你自定义类的实例——哪怕你在客户端引入了类文件,这个普通对象也和你的类没有任何关联,自然调用不了getFoo()方法。
另外提个小建议:尽量不要用Object作为自定义类的名称,它会和JavaScript原生的Object构造函数冲突,很容易引发混淆,后面我会用MyObject来替代你的类名。
解决方案
方案一:将普通对象转换为类实例
客户端拿到序列化后的普通对象后,把它的属性复制到自定义类的实例上,这样实例就能拥有类的原型方法了:
1. 先修改你的自定义类(可选,但更规范)
// object.js module.exports = class MyObject { constructor() { this.foo = "bar"; } getFoo() { return this.foo; } }
2. 客户端代码调整
// 客户端先引入你的类文件(确保路径正确) <script src="/path/to/object.js"></script> <script> // 获取服务端传递的普通对象 var plainObj = !{JSON.stringify(object)}; // 创建类的实例 var ob = new MyObject(); // 把普通对象的属性复制到实例上 Object.assign(ob, plainObj); // 现在就能正常调用方法了 console.log(ob.getFoo()); // 输出 "bar" </script>
方案二:给类添加静态方法快速创建实例
可以在自定义类里加一个静态方法,专门用来从普通对象生成类实例,代码更简洁:
1. 修改自定义类
// object.js module.exports = class MyObject { constructor() { this.foo = "bar"; } getFoo() { return this.foo; } // 静态方法:从普通对象生成实例 static fromPlainObject(plainObj) { const instance = new MyObject(); Object.assign(instance, plainObj); return instance; } }
2. 客户端代码
<script src="/path/to/object.js"></script> <script> var plainObj = !{JSON.stringify(object)}; var ob = MyObject.fromPlainObject(plainObj); console.log(ob.getFoo()); // 输出 "bar" </script>
方案三:避免序列化,直接在客户端创建实例(如果属性不需要服务端动态生成)
如果你的类实例属性不需要服务端动态修改,完全可以直接在客户端创建类实例,不用从服务端传递:
<script src="/path/to/object.js"></script> <script> var ob = new MyObject(); console.log(ob.getFoo()); // 直接输出 "bar" </script>
注意:不要尝试把函数序列化到JSON里(比如把
getFoo转为字符串后在客户端eval),这种做法不仅不安全,还会破坏代码的可维护性,完全不推荐。
内容的提问来源于stack exchange,提问作者Mattia
相关产品推荐
相关产品推荐

