Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 以干净的方式从构造函数参数为类设置属性_Javascript_Ecmascript 6 - Fatal编程技术网

Javascript 以干净的方式从构造函数参数为类设置属性

Javascript 以干净的方式从构造函数参数为类设置属性,javascript,ecmascript-6,Javascript,Ecmascript 6,我为一个接收一些参数的类编写了这段代码,并且每次将它们作为对象属性指定一次 class InitAnimation { constructor(settingsAnimation, settingButton, isHelp, isEnd) { // Initialized the configuration for main animation. this.settingsAnimation = settingsAnimation; this.settingBut

我为一个接收一些参数的类编写了这段代码,并且每次将它们作为对象属性指定一次

class InitAnimation {
  constructor(settingsAnimation, settingButton, isHelp, isEnd) {
    // Initialized the configuration for  main animation.
    this.settingsAnimation = settingsAnimation;
    this.settingButton = settingButton;
    this.yes = null;
    this.no = null;
    this.isHelp = isHelp;
    this.isEnd = isEnd;
    this.initConfig();
  }
在ES6中是否有一种更干净的方法可以做到这一点,即我只需要获取参数键值并将它们作为计算属性名分配给对象?比如:

class InitAnimation {
  constructor(settingsAnimation, settingButton, isHelp, isEnd) {
    // Initialized the configuration for  main animation.
    // I know this doesn't work on 'arguments'
    arguments.forEach(key => this[key] = arguments[key]);
    this.initConfig();
}

在这种情况下,我不能修改发送参数的方式,因为这意味着要更改其他人的代码,而且项目现在有点大。我是否可以在不更改参数传递方式的情况下以更好的方式执行此操作?

是的,在ES2015+中,您可以使用
对象。分配
和速记属性:

constructor(settingsAnimation, settingButton, isHelp, isEnd) {
  // Initialized the configuration for  main animation.
  Object.assign(this, {settingsAnimation, settingButton, isHelp, isEnd});
  this.yes = null;
  this.no = null;
  this.initConfig();
}
实例:

类初始化动画{
构造函数(设置动画、设置按钮、isHelp、isEnd){
//初始化了主动画的配置。
赋值(this,{settingsAnimation,settingButton,isHelp,isEnd});
this.yes=null;
this.no=null;
this.initConfig();
}
initConfig(){
}
}
常数a=新的初始动画(“a”、“b”、“c”、“d”);

控制台日志(a)您可以使用以下技术检测函数参数的名称:

因此,您可以将其应用于构造函数,然后使用循环将参数名称与其值(按索引)匹配,然后将其应用于对象

function argumentsToObject( func, args ) {
   const argNames = getArgumentNames( func ); //use the code from the above link to do this
   const resultObject = {};
   argsNames.forEach( ( argName, index ) => {
      var argValue = args[index];
      resultObject[ argName ] = argValue;
   });
}
然后在构造函数中,执行以下操作:

const argsObject = argumentsToObject( InitAnimation.prototype.constructor, arguments );
//copy all the arguments onto this
Object.assign( this, argsObject );

这里有几个选项

对象文字可用于指定属性。这会导致复制和粘贴参数,以便显式枚举它们,但会导致更可靠的代码和函数签名,可以进行静态分析:

  constructor(foo, bar) {
    Object.assign(this, { foo, bar });
    ...
  }
参数可以根据参数列表进行处理。这会导致参数列表被枚举一次,但函数签名是松散的,无法对其进行静态分析,并且容易出现人为错误:

  constructor(...args) {
    ['foo', 'bar']
    .forEach((paramName, i) => {
      this[paramName] = args[i];
    });
  }
应该注意的是,这在TypeScript中得到了有效解决,这也是为什么可以选择它而不是普通JavaScript的原因之一:

constructor(public foo) {}
语法上的糖是什么

constructor(foo) {
  this.foo = foo;
}

我认为询问者不想重新列出所有参数。@DuncanThacker:唯一合理的避免方法是接受一个对象,即使这样,你也会合并该对象的所有属性(这可能不安全)。以上内容简洁明了,避免了不必要的重复(例如,每个参数名称只列出两次而不是三次)。@DuncanThacker:正如estus所说,缩小。相对于价值而言,也有明显的高开销,
toString
直到最近才被标准化,不同的浏览器在评论方面表现不同,……我认为这是一种方式,它是干净的,一行代码。我不能更改构造函数参数的任何内容,但在函数内部它是可以的,此外,我可以选择要合并的参数。谢谢你的回答!
…args
方法的缺点是函数的arity会受到影响,代码辅助在编写调用时无法检测参数名和帮助。不过,还是很有创意的。是的,我发现你提到的第一种选择通常更可取,它是湿的,但不太容易出现人为错误。第二个选项适用于调用过程中没有明确列出函数参数的情况(例如,在DI容器中)。即使此时代码没有缩小,像这样的设计解决方案也将成为客户端项目未来的一个障碍(问题没有
node.js
标记)。建议这样的解决方案并将其牢记在心是可以的,但是开发人员应该了解其中的含义——并非所有人都知道依赖函数/类名和签名是不安全的。