将参数传递给类构造函数

时间:2016-01-10 12:56:27

标签: javascript node.js

我已经编写了以下模块,但导入它并没有按预期工作。文件(简称为简称):

templates.js

'use strict';

export default class Templates {
    constructor (args) {
        this.files = [{
            name: `${args.name}.js`,
            path: 'src/',
            content: ''
        }];
        /* code omitted */
    }
};

我试图像这样使用它:

index.js

import Templates from './templates'

const opts = {name: 'app'};
/* code ommited */
console.log('Templates >>', typeof Templates);
console.log('Templates >>', new Templates());

let tmpls = new Templates(opts);
console.log(tmpls.files[0].name);

但我在控制台中收到以下错误跟踪。

npm ERR! Linux 3.16.0-38-generic
npm ERR! argv "/home/wesleycoder/.nvm/versions/node/v5.1.0/bin/node" "/home/wesleycoder/.nvm/versions/node/v5.1.0/bin/npm" "init"
npm ERR! node v5.1.0
npm ERR! npm  v3.3.12

npm ERR! Cannot read property 'name' of undefined

是的,这是一个~/.npm-init脚本供谁问。

修改 感谢@low_ghost的有用回复。

我发现我的问题不是出口和导入课程。 它实际上是关于将参数传递给这个类,而不是关于不传递参数。所以我改变了简洁的标题。

我的代码中没有任何参数的console.log(new Templates())是故意的。 我试图解决的错误是关于实例化对象和获取文件数组,但我直接从commander.js库传递参数,并且传递的参数是" overkill"为了完成这个任务,所以我通过从commander.js获取输入并在空对象中的属性中分配每个参数然后沿着构造函数传递此对象来简化参数,这允许我取readline-sync并读取来自未通过的选项的输入并使脚本更加精彩,在此之后一切正常。

如果commander.js有任何选项可以在不增加库属性的额外权重的情况下传递选项,那就没关系了。

对于有兴趣的人,项目是here on github。你可以分叉,自己制作变种和分享,我发现使用~/.npm-init可以帮助你创建需要更具体环境的项目。

EDIT2: 毕竟commander.js没有用,因为我无法将npm init命令中的参数传递给它自己的脚本。

2 个答案:

答案 0 :(得分:3)

由于构造函数调用中缺少参数,因此名称未定义。根据意图,最佳解决方案是检查名称的存在和类型:

 'use strict';

 export default class Templates {
   constructor (args) {
     this.files = (args.name && typeof arg.name === "string")
       ? [{
           name: `${args.name}.js`,
           path: 'src/',
           content: ''
         }]
       : [];
    /* other code */
   }
};

如果你对三元组合你好的话。如果arg.name不存在或者不是字符串,则返回一个空数组作为this.files。

编辑:

或者,正如madox2建议的那样,提供默认值。虽然我会使用名称的默认值而不是整个args对象。像:

 constructor({ name = 'defaultName', ...otherArgs } = {})

如果您致电:

 new Templates({ dir: 'repo' })

你仍然会有默认的名称,如果你按字面意思取得省略号,你可以从otherArgs.dir获得dir。 = {}部分允许调用

 new Templates()

并仍然获得默认名称。

答案 1 :(得分:2)

Templates类的构造方法将object作为参数。如果您未通过,args参数为undefined,当您致电args.name时,参数将失败。试试这个:

console.log('Templates >>', new Templates({}));

或:

console.log('Templates >>', new Templates({name: 'myName'}));

您还可以在构造函数中设置默认参数值,然后在不带参数的情况下调用它:

constructor (args = {name: 'defaultName'}) {
    //...