将ES6类存储在变量中,并通过Object.Create实例化它

时间:2016-08-25 21:26:59

标签: javascript angularjs ecmascript-6

我目前需要通过变量将传递给动态调用其构造函数的函数,依此类推。简短的例子:

class MyClass {
  constructor ($q) {
    console.log($q);
  }

  expose () {
    return {};
  }
}

const myclass = function () {
  // My concern is this ------.
  // I need to pass it        |
  // as a variable           \|/
  //                          '
  let obj = Object.create(MyClass.prototype);
  obj.constructor.apply(obj, arguments);
  return {}; // other stuff goes here
};
myclass.$inject = ['$q'];
export {myclass};

我的想法是将MyClass作为变量传递,以这种方式:

const myclass = function (classVariable) {
  let obj = Object.create(classVariable.prototype);
  obj.constructor.apply(obj, arguments);
  return {}; // other stuff goes here
};

因此我可以像let newclass = myclass(MyClass);一样调用它。这样,如果我有不同的类(MyClass2,MyClass3等),我不必在每个文件中重复代码。如果我尝试这样做,Chrome会抛出一个错误,说它不能使用类作为变量或类似的东西。

那么,这样做的最佳方法是什么,避免重复代码?它实际上是一个重新设计我正在努力避免由我需要解决的其他人造成的复制粘贴灾难。提前谢谢!

2 个答案:

答案 0 :(得分:6)

我认为您的困惑在于您认为类构造函数不能被变量引用。他们可以,他们只是功能。所以:

class Foo {
    message() {
        console.log("I'm a Foo");
    }
}
class Bar {
    message() {
        console.log("I'm a Bar");
    }
}
function test(C) {
      let obj = new C();
      obj.message(); // "I'm a Foo" or "I'm a Bar", depending on
                     // whether Foo or Bar was passed in
}
test(Foo);
test(Bar);

您调用var obj = Object.create(X.prototype)后跟X.apply(obj, /*...args here...*/)的模式可以在ES5及更早版本中使用,但ES2015的类不允许这样做。要从它们构造实例,您使用new运算符。其原因与子类化和设置new.target有关,因此如果实例有理由创建新实例(如Promise那样),它可以以明确的方式做到这一点。

这似乎可能是后退一步,但如果由于某种原因你将构造函数参数作为数组而不是离散项,那么扩展表示法允许你使用new

let obj = new C(...args);

所以 if 你需要一个接受类构造函数和参数数组的泛型函数,并且需要使用这些参数返回该类的实例,它看起来像这样:

function createInstanceOf(C, args) {
    return new C(...args);
}

答案 1 :(得分:0)

我相信你要找的是closure

function makeFactory(constructor) {
  return function(...args) {
    let obj = new constructor(...args);
    return {}; // other stuff goes here
  };
}
const myclass = makeFactory(MyClass);
// then use
myClass().expose() // or whatever you were going to do with it