3

Let's say I have a Ruby class and a Ruby module

module Foo
  def hello
    puts 'hello'
  end
end

class Bar
  include Foo
end

and now I can do something like this

Bar.new.hello 

Can I do the same in JavaScript? I can't use extends keyword because my JavaScript class is already inherited. How can I mixin some functionality to my class?

Updated

I want to use something working with ES6 classes

Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
user3309314
  • 2,453
  • 2
  • 17
  • 30
  • I think you meant `include Foo`, not `include Bar`. – afuous Nov 06 '16 at 17:06
  • Absolutely. I fix the typo – user3309314 Nov 06 '16 at 17:10
  • have you tried something with ES6 classes? – max pleaner Nov 06 '16 at 18:52
  • @user3309314 >>I want to use something working with ES6 classes<< ... how about then searching for "es6 classes mixins" ... http://stackoverflow.com/questions/30732241/mixins-for-es6-classes-transpiled-with-babel ... or "es 6 classes mixins" ... http://stackoverflow.com/questions/38970402/es-6-classes-mixins ... the first match already looks more than just promising. – Peter Seliger Nov 07 '16 at 16:01

3 Answers3

4

I do recommend reading some of the listed answers of mine given on SO, that are related to the OP's very one.

... Edit: By the way, a search for "es6 classes mixins" does already point to Mixins for ES6 classes, transpiled with babel ...

Using the OP's example, an already reliable answer might briefly be broken down to ...

function withSayHello() {       // - function based *Flight Mixin* as of Angus Croll.
  this.sayHello = function () { // - should be encouraged becoming the main approach
                                //   (though featuring a sugared syntax) of a future
    console.log(this.hello);    //   *Lightweight Trait* implementation.
  };                            //
}                               //

function Bar() {                // - classic ES3 constructor.
    this.hello = 'hello';       //
                                //
    withSayHello.call(this);    // - applying the function based Mixin/Trait/Talent
}                               //   from above.
var bar = new Bar;

bar.sayHello();


class Foo {                     // - with syntactic "class" sugar ...
  constructor() {               //   ... `constructor` does remain the place for ...
    this.hello = 'Howdy!';      //
                                //
    withSayHello.call(this);    //   ... applying function based Mixins/Traits/Talents.
  }                             //
}                               //
var foo = new Foo;

foo.sayHello();

One might check the above example also with Babel's REPL.

Browsers still do not support JavaScript's standardized module system. On the other hand e.g. JS libraries and the NodeJS environment do provide their own module systems. The working example from above easily transfers/transpiles in each of it - but here again into the standard one as it already is supported by compilers like Babel and Traceur.

// module "my_special_withSayHello_mixin.js"
//
export default function withSayHello() {
  this.sayHello = function () {

    console.log(this.hello);
  };
}


// module "my_very_own_Foo_implementation.js"
//
import withSayHello from 'my_special_withSayHello_mixin';

export default class Foo {
  constructor() {
    this.hello = 'Howdy!';

      withSayHello.call(this);
  }
}


// module "main.js"
//
import Foo from 'my_very_own_Foo_implementation';

var foo = new Foo;
foo.sayHello();
Community
  • 1
  • 1
Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
1

There is nothing in the Javascript language that supports this directly, but it can be emulated.

var Foo = {
    hello: function() {
        console.log("hello");
    }
};

function Bar() {}

for (var key in Foo) {
    Bar.prototype[key] = Foo[key];
}

new Bar().hello(); // prints hello

This loops through everything in Foo and adds it to Bar.

afuous
  • 1,478
  • 10
  • 12
1

You can using prototypical inheritance.

var Foo = function(){
    this.hello = function(){
        console.log('hello');
    }
}

var Bar = function(){
    Foo.call(this);
}

Bar.prototype = Object.create(Bar);

new Bar().hello();
Gabs00
  • 1,869
  • 1
  • 13
  • 12