javascript 在js中使用mixin的最佳方式是什么?

siv3szwd  于 2022-12-10  发布在  Java
关注(0)|答案(1)|浏览(327)

最近,我偶然发现了两篇关于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!

在这些场景中创建的对象也具有不同的组成/结构。

  • 现在我搞不清哪一个比另一个好。
  • 一个比另一个有什么优势。
  • 因此我更喜欢用哪一个。
nkcskrwz

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的概念,如TraitsStateful TraitsTalents,后者是真正适合JavaScript语言范例的组合概念。

是否使用mixin的经验法则

只有在代码重用可以用 observable 这样的形容词来描述的情况下,和/或在整个系统中,不相似的类和/或异构类型需要相同的附加行为时,才使用它。

相关问题