Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Как переопределить undefine которое возвращает несуществующее свойство? (https://javascript.ru/forum/misc/63458-kak-pereopredelit-undefine-kotoroe-vozvrashhaet-nesushhestvuyushhee-svojjstvo.html)

Shitbox2 08.06.2016 18:38

Как переопределить undefine которое возвращает несуществующее свойство?
 
Нужно создать объект, который будет возвращать, например, null вместо undefined при запросе несуществующего свойства.

destus 08.06.2016 19:00

let obj = {
	"a": 1,
	"b": 2
};

obj = new Proxy(obj, {
  get(target, prop) {
  return prop in target ? target[prop] : null
  }
})

alert( obj['a'] ); //1
alert( obj['qqqqq'] ); //null

ruslan_mart 08.06.2016 19:44

destus, это конечно всё хорошо, но поддержка плохая.

Shitbox2, а чем undefined не вариант?

nerv_ 08.06.2016 23:08

class Foo {
  constructor() {
    this.__x = 1;
    this.__y = 2;
  }
  get (key) {
    let k = `__${key}`;
    return k in this ? this[k] : null;
  }
  set (key, value) {
    let k = `__${key}`;
    this[k] = value;
  }
}

let object = new Foo();
alert(object.get('x'));
alert(object.get('z'));

Shitbox2 09.06.2016 09:36

Спасибо! Попробую!

Эта штука должна в валидаторах выводить сообщение по-умолчанию. Если валидатор вернет undefined это будет считаться успешной валидацией. Можно, конечно, в каждом валидаторе писать что-то типа
return options.message || defaults.message
но как-то слишком много копипаста)

nerv_ 09.06.2016 09:52

Shitbox2, тогда еще проще
function modifier(any) {
	return any === undefined ? null : any;
}

function isValid(any) {
	return modifier(any);
}

alert(isValid(0));
alert(isValid(1));
alert(isValid(undefined));


Я бы так сделал
function isUndefined(any) {
	return any === undefined;
}

function Validator({message}) {
	this.message = isUndefined(message) ? null : message;
}

let validator1 = new Validator({message:'test'});
let validator2 = new Validator({message: undefined});
let validator3 = new Validator({});

alert(validator1.message);
alert(validator2.message);
alert(validator3.message);

Shitbox2 09.06.2016 10:16

destus, Proxy действительно даже Babel не поддерживает(

nerv_, зачем такие сложности?
function Foo() {}

Foo.prototype.get = function(key) {
    return key in this ? this[key] : null;
};

const object = Object.assign(new Foo(), {x: 1, y: 2});

alert(object.get('x'));
alert(object.get('z'));

Shitbox2 09.06.2016 10:24

nerv_, не увидел предыдущий ответ сразу) Так не получится. Валидатор имеет примерно такой код:
if (isValid(value)) {
   return undefined/null/0/''
} else {
   return options[поле, где хранится сообщение об ошибке]
}

Т.е. у нас единственная зацепка это то, что сообщение является полем в options, а объект options (как и обертку над валидатором) мы создаем сами (пользователь лишь записывает в него свойства)

ruslan_mart 09.06.2016 11:17

Shitbox2, автоматизировать не получится, только вручную.

function modifier(value) {
    return value === void 0 ? null : value;
}



alert(modifier(1));
alert(modifier(false));
alert(modifier(undefined));


Ну или юзать Proxy/Object.observe, но у них поддержка плохая.

Shitbox2 09.06.2016 11:41

Раз не получается просто, сделал примерчик. Может быть еще какие-то способы есть?
//Пользовательский валидатор. Мы не можем его контролировать и название поля с сообщением мы не знаем
function isMax(value, options) {
    if (value > options.max) {
        return options.maxMessage;
        // return options.maxMessageXXX //поле с сообщением может не существовать
        // return 'Плохое число' //вернул свое сообщение
    }
}

//Наша обертка. Здесь мы можем подменить options
function validateMax(value, options) {
    var result = isMax(value, options);

    if (!result) {
        return 'Валидно'
    }
    return result;
}

alert(validateMax(3, {max: 2, maxMessage: 'Слишком большое'}));
alert(validateMax(3, {max: 2})); //Неверное поведение
alert(validateMax(1, {max: 2, maxMessage: 'Слишком большое'}));


Часовой пояс GMT +3, время: 21:04.