如何使用ES6类实例属性和方法扩展对象

时间:2017-09-18 14:34:51

标签: javascript ecmascript-6 ecmascript-5 es6-class

我正在重构旧版ES5代码库中的一些代码,我正在执行以下操作:

function ObjectCreatorFunction() {
  this.someProperty= {};
}

/*
 * Static method, to extend the object passed as a parameter with the
 * ObjectCreatorFunction instance properties and methods
 */
ObjectCreatorFunction.extend = function extend(object) {
  var key;

  ObjectCreatorFunction.call(object);
  for (key in ObjectCreatorFunction.prototype) {
    if (ObjectCreatorFunction.prototype.hasOwnProperty(key)) {
      if (!object.hasOwnProperty(key)) {
        object[key] = ObjectCreatorFunction.prototype[key];
      }
    }
  }

  return object;
};

ObjectCreatorFunction.prototype.someMethod = function someMethod() {...}
//etc

我试图用ES6重写做同样的事情,所以我有这个

class ClassName{
  constructor() {
    this.someProperty= {};
  }

  static extend(object) {
    let key;

    ClassName.constructor.call(object);
    for (key in ClassName.prototype) {
      if (ClassName.prototype.hasOwnProperty(key)) {
        if (!object.hasOwnProperty(key)) {
          object[key] = ClassName.prototype[key];
        }
      }
    }

    return object;
  }

  someMethod() {...}
  //etc
}

我的问题是该行 ClassName.constructor.call(object); 不按预期工作,即传递的对象不获取类的实例属性。

我尝试过几种方法来重写这个(甚至一些非正统的方法)无济于事。

如何使用ES6扩展具有类'实例属性的对象?

声明:

我的代码通过转发过程传递,包含babel和webpack。如果它对类的内部工作方式有任何影响。

1 个答案:

答案 0 :(得分:1)

不,这不适用于class语法。它只是a bit more而不仅仅是语法糖。原型继承保持不变,但实例的初始化现在的工作方式不同,特别是对于继承的类,并且如果没有new则不能调用不创建新实例的构造函数。

我建议明确一下你的mixin,并给它一个init方法:

class Mixin {
    constructor(methods) {
        this.descriptors = Object.getOwnPrpertyDescriptors(methods);
    }
    extend(object) {
        for (const p of this.descriptors)) {
            if (Object.prototype.hasOwnProperty.call(o, p)) {
                if (process.env.NODE_ENV !== 'production') {
                    console.warn(`Object already has property "${p}"`);
                }
            } else {
                Object.defineProperty(o, p, this.descriptors[p]);
            }
        }
    }
}

// define a mixin:
const xy = new Mixin({
    initXY() {
        this.someProperty= {};
    },
    someMethod() { … }
});
// and use it:
class ClassName {
    constructor() {
        this.initXY();
    }
}
xy.extend(ClassName.prototype);