最近,我偶然发现了两篇关于mixins的文章,这让我搞不清哪一篇更好。
mdn中的第一个
var calculatorMixin = Base => class extends Base {
calc() { }
};
var randomizerMixin = Base => class extends Base {
randomize() { }
};
class Foo { }
class Bar extends calculatorMixin(randomizerMixin(Foo)) { }
https://javascript.info/mixins中的第二个
let sayMixin = {
say(phrase) {
alert(phrase);
}
};
let sayHiMixin = {
__proto__: sayMixin, // (or we could use Object.create to set the prototype here)
sayHi() {
// call parent method
super.say(`Hello ${this.name}`);
},
sayBye() {
super.say(`Bye ${this.name}`);
}
};
class User {
constructor(name) {
this.name = name;
}
}
// copy the methods
Object.assign(User.prototype, sayHiMixin);
// now User can say hi
new User("Dude").sayHi(); // Hello Dude!
在这些场景中创建的对象也具有不同的组成/结构。
- 现在我搞不清哪一个比另一个好。
- 一个比另一个有什么优势。
- 因此我更喜欢用哪一个。
1条答案
按热度按时间nkcskrwz1#
我完全同意Jared Smith的观点。就像任何工具或工具集一样,人们需要知道是否要使用它。如果出于任何原因选择了 mixins 的概念,人们应该真正知道它的功能和缺失,特别是在应用于JavaScript的编程范例/概念时。
在这一点上,我是固执己见的,因此下面的想法和技术方法将从我自己的Angular 提供。其他解决方案要广泛得多,其中一些我有时也会使用。
让我们以OP提供的第一个源代码为例。例如,如果将上面给出的例子改写为类似于...
第一个
......那么我最担心的是方法本身,因为它完全基于类和它们的扩展。“mixin” 是类,由类工厂立即创建。它们总是扩展另一个类。因此它是纯继承。
即使编写这样一个 mixin-class 作为 “可以做” 事情的行为容器,并且类型稍后 “具有” 特定行为,这种方法在技术上根本不承认mixin背后的概念,因为它本质上是基于子-父关系或 “是” 关系。
第二种方法,利用对象和
Object.assign
,乍一看像是许多古老的mixin方法的现代变体,当时都使用了与对象相关联的行为和自编写的extends
方法的组合......就像......extends(targetObject, mixinSourceObject)
。这种方法的独特之处在于它如何支持/解决 “composite-mixins”...从其他mixin创建的mixin。通过
super
委托链接行为并将另一个基于对象的mixin分配给mixin的__proto__
属性,在我看来是可行的和优雅的。我个人会花更多的时间玩/做研究这个第二提供的方法。
还有另一种方法......基于函数的mixin。第二个基于对象的mixin示例的代码被重写到它的基于函数的pendant中,看起来像这样......
第一次
即使在今天,选择这种方法也有一些很好的理由。首先,它与OP中提到的其他两种方法有共同之处...不需要额外的库。其次,它确实可以在每个给定的ES 3环境中运行,与其他方法不同。第三,基于函数的方法将mixin实现为“适用类型”,因此可以免费获得委托和封装。
现在我们将演示这两种方法的威力。仍然使用第二个示例代码和引入的基于函数的mixin方法,可以很容易地创建另一个用户,该用户隐藏其初始的
name
,但通过其say
行为将其公开。当然,以下代码只是为了理解概念。在实践中很难意识到这种 *”像这样混合的混合物...第一个
基于函数的混合的意见摘要
仅仅凭借ES 3已经提供的功能,通过闭包的封装、明确的功能委托以及通过
call
/apply
应用不同的上下文,我们已经可以从基于mixin的组合开始。2结合这些技术可以实现更强大的概念,比如冲突解决,它可以/将基于已经演示的通过代理引用和一些函数组合的转发。注入和传递附加状态也是可能的。因此,我们甚至可以实现超越mixin的概念,如Traits、Stateful Traits和Talents,后者是真正适合JavaScript语言范例的组合概念。是否使用mixin的经验法则
只有在代码重用可以用 observable 这样的形容词来描述的情况下,和/或在整个系统中,不相似的类和/或异构类型需要相同的附加行为时,才使用它。