Multiple inheritance using classes

前端 未结 4 1337
小蘑菇
小蘑菇 2020-12-11 14:15

Is it possible to extend only some specific part from multiple classes? Example:

4条回答
  •  渐次进展
    2020-12-11 14:33

    Note ... I had to split my previous answer into 2 separate parts since for quite a while it is not anymore that easy referencing outside hosted javascript code. Due to that I now do provide the necessary trait library as minified inline code within the next given example ...

    Having on hand natively implemented Talents or Traits one day in JavaScript, will make this kind of composition even more flexible/powerful ...

    var
      withWalkingAbility = (function mixinFactory () {
        function walking() {
          return "walking";
        }
        return function abilityMixin () {
          this.walk = walking;
        };
      }()),
    
      withRunningAbility = Trait.create(function trait (use, applicator) {
        function running() {
          return "running";
        }
        applicator(function () {
          this.run = running;
        });
      });
    
    var
      withSelfAwareness = (function mixinFactory () {
        function reflectThySelf() {
          return "I'm";
        }
        return function awarenessMixin () {
          this.reflect = reflectThySelf;
        };
      }()),
    
      withDepersonalization = Trait.create(function trait (use, applicator) {
        function objectify() {
          return "It's";
        }
        applicator(function () {
          this.objectify = objectify;
        });
      });
    
    var
      withSelfAwareWalkingAndRunningAbility = Trait.create(function trait (use, applicator) {
    
        use(withWalkingAbility, withRunningAbility)
          .apply.all();
    
        applicator(function () {
    
          this.walk = (function (proceed) {
            return function () {
    
              console.log([this.reflect(), proceed.call(this)].join(' '))
            };
          }(this.walk));
    
          this.run = (function (proceed) {
            return function () {
    
              console.log([this.reflect(), proceed.call(this)].join(' '))
            };
          }(this.run));
    
        }).requires([
    
          "reflect"
    
        ]);
      }),
      withDepersonalizedRunningAbility = Trait.create(function trait (use, applicator) {
    
        use(withRunningAbility)
          .apply(withRunningAbility);
    
        applicator(function () {
    
          this.run = (function (proceed) {
            return function () {
    
              console.log([this.objectify(), proceed.call(this)].join(' '))
            };
          }(this.run));
    
        }).requires([
    
          "objectify"
    
        ]);
      });
    
    
    
    class Human {
      constructor() {
        // `Human` specific instance slots.
      }
      // `Human` specific prototypal methods.
    }
    withSelfAwareness.call(Human.prototype);
    
    
    class Animal {
      constructor() {
        withDepersonalization.call(this);
        // other `Animal` specific instance slots.
      }
      // `Animal` specific prototypal methods.
    }
    
    
    class HumanWalkerAndRunner extends Human {
      constructor() {
        super();
      }
    }
    withSelfAwareWalkingAndRunningAbility.call(HumanWalkerAndRunner.prototype);
    
    
    class AnimalRunner extends Animal {
      constructor() {
        super();
        withDepersonalizedRunningAbility.call(this);
      }
    }
    
    
    var
      humanWalkerAndRunner = (new HumanWalkerAndRunner),
      animalRunner = (new AnimalRunner);
    
    console.log('humanWalkerAndRunner : ', humanWalkerAndRunner); // HumanWalkerAndRunner {}
    console.log('(humanWalkerAndRunner instanceof HumanWalkerAndRunner) ? ', (humanWalkerAndRunner instanceof HumanWalkerAndRunner)); // true
    console.log('(humanWalkerAndRunner instanceof Human) ? ', (humanWalkerAndRunner instanceof Human)); // true
    humanWalkerAndRunner.walk(); //  "I'm walking"
    humanWalkerAndRunner.run(); //  "I'm running"
    console.log('(humanWalkerAndRunner.hasOwnProperty("walk")) ? ', humanWalkerAndRunner.hasOwnProperty("walk")); // false
    console.log('(humanWalkerAndRunner.hasOwnProperty("run")) ? ', humanWalkerAndRunner.hasOwnProperty("run")); // false
    
    console.log('\n');
    
    console.log('animalRunner : ', animalRunner); // AnimalRunner {objectify: function, run: function}
    console.log('(animalRunner instanceof AnimalRunner) ? ', (animalRunner instanceof AnimalRunner)); // true
    console.log('(animalRunner instanceof Animal) ? ', (animalRunner instanceof Animal)); // true
    animalRunner.run(); //  "It's running"
    console.log('(animalRunner.hasOwnProperty("run")) ? ', animalRunner.hasOwnProperty("run")); // true
    .as-console-wrapper { max-height: 100%!important; top: 0; }

提交回复
热议问题