ES6 Классы Значение по умолчанию
Можно ли создать класс 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' из undefined.
Возможно, я не понимаю, как работают классы в javascript.
Ответы
Ответ 1
Если вы собираетесь использовать ES6, почему бы не использовать все ES6, то есть значения по умолчанию для параметров и назначение destructuring
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: также проверено и подтверждено для запуска на https://babeljs.io/repl/
Ответ 2
Object.assign работает для меня, а также
class RenderProperties {
constructor(options = {}){
Object.assign(this, {
fill : false,
fillStyle : 'rgba(0, 255, 0, 0.5)',
lineWidth : 1,
strokeStyle : '#00FF00'
}, options);
}
}
Ответ 3
Я бы предложил следующее:
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'});
Ответ 4
TypeError: Невозможно установить свойство 'c' из undefined.
Это означает, что options
- undefined.
Убедитесь, что объект 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
Я просто задал аналогичный вопрос и нашел этот вопрос после того, как придумал решение, поэтому я подумал, что я тоже опубликую его здесь.
Мой вопрос касался 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
Скомпилированный Babel ES5
Все, что мы делаем здесь, это деконструкция аргумента options, и мы обрабатываем прецедент использования undefined с тройным.
Ответ 6
Более короткая и более чистая версия на основе Параметры по умолчанию из веб-документов MDN.
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);
Ответ 7
Я бы просто добавил это к прототипу. Классы 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
Так что я читал ответы на этот вопрос, и я не нашел такой, которая бы легко работала с расширенными классами, поэтому я придумал это.
Сначала вы создаете функцию, которая проверяет, есть ли у объекта свойства другого объекта:
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
если нет параметров, проходящих через конструктор, ему присваивается значение по умолчанию, как это было задано заранее, я надеюсь, что помог!
class User {
constructor(fullName = "fooName", lastName, canAccess = false) {
this.fullName = fullName;
this.lastName = lastName;
this.canAccess = canAccess;
}
}