ES6类默认值

时间:2015-07-10 13:40:42

标签: javascript ecmascript-6 babeljs

是否可以创建一个ES6类,如果属性未在新方法中传递,则为该属性分配默认值?

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:无法设置未定义的属性“c”。

也许我没有得到javascript中的类如何工作。

12 个答案:

答案 0 :(得分:21)

如果您要使用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/

上投放

答案 1 :(得分:12)

Object.assign 也适用于我

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

答案 2 :(得分:5)

我建议如下:

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'});

答案 3 :(得分:3)

如果您希望某些属性为默认属性,但有些属性不可用,则可以使用扩展运算符(与Object.assign答案相同)

const defaults = {someDefault: true};

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

答案 4 :(得分:1)

  

TypeError:无法设置属性' c'未定义的。

这意味着options未定义。

确保options对象存在,首先:

if(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';
}else{
    this.a = 'default a value';
    this.b = 'default b value';
    this.c = 'default c value';
}

或者,好又短:

options = 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';

答案 5 :(得分:0)

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

我的问题是针对ES6并使用解构来设置类的参数默认值。似乎规范不允许你直接解构参数,除非你做类似于@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

我们在这里所做的就是解构options参数,我们用三元组来处理未定义的用例。

答案 6 :(得分:0)

基于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);




传递一个Object。



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);




答案 7 :(得分:0)

我只是将其添加到原型中。 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"
});

答案 8 :(得分:0)

因此,我一直在阅读有关此问题的答案,但找不到适合扩展类的方法,所以我想到了这一点。

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

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

然后在类中定义如下默认值:

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);
  }
}

现在,如果您想拥有一个子类,则只需声明该子类的默认值即可:

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'

答案 9 :(得分:0)

  

如果没有参数通过构造函数,则为   分配了默认值作为默认值,希望对您有所帮助!

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

答案 10 :(得分:0)

我做了一个小小的更正:用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' }

答案 11 :(得分:-1)

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

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;
    }
}