我可以有一个返回另一个类实例的类实例吗?

时间:2016-04-01 20:31:51

标签: javascript class oop inheritance

我正在尝试让一个对象返回另一个对象,并将一些数据传递给所有微实例。这就是我想要实现的目标。

export class Macro {
  constructor(props) {
    return (props) => {
      return Micro(props)
    }
  }
}

export class Micro {
  constructor(props) {
    this.macro = props
  }
}

let MicroInstance = new Macro({'happy': true})
let instance = new MicroInstance()
console.log(instance.macro.happy) // true

这会引发错误:

  _classCallCheck(this, Macro);
                        ^

ReferenceError: Macro is not defined

更新1)

这是一个更现实的用例。我正在尝试创建一个使用定义类信息的自定义错误对象,这样我就不必继续将所有相同的参数传递给LangError类。

let languages = {
  "en": {
    "login_errors": {
      "invalid_name": "Invalid Name: {name}!"
    }
  },
  "jp": {
    "login_errors": {
      "invalid_name": "無効な名前: {name}"
    }
  },
  "es": {
    "login_errors": {
      "invalid_name": "Nombre no válido: {name}!"
    }
  }
}

let LangError = new LangErrorDefinition({languages, nestedLocalesProp: 'login_errors'})
let error = new LangError('invalid_name', { name: 'Thomas' })
console.log(error.messages)

// { en: 'Invalid Name: Thomas!',
//   jp: '無効な名前: Thomas',
//   es: 'Nombre no válido: Thomas!' }

更新2)

使用Jonathan Lonowski的答案,jsfiddle

class Macro {
  constructor(props) {
    return () => {
      return new Micro(props)
    }
  }
}

class Micro {
  constructor(props) {
    this.macro = props
  }
}

let MicroInstance = new Macro({'happy': true})
let instance = new MicroInstance()
console.log(instance.macro.happy) // true

然而,它仍然在我的本地文件中给我一个babel错误。

/Users/thomasreggi/Desktop/project/test/error-suite.js:99
  _classCallCheck(this, Macro);
                        ^

ReferenceError: Macro is not defined
    at new Macro (error-suite.js:94:7)
    at Object.<anonymous> (error-suite.js:108:21)
    at Module._compile (module.js:398:26)
    at loader (/Users/thomasreggi/.nvm/versions/node/v5.3.0/lib/node_modules/babel-cli/node_modules/babel-register/lib/node.js:130:5)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/thomasreggi/.nvm/versions/node/v5.3.0/lib/node_modules/babel-cli/node_modules/babel-register/lib/node.js:140:7)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Function.Module.runMain (module.js:430:10)
    at /Users/thomasreggi/.nvm/versions/node/v5.3.0/lib/node_modules/babel-cli/lib/_babel-node.js:161:27
    at Object.<anonymous> (/Users/thomasreggi/.nvm/versions/node/v5.3.0/lib/node_modules/babel-cli/lib/_babel-node.js:162:7)

更新3)

上述错误是由于赞扬了日文字符,我正在使用babel-node以及2015react预设。

https://gist.github.com/reggi/cb9e83ce74de17da1ca2935b0bb3ff1d

2 个答案:

答案 0 :(得分:4)

不是真的。当构造函数返回任何对象(包括函数)时,new将按原样返回该对象,而不是它创建的实例

console.log(MicroInstance instanceof Macro);    // false
console.log(MicroInstance instanceof Function); // true

但是,考虑到这一点,Macro(或LangErrorDefinition)可能只是一个函数,它返回的内容可能是一个新类(例如,ModifiedMicro)。

这仍然可以通过继承(Micro)使用extends,以避免为闭包中创建的每个ModifiedMicro重新定义大部分类(Macro

export class Micro {
  constructor(props, ...args) {
    this.macro = props;
    this.micro = args;
  }
}

export function Macro(props) {
  return class ModifiedMicro extends Micro {
    constructor(...args) {
      super(props, ...args);
    }
  };
}

let MicroInstance = Macro({'happy': true}) // no need for `new`
let instance = new MicroInstance('one', 'two')

console.log(instance.macro.happy) // true
console.log(instance.micro)       // ['one', 'two']

console.log(instance instanceof Micro); // true

[原始答案]

constructor的{​​{1}}目前有2个问题:

  1. Macro参数被声明两次。

    props

    由于变量阴影,第二个声明将提供给constructor(props) { // 1st return (props) => { // 2nd // ... } } ,但只有第一个声明会在您的使用中被赋予一个值:

    Micro(props)
  2. 返回let MicroInstance = new Macro({'happy': true}) // 1st let instance = new MicroInstance(/* props */) // 2nd 时缺少new

    Micro(props)

    如果没有,您应该看到return new Micro(props)

      

    没有'new'

    ,不能调用类构造函数Micro
  3. 根据您的预期,TypeError应根据需要调整console.log()

    true

答案 1 :(得分:0)

export function Macro( props) {
    return function() { this.macro = props }
}

可以在不使用胖箭头函数(不能用作构造函数)或与原型链交互的情况下提供所述功能。

new来电中的new Macro会产生噪音,应予以省略。当调用Macro.prototype时,包含它会在Macro上创建一个新的Macro实例对象,只是为了让实例对象被丢弃,因为Macro返回一个(不同的)函数对象。