草庐IT

javascript - ES6 类的 Mixins,用 babel 转译

coder 2024-05-14 原文

根据各种来源(2alityesdiscuss)应该能够向类中添加混入:

EDIT 发现类方法不可枚举,因此无法工作。编辑了下面的代码,但仍然没有喜悦

class CartoonCharacter {
  constructor(author) {
    this.author = author;
  }

  drawnBy() {
    console.log("drawn by", this.author);
  }
}

// THIS CANNOT WORK
// class methods are not enumerable
// class Human {
//  haveFun() {
//    console.log("drinking beer");
//  }
// }

let Human = Object.create({}, {
  haveFun:   {
    enumerable: true,
    value: function () {
      console.log("drinking beer");
    }
  }
});

class Simpson extends Object.assign(CartoonCharacter, Human) {
  constructor(author) {
    super(author);
  }
}


let homer = new Simpson("Matt Groening");
homer.drawnBy();  // expected: drawn by Matt Groening
homer.haveFun();  // expected: drinking beer

我收到了“马特·格罗宁 (Matt Groening) 画的”,但我收到了一个错误,而不是“喝啤酒”

-> Uncaught TypeError: E.haveFun is not a function

最佳答案

子类工厂混合

在 Javascript 中还有另一种实现 mixin 的方法:使用子类工厂。

子类工厂是一个函数,除了一个基类并返回这个基类的扩展子类:

const mixin = base => class extends base {
  /* properties to mix in */
}

子类工厂之所以成为可能,有两个原因:

  • classes 可以定义为表达式并且在 Javascript 中是第一类*
  • extends 子句可以包含任意表达式

让我们应用这个模式:

// superclass
class CartoonCharacter {
  constructor(author) { this.author = author }
  drawnBy() { return "drawn by " + this.author }
}

// mixin 1
const Human = base => class extends base {
  haveFun() { return "drinking beer" }
}

// mixin 2
const Simpson = base => class extends base {}

// composed subclass
const Homer = Simpson(Human(CartoonCharacter));

// create an instance
const homer = new Homer("Matt Groening")

console.log(homer.drawnBy());
console.log(homer.haveFun());

sublcass工厂mixins有什么优势?

  • 自然属性优先级:稍后混合在属性中会覆盖先前的同名属性
  • mixin(Human/Simpson)和子类(Homer)都可以像往常一样使用super
  • mixins 可以有构造函数(有状态 mixins)
  • 原型(prototype)或实例没有变化

有状态混合

状态使事情变得困难。您应该尽可能避免状态。然而,有时你的 mixin 需要它自己的状态,它通过构造函数传递:

class CartoonCharacter {
  constructor(author) { this.author = author }
  drawnBy() { return "drawn by " + this.author }
}

const Human = base => class extends base {
  haveFun() { return "drinking beer" }
}

const Simpson = base => class extends base {
  constructor(arg, ...superArgs) {
    super(...superArgs);
    this.name = arg;
  }
  sayHey() { return "Hey, I am " + this.name }
}

const Homer = Simpson(Human(CartoonCharacter));
const homer = new Homer("Homer Simpson", "Matt Groening")

console.log(homer.drawnBy());
console.log(homer.haveFun());
console.log(homer.sayHey());

*术语一等函数意味着函数可以作为参数传递或像普通数据一样返回值

关于javascript - ES6 类的 Mixins,用 babel 转译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30732241/

有关javascript - ES6 类的 Mixins,用 babel 转译的更多相关文章

  1. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  2. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  3. 没有类的 Ruby 方法? - 2

    大家好!我想知道Ruby中未使用语法ClassName.method_name调用的方法是如何工作的。我头脑中的一些是puts、print、gets、chomp。可以在不使用点运算符的情况下调用这些方法。为什么是这样?他们来自哪里?我怎样才能看到这些方法的完整列表? 最佳答案 Kernel中的所有方法都可用于Object类的所有对象或从Object派生的任何类。您可以使用Kernel.instance_methods列出它们。 关于没有类的Ruby方法?,我们在StackOverflow

  4. ruby - Rails 关联 - 同一个类的多个 has_one 关系 - 2

    我的问题的一个例子是体育游戏。一场体育比赛有两支球队,一支主队和一支客队。我的事件记录模型如下:classTeam"Team"has_one:away_team,:class_name=>"Team"end我希望能够通过游戏访问一个团队,例如:Game.find(1).home_team但我收到一个单元化常量错误:Game::team。谁能告诉我我做错了什么?谢谢, 最佳答案 如果Gamehas_one:team那么Rails假设您的teams表有一个game_id列。不过,您想要的是games表有一个team_id列,在这种情况下

  5. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  6. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  7. ruby - 为什么当我调用类的实例方法时,初始化不显示为方法? - 2

    我正在写一篇关于在Ruby中几乎一切都是对象的博客文章,我试图通过以下示例来展示这一点:classCoolBeansattr_accessor:beansdefinitialize@bean=[]enddefcount_beans@beans.countendend所以从类中我们可以看出它有4个方法(当然,除非我错了):它可以在创建新实例时初始化一个默认的空bean数组它可以计算它有多少个bean它可以读取它有多少个bean(通过attr_accessor)它可以向空数组写入(或添加)更多bean(也通过attr_accessor)但是,当我询问类本身它有哪些实例方法时,我没有看到默认

  8. ruby-on-rails - Rails 中同一个类的多个关联的最佳实践? - 2

    我认为我的问题最好用一个例子来描述。假设我有一个名为“Thing”的简单模型,它有一些简单数据类型的属性。像...Thing-foo:string-goo:string-bar:int这并不难。数据库表将包含具有这三个属性的三列,我可以使用@thing.foo或@thing.bar之类的东西访问它们。但我要解决的问题是当“foo”或“goo”不再包含在简单数据类型中时会发生什么?假设foo和goo代表相同类型的对象。也就是说,它们都是“Whazit”的实例,只是数据不同。所以现在事情可能看起来像这样......Thing-bar:int但是现在有一个新的模型叫做“Whazit”,看起来

  9. ruby - 从外部访问类的实例变量 - 2

    我理解(我认为)Ruby中类变量和类的实例变量之间的区别。我想知道如何从该类外部访问该类的实例变量。从内部(即在类方法中而不是实例方法中),它可以直接访问,但是从外部,有没有办法做MyClass.class.[@$#]variablename?我没有任何具体原因要这样做,只是学习Ruby并想知道是否可行。 最佳答案 classMyClass@my_class_instance_var="foo"class上述yield:>>foo我相信Arkku演示了如何从类外部访问类变量(@@),而不是类实例变量(@)。我从这篇文章中提取了上述内

  10. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

随机推荐