如何在javascript中實現特質?javascript中的特質
15
A
回答
15
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);
};
例子:
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]
2
有不同的方法,並在此期間生產做好準備庫以及。
Mixins是跨類繼承的最舊代碼重用形式。由於Mixins的概念不涵蓋/識別衝突解決功能,它們需要按照線性順序組成。
特徵是精細粒度的代碼重用單元,也在類級別上工作;但它們更靈活,因爲Traits必須提供組合操作符來組合,排除或混淆方法。
我確實推薦閱讀2篇論文,這兩篇論文都介紹了Mixins/Traits/Talents的基於圖書館不可知論的基於純函數的方法。
- A fresh look at JavaScript Mixins安格斯·克羅爾從2011年5月
- The many talents of JavaScript for generalizing Role Oriented Programming approaches like Traits and Mixins從2014年4月
爲具備未來2個給出的例子基於混入力學中的純函數和代表團的那麼簡單......
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
如果一個人是需要建立和/或生產準備庫應該有
這麼久
細看附錄I
另請參見:
- stackoverflow.com :: How to use mixins properly in Javascript
- stackoverflow.com :: Javascript Traits Pattern Resources
附錄II
由於不時我顯然撥弄與此有關的事情,我不想添加一些最後的想法...
沒有太多膠合代碼的庫不可知方法(如上所述)只適用於行爲重用的非常細粒度的可組合單元。因此,只要沒有遇到超過1或2個容易解決的衝突,基於例如安格斯克羅爾的Flight Mixins是遵循的路徑。
如果涉及真正的特徵,那就必須有一個抽象層次。這一層(例如像DSL那樣的某種語法糖提供)需要隱藏複雜性,例如從特徵構成特徵或在特徵上解決衝突適用時間(當特質的行爲應用於對象/類型時)。
現在有3個例子,在讓從我的角度提供並問到底是什麼OP爲...
我如何能實現在JavaScript特質?
- stackoverflow.com :: Compostions and mixins in JS
- stackoverflow.com :: Mixins for ES6 classes, transpiled with babel
- stackoverflow.com :: Refactoring legacy mixin-based class hierarchies
- stackoverflow.com :: Multiple inheritance using classes
2
我認真推薦你去結帳trait.js庫。他們對於總體模式及其具體實施也有不錯的文章。我最近內置於我的項目中,它的作用就像一個魅力。
相關問題
- 1. phpunit中的特質TestCase
- 2. MCMCglmm中「特質」的含義
- 3. 圈JSON的特質
- 4. 特質實施
- 5. 駝鹿特質
- 6. 特質好壞?
- 7. 特質指針
- 8. 內特質
- 9. 從特質
- 10. 使用另一個特質的PHP特質
- 11. 缺少GWT特質
- 12. canEqual()在scala.Equals特質
- 13. 阿爾特性質
- 14. RAML特質定義
- 15. 撰寫獨立的特質
- 16. Rspec stubbing在FactoryGirl的特質
- 17. 初始化的特質
- 18. jqGrid的特徵質疑
- 19. Symfony 2項目中的特質位置
- 20. 如何重寫PHP中的特質?
- 21. 斯卡拉特質中的Setter和Getters?
- 22. 在PHP中使用最終的特質
- 23. 斯卡拉特質中的衝突域
- 24. 特質中的惰性斷言
- 25. 如何強制一個特質來實現另一個特質
- 26. 特質「應用/ Elasticquent特質」未找到laravel5.2和elasticsearch-2.3.2
- 27. 斯卡拉:讓特質依賴於其他特質
- 28. 什麼特質lib真的帶來了JavaScript?
- 29. 的Javascript UC和UC性質
- 30. 在C++中忽略了特質專精
移動Rational構造函數之外的TOrd.useBy以代替原型。 – 2009-12-31 07:40:15
真棒太棒了!好老的語言!好的新思想 – asyncwait 2011-02-24 15:10:32