CoffeeScript Mixin转ES6后遍历类属性失效,无法调用混合方法
解决ES6 Mixin中for...in无法遍历class原型方法的问题
你的问题主要出在三个地方:class语法错误、class原型方法的可枚举性限制,以及实例方法的调用方式错误,下面一步步帮你解决:
1. 先修正Class1的语法错误
你写的export Class1{缺少了class关键字,这会导致Class1无法被正确定义和导出,先改成正确的写法:
export class Class1 { tobe_mixed_func() { console.log("it should works"); } }
2. 核心问题:class原型方法默认不可枚举
ES6用class语法定义的原型方法,默认是不可枚举的(enumerable: false),而你原来的include方法里用的for...in循环,只会遍历对象的可枚举属性。所以当你传入Class1.prototype时,循环根本找不到tobe_mixed_func这个方法。
修正Module的include方法
我们可以用Object.getOwnPropertyNames来获取对象的所有自有属性名(包括不可枚举的),或者用Object.getOwnPropertyDescriptors配合Object.assign来完整复制属性描述符,这里推荐第一种更直观的写法:
export class Module { static extend(obj) { // 用Object.assign简化extend逻辑,效果和原来一致 Object.assign(this, obj); return this; } static include(obj) { // 获取obj的所有自有属性名,跳过constructor避免覆盖类构造函数 Object.getOwnPropertyNames(obj).forEach(key => { if (key !== 'constructor') { this.prototype[key] = obj[key]; } }); return this; } };
3. 修正实例方法的调用方式
你用TestClass.tobe_mixed_func()直接调用类本身,但include方法是把方法添加到类的原型上,也就是这是个实例方法,必须通过类的实例来调用:
import { Module } from "./module" import { Class1 } from "./class1" class TestClass extends Module {} // 调用include混入方法 TestClass.include(Class1.prototype); // 创建实例后调用方法 new TestClass().tobe_mixed_func(); // 现在会正确输出:it should works
如果你想在类定义内部完成混入,可以用ES6的静态代码块:
class TestClass extends Module { static { this.include(Class1.prototype); } } new TestClass().tobe_mixed_func();
这样修改后,你的Mixin功能就可以正常工作了。
内容的提问来源于stack exchange,提问作者medBouzid
相关产品推荐
相关产品推荐

