【问题标题】:Javascript Traits Pattern ResourcesJavascript 特征模式资源
【发布时间】:2011-10-22 01:51:00
【问题描述】:

谁能推荐在 javascript 中使用特征的好资源?经过一番搜索,我主要找到有关提供特征功能的库的文章,但我很好奇如何在没有库的情况下实现特征的最佳实践。

我在 SO 上看到了这篇文章,还有其他方法吗? Traits in javascript

也欢迎任何现实世界的例子。

谢谢。

【问题讨论】:

    标签: javascript traits


    【解决方案1】:

    我会建议一些简单的东西,大致如下:

    1. 让特征被定义为标准的 JavaScript 对象。

      var equalsTrait = {
          eq: function(obj) {
              return this == obj
          },
          neq: function(obj) {
              return ! this.eq(obj)
          }
      };
      
    2. 编写一个函数以使用您的特征扩展给定类(并将其绑定到全局范围内的合理位置):

      window.Traits = {};
      Traits.addToClass = function(traits, cls) {
          for (var key in traits) {
              if (cls.prototype[key]) {
                  alert("Class " + cls + " already has a method named " + key + "!");
              }
              else {
                  cls.prototype[key] = traits[key];
              }
          }
      }
      
    3. Profit!

    【讨论】:

    • 感谢您的示例。因此,从模式的角度来看,您认为要正确实现特征需要满足哪些标准?特征是可以由任何对象实现的可重用功能。除此之外还有什么?我在库中看到他们处理命名空间冲突。在您的示例中,特征被复制到创建的每个实例中,在所有实例之间共享特征会更好(如果甚至需要的话)?
    【解决方案2】:

    trait.js 库中有关特征的一些(有限)信息

    不是关于 Javascript,而是一篇关于继承系统和特征的好论文“Traits: A Mechanism for Fine-grained Reuse”。实现细节的描述可以在“Applying Traits to the Smalltalk Collection Hierarchy”中找到。更多此类论文列于this page

    【讨论】:

      【解决方案3】:

      2011 年 5 月 Angus Croll 的 A fresh look at JavaScript Mixins 和 2014 年 4 月的 The many talents of JavaScript for generalizing Role Oriented Programming approaches like Traits and Mixins 两篇确实描述了库无关纯函数的基于 Mixin 和 Trait 方法的论文。

      这么久

      附录一

      另请参阅:

      附录二

      由于我时不时地摆弄这件事,所以我不想在这件事上添加一些最后的想法......

      没有太多胶水代码(如上所述)的库无关方法仅适用于行为重用的非常细粒度的可组合单元。因此,只要不遇到超过 1 或 2 个易于解决的冲突,基于例如Angus Croll 的 Flight Mixins 是我们应该遵循的路径。

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

      到目前为止,SO 有 3 个示例,从我的角度来看,它们提供了 OP 确实要求的内容……

      也欢迎任何现实世界的例子。

      【讨论】:

        【解决方案4】:

        您可以在没有库的情况下使用函数来实现特征。

        查看工作示例Traits + Inheritance

        感谢dbarbeau

        // Usage __traits(TargetClass, Trait1, Trait2, ...);
        // Mix multiple definitions as traits. Properties will be overwritten if names are duplicating. 
        function __traits(mixtureTarget) {
            for(var a=1; a < arguments.length; ++a) {
                var mixin = arguments[a];
                for (var p in mixin){ if (mixin.hasOwnProperty(p)){ mixtureTarget[p] = mixin[p]; } };
                Object.getOwnPropertyNames(mixin.prototype).forEach( function(name) {
                    mixtureTarget.prototype[name] = mixin.prototype[name];
                });
            }; 
        };
        

        【讨论】:

          【解决方案5】:

          在 npm 中有一个简单轻量级的包。你可以在这里查看它,它确实使 PHP 特性的特性很容易在 Javascript 上实现。

          https://github.com/regs37/trait.js

          // create a simple trait that you want to be reusable
          const MyTrait = trait({
            sampleTrait: function(){
              return "trait";
            }
          })
          
          // lets have a sample class User
          class User {
          
          }
          
          // we will inherit the trait to the User Class
          MyTrait.in(User);
          
          // sample instance of the user
          let user = new User();
          
          // try to call he trait we have inherited
          console.log(user.sampleTrait()); // trait
          &lt;script src="https://unpkg.com/trait.js@1.2.12/build/trait.min.js"&gt;&lt;/script&gt;

          【讨论】:

          • 这个不错的项目实际上更适合许多现有的方法/解决方案/实现,这些方法/解决方案/实现更好地标记为 mixin。 trait 与更直接的 mixin 方法不同,它提供(除了基本组合任务之外)冲突解决过程/运算符,例如 beforeafteralias,例如同名的方法。为任何类型的prototype 对象(如inherit_to)提供混合功能不会自动使实现成为trait
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-03-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-08-09
          相关资源
          最近更新 更多