ES6 类 默认值

ES6 Classes Default Value

是否可以创建一个 ES6 class,如果它没有在新方法中传递,则将默认值分配给 属性?

class myClass {
    constructor(options) {
        this.a = typeof options.a !== 'undefined' ? options.a : 'default a value';
        this.b = typeof options.b !== 'undefined' ? options.b : 'default b value';
        this.c = typeof options.c !== 'undefined' ? options.c : 'default c value';
    }
}

var myClassWithValue = new myClass({a:'a value', b: 'b value'});

如果我尝试使用此代码执行此操作,并使用 babeljs 进行编译,我会收到 TypeError: Cannot set 属性 'c' of undefined。

也许我不明白 classes 在 javascript 中是如何工作的。

我建议如下:

class myClass {
  constructor(options) {
    const defaults = {
      a: 'default a value',
      b: 'default b value',
      c: 'default c value'
    };
    const populated = Object.assign(defaults, options);
    for (const key in populated) {
      if (populated.hasOwnProperty(key)) {
        this[key] = populated[key];
      }
    }
  }
}

var myClassWithValue = new myClass({a:'a value', b: 'b value'});

如果你打算使用 ES6,为什么不使用所有的 ES6,即参数和解构赋值的默认值

class myClass {
  constructor({a = 'default a value', b = 'default b value', c = 'default c value'} = {a:'default option a', b:'default option b', c:'default option c'}) {
    this.a = a;
    this.b = b;
    this.c = c;
  }
}
var v = new myClass({a:'a value', b: 'b value'});
console.log(v.toSource());
var w = new myClass();
console.log(w.toSource());

http://www.es6fiddle.net/ibxq6qcx/

编辑:还在 https://babeljs.io/repl/

上测试并确认 运行

我刚刚问了一个类似的问题,在想出解决方案后发现了这个问题,所以我想我也post在这里。

我的问题特定于 ES6 并使用解构来设置 class 的参数默认值。似乎规范不允许您直接解构参数,除非您做类似于@Jaromanda X 所做的事情。

我想要更短更简洁的内容,最终使用了以下模式:

class Test {
    constructor(options) {
      let {
        defaultOne   : defaultOne   = 'default one value', 
        defaultTwo   : defaultTwo   = 'default two value', 
        defaultThree : defaultThree = 'default three value'
      } = (options) ? options:{};

      this.defaultOne   = defaultOne;
      this.defaultTwo   = defaultTwo;
      this.defaultThree = defaultThree;

      this.init();
    }

  init() {
    console.log(this.defaultOne);
    console.log(this.defaultTwo);
    console.log(this.defaultThree);
  }
}

new Test({defaultOne: 'Override default one value'});
new Test();

ES6 Babel test

Compiled Babel ES5

我们在这里所做的只是解构选项参数,我们用三元处理未定义的用例。

Object.assign 也适合我

class RenderProperties {
   constructor(options = {}){
        Object.assign(this, {
            fill : false, 
            fillStyle : 'rgba(0, 255, 0, 0.5)',
            lineWidth : 1,
            strokeStyle : '#00FF00'
        }, options);
    }
}

基于Default parameters from MDN web docs.的更短更清晰的版本

class myClass {
  constructor(
  a = 'default a value',
  b = 'default b value',
  c = 'default c value'
  ) {
      this.a = a;
      this.b = b;
      this.c = c;
    }
}

let myClassWithValue = new myClass('a value','b value');

console.log(myClassWithValue);

通过一个对象。

class myClass {
  constructor({
  a = 'default a value',
  b = 'default b value',
  c = 'default c value'
  }) {
      this.a = a;
      this.b = b;
      this.c = c;
    }
}

let options = {
  a: 'a value',
  b: 'b value'
}

let myClassWithValue = new myClass(options);

console.log(myClassWithValue);

我只是将其添加到原型中。 ES6 类 只是语法糖,因此您可以使用在引入 class 关键字之前可用的所有标准原型继承技术。

const {assign, seal} = Object;

class MyClass {
    constructor(options) {
        assign(seal(this), options);
    }
}

assign(MyClass.prototype, {
    a: "default a value",
    b: "default b value",
    c: "default c value"
});

所以我一直在阅读这个问题的答案,但我没有找到可以轻松处理扩展 classes 的答案,所以我想到了这个。

首先,您创建一个函数来检查 object 是否具有另一个 object 的属性:

function checkValues(values = {}, targets) {
  values = Object.keys(values);
  targets = Object.keys(targets);
  return values.every(keyValor => targets.includes(keyValor));
}

然后在 class 中定义默认值,如下所示:

class Error {
  constructor(options = {}) {
    //Define default values
    var values = {
      title: '',
      status: 500,
      mesagge: ''
    };
    //Check if options has properties of values
    var valid = checkValues(values, options);
    //If options doesn't has all the properties of values, assign default values to options
    if (!valid) {
      options = valores
    }
    //Asign options to the class
    Object.assign(this, options);
  }
}

所以现在,如果你想要一个 child class 你只需要声明默认值 child class:

class FormError extends Error{
  constructor (options = {}){
    var values = {
      invalidParams: [{name:'', reason: ''}]
    };
    var valid = checkValues(values, options);
    if (!valid) { options = values}
    super(options);
    Object.assign(this, options);
  }
}

示例:

var a = new Error();
var b = new FormError();
var c = new FormError({invalidParams: [{name: 'User', reason: 'It has to be a string!'}]});
console.log(a, b, c);

注意: 仅当您希望拥有所有默认值而不仅仅是其中一些默认值时才有效,例如:

var e = new Error({message: 'This is an error'});
console.log(e.message);// ''
//Error e will only have the default values, and message would be empty.

var h = new FormError({title: 'FORM ERROR', status: 400});
console.log(h.title);//''
//Error h will only have the defaults because I didn't provide 'invalidParams'

if there is no parameter passing through the constructor, it is assigned a default value as it was pre-set, I hope I have helped!

class User {
  constructor(fullName = "fooName", lastName, canAccess = false) {
    this.fullName = fullName;
    this.lastName = lastName;
    this.canAccess = canAccess;
  }
}

如果您希望某些属性默认但另一些属性不默认,您也可以使用展开运算符(工作方式与 Object.assign 答案相同)

const defaults = {someDefault: true};

class SomeClass {
    constructor(config) {
        this.config = {...defaults, ...config};
    }
}

我做了一个小修正:用 Object()

替换了大对象
class SomeClass {
  constructor({a = 'defA', b = 'defB', c = 'defC'} = Object()) { 
    this.a = a;
    this.b = b;
    this.c = c; }
}
console.log(new SomeClass ({a:'a', b:'b', c:'c'}))
console.log(new SomeClass ({a:'a', c:'c'}))

(节点 REPL)输出:

SomeClass { a: 'a', b: 'b', c: 'c' }
SomeClass { a: 'a', b: 'defB', c: 'c' }

我建的。我认为这是阅读该问题中代码的最简单方法。

class myClass {

    constructor(options){

        let default_values ={
            a: '',
            b: '',
            c: ''
        }
        options = {...default_values, ...options}

        this.a = options.a;
        this.b = options.b;
        this.c = options.c;
    }
}