ES6:我使用的是Classes&在JavaScript中正确使用Mixins?

时间:2017-01-02 17:29:25

标签: javascript ecmascript-6

过去几天我一直在学习ECMAScript 6 Classes,Mixins和其他功能,但我不确定我对用例的理解是否正确。下面是一个包含Classes,Subclasses和Mixins的示例的片段。

getInfoContents()

上面的代码没有错误,我得到了正确的输出。但是,我的Mixins实现在语义上是否正确?为给定的上下文设置class Person{ constructor (opts){ for(let prop of Object.keys(opts)){ this[prop] = opts[prop]; } Person.count++; } static count = 0; } //Greeting Mixin const Greetings = Person => class extends Person{ sayHello(){} } //Job Mixin const Jobs = Person => class extends Person{ getJobs(){} getSalary(){} setJobs(){} setSalary(){} } //Subclass class WorkingPerson extends Jobs(Greetings(Person)){ constructor(opts){ super(opts); //this.type = 'nice'; } sayHello(){ if(this.type == 'nice') console.log(`Hello there! Wonderful day isnt it?`); else console.log(`Ah! Get out of here!`); } getJobs(){ return this.jobs; } setJobs(...jobs){ this.jobs.push(jobs); } getSalary(){ return this.salary; } setSalary(salary){ this.salary = salary; } } let wp = new WorkingPerson({name:'Ajay',jobs:['Digital Evangelist'],salary:10000}); let wp2 = new WorkingPerson({name:'Ron',jobs:['Entertainer'],salary:20000}); let wp3 = new WorkingPerson({name:'Morris',jobs:['Televangelist'],salary:30000}); console.log(`Number of people = ${Person.count}`); Jobs Mixin是否有意义?我读了一篇博客Mixins and Javascript: The Good, the Bad, and the Ugly.,其中他们将mixins定义为抽象子类。查看示例,他们为给定的类添加了小功能。由于这听起来与装饰师的定义相似,所以我看到了Python: Use of decorators v/s mixins?的接受答案的区别。它说:

  

Mixins增加了新的功能。装饰器用于修改现有的   功能。

这让我想到GreetingsJobs是否是Mixins,那么你会在这个背景下为装饰者提供什么样的例子呢?如果我有任何不妥之处,请提供正确答案的代码块。

此外,是否有更好的方法来提供输入参数,而不是在实例化Greetings时将一些原始对象作为参数抛出?

2 个答案:

答案 0 :(得分:3)

不,mixins未正确应用。

Person => class extends Person{...}是基本继承,可以相应地实现:

class GreetingPerson extends Person {
    sayHello() {...}
}

如果有多个不相关的类应该具有相同的方法集,请考虑应用composition over inheritance原则。

对于其余的情况(例如,根据上述原则无法重构的多态性),mixins可以应用于原型:

function mixin(obj) {
  return function (target) {
    for (const key of Object.getOwnPropertyNames(obj))
      target.prototype[key] = obj[key];
    return target;
  }
}

class GreetingBeing {
  sayHello() {...}
}

const Person = mixin(GreetingBeing.prototype)(class Person extends Biped { ... })

// or for ES.Next,
// @mixin(GreetingBeing.prototype)
// class Person extends Biped { ...}

或实例:

class Person extends Biped {
  constructor()
    super();
    Object.assign(this, GreetingBeing.prototype);
  }
}

请注意mixin helper / decorator不执行多重继承。它只是将自己的可枚举属性从GreetingBeing.prototype复制到Person.prototype

答案 1 :(得分:1)

嗯......还有装饰者提案还在吗?这可能是错的,但我认为这可能是一个未来的状态(哦,我们需要跟上的速度......)

我的理解是这样的:在你的背景下,说你想要"工作"只读。装饰者可以适应账单。

类似的东西:

function readonly ( target, key, descriptor ) {
    descriptor.writable = false;
    return descriptor;
}

// import the decorator function
import { readonly } from 'my-decorators';

class Person {
  @readonly
  person ( ) { return this.user; }
}

所以我们在这里修改该属性的行为只是隐式只读,而不是将其隐藏在闭包中等等。我也猜测现在这个属性可以检查为"只读"属性,这样它可以作为只读出现在IDE代码辅助对话框中(这很酷)。

要了解mixin的一个非常好的语言是Scala。语言本身可能不是你的事,但mixins是该语言中一个重要且广泛使用的部分。无论如何,我得到了我的主要理解,这看起来很有效。比直接OOP继承等更不僵硬,更灵活的概念。

很棒的问题我喜欢探索这些东西。你一定很享受那堂课。