2015-07-10 36 views
7

Czy można utworzyć klasę ES6, która przypisuje wartość domyślną do właściwości, jeśli nie została przekazana w nowej metodzie?Klasy ES6 Wartość domyślna

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

Jeśli staram się robić to z tego kodu, kompilacja z babeljs, otrzymuję TypeError: nie można ustawić właściwość „C” z niezdefiniowane.

Może nie rozumiem, jak działają klasy w javascript.

+0

Jeśli nie można odczytać właściwość 'C' z' undefined', oznacza to, że cokolwiek ma mieć właściwości 'C' ** **' undefined' jest. Co oznacza, że ​​w twoim przypadku 'opcje' są niezdefiniowane. –

+0

Ale tego właśnie chcę. Jeśli nie przekażę wartości c w opcjach, tworzy nowy obiekt z wartością domyślną dla c –

+1

Twój kod jest OK, możesz go skopiować/wkleić [tutaj] (https://babeljs.io/repl/) i zobaczyć. – Engineer

Odpowiedz

9

Jeśli masz zamiar użyć ES6, dlaczego nie korzystać ze wszystkich ES6, czyli domyślne wartości parametrów i rozpad przypisania

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/

edit: też testowane i potwierdzone do uruchomienia na https://babeljs.io/repl/

+0

Nice. Nie wiedział o zadaniu destrukturyzacji. To jest rozwiązanie, którego szukałem. –

+0

To nie jest zadanie destrukturyzacji. Przy okazji, prawdopodobnie nie chcesz dwóch różnych wartości domyślnych. – Bergi

+2

@Bergi co to jest? –

3

Proponuję następujące:

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

To działa. Dzięki –

+0

@LeonardoAlves przy założeniu, że używasz aktualnej wersji Babel, powinna przekonwertować 'const' na' var' poprawnie w transpiled code. –

+0

Dzięki temu wskazać. Przyjrzy się. –

1

TypeError: Cannot set property 'c' of undefined.

Oznacza to options jest niezdefiniowany.

Upewnij się, że obiekt options istnieje, najpierw:

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

Albo, ładne i krótkie:

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'; 
+0

Czy ten błąd nie oznaczałby raczej, że "ten" jest niezdefiniowany? 'options.c' nigdy nie jest * ustawione *. – Bergi

0

właśnie zadał podobne pytanie i znaleźć na to pytanie po tym, jak wpadł na rozwiązanie, więc pomyślałem, że to tutaj również.

Moje pytanie dotyczyło ES6 i dekonstrukcji do ustawiania parametrów domyślnych dla klasy. Wygląda na to, że specyfikacja nie pozwala na bezpośrednią dekonstrukcję argumentów, chyba że zrobisz coś podobnego do tego, co zrobił @Jaromanda X.

Chciałem coś krótsze i czystsze, a zakończył się stosując następujący wzór:

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

Wszystko robimy tutaj jest dekonstrukcji argument opcji, a my obsłużyć niezdefiniowany przypadek użycia z potrójnym.

3

Object.assign działa na mnie jak dobrze

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

To zadziałało dla mnie świetnie. Dzięki za wysłanie tego małego klejnotu. –

0

Shorter i czystsza wersja na podstawie 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);

Z przechodzącej obiektu.

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