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

 

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