Martin Thompson
Martin Thompson

Reputation: 3755

What is the nodejs equivalent of PHP trait

In PHP , I've used traits before which is a nice way of separating out reusable code & generally making things more readable.

Here is a specific Example: ( trait and class can be in separate files ) . How could I do this in nodejs?

<?php

trait HelloWorld {
    public function sayHello() {
        echo 'Hello World!';
    }
    ..more functions..
}

class TheWorld {
    use HelloWorld;
}

$o = new TheWorldIsNotEnough();
$o->sayHello();

?>

In Nodejs , I have looked at at Stampit which looks quite popular , but surely there is a simple way to compose functions in a nice OOP & make more readable in nodejs without depending on a package?

Thanks for your time!

Upvotes: 6

Views: 3869

Answers (2)

ponury-kostek
ponury-kostek

Reputation: 8070

In JavaScript you can use any function as trait method

function sayHello() {
  console.log("Hello " + this.me + "!");
}

class TheWorld {
  constructor() {
    this.me = 'world';
  }
}

TheWorld.prototype.sayHello = sayHello;
var o = new TheWorld();
o.sayHello();

or pure prototype version

//trait
function sayHello() {
  console.log("Hello " + this.me + "!");
}

function TheWorld() {
  this.me = "world";
}

TheWorld.prototype.sayHello = sayHello;
var o = new TheWorld();
o.sayHello();

You can even create function that's apply traits to class

//trait object
var trait = {
  sayHello: function () {
    console.log("Hello " + this.me + "!");
  },
  sayBye: function () {
    console.log("Bye " + this.me + "!");
  }
};

function applyTrait(destClass, trait) {
  Object.keys(trait).forEach(function (name) {
    destClass.prototype[name] = trait[name];
  });
}

function TheWorld() {
  this.me = "world";
}

applyTrait(TheWorld, trait);
// or simply
Object.assign(TheWorld.prototype, trait);
var o = new TheWorld();
o.sayHello();
o.sayBye();

Upvotes: 16

Vasyl Boroviak
Vasyl Boroviak

Reputation: 6138

There is the NPM module: https://www.npmjs.com/package/traits.js

Code example from their README:

var EnumerableTrait = Trait({
  each: Trait.required, // should be provided by the composite
  map: function(fun) { var r = []; this.each(function (e) { r.push(fun(e)); }); return r; },
  inject: function(init, accum) { var r = init; this.each(function (e) { r = accum(r,e); }); return r; },
  ...
});

function Range(from, to) {
  return Trait.create(
    Object.prototype,
    Trait.compose(
      EnumerableTrait,
      Trait({
        each: function(fun) { for (var i = from; i < to; i++) { fun(i); } }
      })));
}

var r = Range(0,5);
r.inject(0,function(a,b){return a+b;}); // 10

Upvotes: 0

Related Questions