通过遍历 class(原型)属性使 Mixins 工作
Make Mixins work by looping through a class (prototype) properties
我使用 Coffeescript 有一段时间了...我一直在使用的东西是 mixins,我从这个 article 中得到启发,这是 class 我用 coffeescript :
class @Module
@extend: (obj) ->
for key, value of obj
# will be available as class methods
@[key] = value
this
@include: (obj) ->
for key, value of obj
# Assign properties to the prototype
@::[key] = value # similar to this.prototype[key] = value
this
include
class方法复制一个obj(基本上是另一个class)方法,并使它们成为目标class的实例方法,而extend
方法将使 obj 方法作为目标 class 的 class 方法。
这个class的用法很简单:
class @TargetClass extends Module
@include Class1::
@extend Class2::
}
现在我正在转向 ES6 语法,我正在尝试将该语法转换为原始语法 javascript,这是我的模块 class:
export class Module {
static extend(obj) {
for (let key in obj) {
// will be available as class methods
const value = obj[key];
this[key] = value;
}
return this;
}
static include(obj) {
for (let key in obj) {
// Assign properties to the prototype
const value = obj[key];
this.prototype[key] = value;
}
return this;
}
};
然后我试图让 Class1 的方法在我的 TestClass 中作为实例方法可用:
这是我的 Class1:
export Class1{
tobe_mixed_func(){
console.log("it should works");
}
}
这是我的测试类:
import { Module } from "./module"
import { Class1 } from "./class1"
class TestClass extends Module{
static initClass(){
this.include(Class1.prototype) // I also tried this.include(Class1) but doesn't work either
}
}
TestClass.initClass();
TestClass.tobe_mixed_func(); // TestClass.tobe_mixed_func is not a function
我收到 TestClass.tobe_mixed_func is not a function
错误,我尝试调试以查看我的 Module.include
函数是否在 obj 参数中接收到 Class1
,它接收到了!但是我注意到的是 Module.include
的 for (let key in obj) {...}
部分不会循环抛出 class "keys" 在这种情况下应该是 "tobe_mixed_func"
我放了一个 console.log(key)
来查看这样的输出:
static include(obj) {
for (let key in obj) {
console.log(key);
const value = obj[key];
this.prototype[key] = value;
}
return this;
}
但是 For 循环永远不会执行...有人能看出我遗漏了什么吗?
函数不可枚举,因此在您执行 for..in
时不会列出。您需要 getOwnPropertyNames
来复制它们:
function assignAll(target, source) {
for (let p of Object.getOwnPropertyNames(source))
target[p] = source[p];
}
class Module {
static extend(obj) {
assignAll(this, obj);
}
static include(cls) {
assignAll(this.prototype, cls.prototype);
}
}
class Class1 {
tobe_mixed_func() {
console.log("it should work");
}
}
class TestClass extends Module {
static initClass() {
this.include(Class1)
}
}
TestClass.initClass();
let a = new TestClass();
a.tobe_mixed_func()
至于更好的方法,我会定义一个普通函数(不是方法),像这样
function mixin(target, ...sources) {
for (let src of sources)
for (let p of Object.getOwnPropertyNames(src.prototype))
target.prototype[p] = src.prototype[p];
return target;
}
然后像这样声明 mixins
class MyClass {
...
}
mixin(MyClass, SomeMixin, SomeOtherMixin)
甚至
const MyClass = mixin(class {
...
}, SomeMixin, SomeOtherMixin)
我使用 Coffeescript 有一段时间了...我一直在使用的东西是 mixins,我从这个 article 中得到启发,这是 class 我用 coffeescript :
class @Module
@extend: (obj) ->
for key, value of obj
# will be available as class methods
@[key] = value
this
@include: (obj) ->
for key, value of obj
# Assign properties to the prototype
@::[key] = value # similar to this.prototype[key] = value
this
include
class方法复制一个obj(基本上是另一个class)方法,并使它们成为目标class的实例方法,而extend
方法将使 obj 方法作为目标 class 的 class 方法。
这个class的用法很简单:
class @TargetClass extends Module
@include Class1::
@extend Class2::
}
现在我正在转向 ES6 语法,我正在尝试将该语法转换为原始语法 javascript,这是我的模块 class:
export class Module {
static extend(obj) {
for (let key in obj) {
// will be available as class methods
const value = obj[key];
this[key] = value;
}
return this;
}
static include(obj) {
for (let key in obj) {
// Assign properties to the prototype
const value = obj[key];
this.prototype[key] = value;
}
return this;
}
};
然后我试图让 Class1 的方法在我的 TestClass 中作为实例方法可用:
这是我的 Class1:
export Class1{
tobe_mixed_func(){
console.log("it should works");
}
}
这是我的测试类:
import { Module } from "./module"
import { Class1 } from "./class1"
class TestClass extends Module{
static initClass(){
this.include(Class1.prototype) // I also tried this.include(Class1) but doesn't work either
}
}
TestClass.initClass();
TestClass.tobe_mixed_func(); // TestClass.tobe_mixed_func is not a function
我收到 TestClass.tobe_mixed_func is not a function
错误,我尝试调试以查看我的 Module.include
函数是否在 obj 参数中接收到 Class1
,它接收到了!但是我注意到的是 Module.include
的 for (let key in obj) {...}
部分不会循环抛出 class "keys" 在这种情况下应该是 "tobe_mixed_func"
我放了一个 console.log(key)
来查看这样的输出:
static include(obj) {
for (let key in obj) {
console.log(key);
const value = obj[key];
this.prototype[key] = value;
}
return this;
}
但是 For 循环永远不会执行...有人能看出我遗漏了什么吗?
函数不可枚举,因此在您执行 for..in
时不会列出。您需要 getOwnPropertyNames
来复制它们:
function assignAll(target, source) {
for (let p of Object.getOwnPropertyNames(source))
target[p] = source[p];
}
class Module {
static extend(obj) {
assignAll(this, obj);
}
static include(cls) {
assignAll(this.prototype, cls.prototype);
}
}
class Class1 {
tobe_mixed_func() {
console.log("it should work");
}
}
class TestClass extends Module {
static initClass() {
this.include(Class1)
}
}
TestClass.initClass();
let a = new TestClass();
a.tobe_mixed_func()
至于更好的方法,我会定义一个普通函数(不是方法),像这样
function mixin(target, ...sources) {
for (let src of sources)
for (let p of Object.getOwnPropertyNames(src.prototype))
target.prototype[p] = src.prototype[p];
return target;
}
然后像这样声明 mixins
class MyClass {
...
}
mixin(MyClass, SomeMixin, SomeOtherMixin)
甚至
const MyClass = mixin(class {
...
}, SomeMixin, SomeOtherMixin)