Angular中mixins繼承

 第一種方式

/**
 * @函數名稱:copyProperties
 * @param
 * @作用:類的屬性和函數copy
 */
function copyProperties(target, source) {
  for (let key of Reflect.ownKeys(source)) {
    if ( key !== 'constructor'
      && key !== 'prototype'
      // && key !== 'name' // name 屬性允許繼承
    ) {
      let desc = Object.getOwnPropertyDescriptor(source, key);
      Object.defineProperty(target, key, desc);
    }
  }
}

/**
 * @函數名稱:mixin
 * @param  類名
 * @作用:實現多繼承
 * @return:繼承後的類
 */
export function mixin(...mixins) {
  class Mix {
    constructor() {
      for (let mixin of mixins) {
        copyProperties(this, new mixin()); // 拷貝實例屬性
      }
    }
  }

  for (let mixin of mixins) {
    copyProperties(Mix, mixin); // 拷貝靜態屬性
    copyProperties(Mix.prototype, mixin.prototype); // 拷貝原型屬性
  }

  return Mix;
}

class Cat {
  name = 'cat'; //
}

class Dog {
  getName() {
    return this['name'];
  }
}

class Test extends mixin(Dog, Cat){};

var test = ()=> new Test();
// name屬性爲class關鍵字後面的類名
console.log(Test.name); // Test
console.log(test.name); // test
console.log(test().name); // cat
console.log(test().getName()); // cat

 第二種方式:通過修飾器實現

/**
 * 通過修飾實現混合繼承
 * @param mixins
 */
export function mixins(...mixins) {
  return function (target) {
    const _mixins = mixin(...mixins);
    const instance = new _mixins();
    Object.assign(target.prototype, instance);
  }
}

class Cat1 {
  _name = 'cat';
}

class Dog1 {
  // 函數必須是等於這種屬性的形式來寫才能繼承
  getName = function () {
    return this['_name'];
  }
}

// 不能繼承name屬性 且定義name時會報錯
@mixins(Cat1, Dog1)
class Test1 {}

var test1 = new Test1();
console.log(Test1.name); // Test1
console.log(test1._name); // Test1
console.log(test1['getName']()); // cat

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章