javascript中的特征

javascript中的特征,javascript,prototype,traits,Javascript,Prototype,Traits,如何在javascript中实现Trait?函数Trait(方法){ function Trait (methods) { this.traits = [methods]; }; Trait.prototype = { constructor: Trait , uses: function (trait) { this.traits = this.traits.concat (trait.traits); return this; } ,

如何在javascript中实现Trait?

函数Trait(方法){
function Trait (methods) {
  this.traits = [methods];
};

Trait.prototype = {
    constructor: Trait

  , uses: function (trait) {
      this.traits = this.traits.concat (trait.traits);
      return this;
    }

  , useBy: function (obj) {
      for (var i = 0; i < this.traits.length; ++i) {
        var methods = this.traits [i];
        for (var prop in methods) {
          if (methods.hasOwnProperty (prop)) {
            obj [prop] = obj [prop] || methods [prop];
          }
        }
      }
    }
};

Trait.unimplemented = function (obj, traitName) {
  if (obj === undefined || traitName === undefined) {
    throw new Error ("Unimplemented trait property.");
  }
  throw new Error (traitName + " is not implemented for " + obj);
};
this.traits=[方法]; }; Trait.prototype={ 构造器:特征 用途:功能(特征){ this.traits=this.traits.concat(trait.traits); 归还这个; } ,使用人:功能(obj){ 对于(变量i=0;i
例如:

var TEq = new Trait ({
    equalTo: function (x) {
      Trait.unimplemented (this, "equalTo");
    }

  , notEqualTo: function (x) {
      return !this.equalTo (x);
    }
});

var TOrd = new Trait ({
    lessThan: function (x) {
      Trait.unimplemented (this, "lessThan");
    }

  , greaterThan: function (x) {
      return !this.lessThanOrEqualTo (x);
    }

  , lessThanOrEqualTo: function (x) {
      return this.lessThan (x) || this.equalTo (x);
    }

  , greaterThanOrEqualTo: function (x) {
      return !this.lessThan (x);
    }
}).uses (TEq);


function Rational (numerator, denominator) {
  if (denominator < 0) {
    numerator *= -1;
    denominator *= -1;
  }
  this.numerator = numerator;
  this.denominator = denominator;
}

Rational.prototype = {
    constructor: Rational

  , equalTo: function (q) {
      return this.numerator * q.numerator === this.denominator * q.denominator;
    }

  , lessThan: function (q) {
      return this.numerator * q.denominator < q.numerator * this.denominator;
    }
};

TOrd.useBy (Rational.prototype);

var x = new Rational (1, 5);
var y = new Rational (1, 2);

[x.notEqualTo (y), x.lessThan (y)]; // [true, true]
var-TEq=新特性({
等式:函数(x){
未实现的(这个“平等”);
}
,notEqualTo:function(x){
返回!this.equalTo(x);
}
});
var-TOrd=新性状({
lessThan:函数(x){
未实现的(这是“较少的”);
}
,大于:函数(x){
return!this.lessThanOrEqualTo(x);
}
,lessThanOrEqualTo:function(x){
返回this.lessThan(x)| | this.equalTo(x);
}
,greaterThanOrEqualTo:function(x){
返回!this.lessThan(x);
}
}).用途(TEq);
有理函数(分子、分母){
if(分母<0){
分子*=-1;
分母*=-1;
}
这个。分子=分子;
这个。分母=分母;
}
Rational.prototype={
构造函数:Rational
,equalTo:function(q){
返回this.numerator*q.numerator===this.densor*q.densor;
}
,lessThan:函数(q){
返回this.numerator*q.densor
有不同的方法,同时也有适合生产的库

mixin是跨类层次结构的最古老的代码重用形式。它们需要按线性顺序组合,因为混合的概念不包括/识别冲突解决功能

Traits是在类级别工作的细粒度代码重用单元;但它们更灵活,因为Traits必须为方法的组合、排除或别名提供复合运算符

我确实建议阅读两篇论文,这两篇论文都涉及到一种与图书馆无关的纯粹基于函数的混合/特质/才能的方法

  • 安格斯·克罗尔,2011年5月
  • 从2014年4月开始
  • 纯函数和基于委托的mixin机制与下面两个给定示例一样简单

    var Enumerable_first = function () {
      this.first = function () {
        return this[0];
      };
    };
    var list = ["foo", "bar", "baz"];
    
    console.log("(typeof list.first)", (typeof list.first)); // "undefined"
    
    Enumerable_first.call(list); // explicit delegation
    
    console.log("list.first()", list.first()); // "foo"
    
    。。。第一个例子在“实例”层面上起作用,第二个例子在“类”层面上起作用

    var Enumerable_first_last = function () {
      this.first = function () {
        return this[0];
      };
      this.last = function () {
        return this[this.length - 1];
      };
    };
    console.log("(typeof list.first)", (typeof list.first));  // "function"   // as expected
    console.log("(typeof list.last)", (typeof list.last));    // "undefined"  // of course
    
    Enumerable_first_last.call(Array.prototype);  // applying behavior to [Array.prototype]
    
    console.log("list.last()", list.last());      // "baz"  // due to delegation automatism
    
    如果需要建立和/或生产就绪的库,则应仔细查看

  • 再见

    附录一

    另请参见:

    • stackoverflow.com::
    • stackoverflow.com::
    附录二

    因为有时我似乎在摆弄这件事,所以我不想在这件事上添加一些最后的想法

    没有太多粘合代码的库无关方法(如上所述)只适用于行为重用的细粒度可组合单元。因此,只要一个人没有遇到超过1或2个容易解决的冲突,基于安格斯·克罗尔(Angus Croll)的飞行混合的模式就是可以遵循的路径

    如果涉及到真正的特征,就必须有一个抽象层次。这一层(例如,作为某种语法糖提供,如DSL)需要隐藏复杂性,例如,在特征应用时(当特征的行为应用于对象/类型时),从特征合成特征或冲突解决的复杂性

    到目前为止,有3个例子,以便从我的角度提供确切的OP要求

    如何在javascript中实现traits

    function Trait (methods) {
      this.traits = [methods];
    };
    
    Trait.prototype = {
        constructor: Trait
    
      , uses: function (trait) {
          this.traits = this.traits.concat (trait.traits);
          return this;
        }
    
      , useBy: function (obj) {
          for (var i = 0; i < this.traits.length; ++i) {
            var methods = this.traits [i];
            for (var prop in methods) {
              if (methods.hasOwnProperty (prop)) {
                obj [prop] = obj [prop] || methods [prop];
              }
            }
          }
        }
    };
    
    Trait.unimplemented = function (obj, traitName) {
      if (obj === undefined || traitName === undefined) {
        throw new Error ("Unimplemented trait property.");
      }
      throw new Error (traitName + " is not implemented for " + obj);
    };
    
    • stackoverflow.com::
    • stackoverflow.com::
    • stackoverflow.com::
    • stackoverflow.com::

    我郑重建议你去图书馆结账。他们也有一篇关于一般模式及其具体实现的很好的文章。我最近在我的项目中内置了一个插件,它工作起来很有魅力。

    将TOrd.useBy移到Rational构造函数之外,改为作用于原型。太棒了!好老兰格!令人遗憾的是,没有逐行的解释。