Javascript: проверьте, может ли что-то иметь свойства, добавленные к нему - PullRequest
4 голосов
/ 16 июня 2019

РЕДАКТИРОВАТЬ: стало понятнее, что нужно определить, могу ли я добавить свойства к значению, а не если значение может иметь свои собственные свойства.

Есть ли способ проверить, возможно ли добавить свойства к value?

Например, если у меня есть этот код:

function test( value ) {
    // return true if it is possible to add properties to value
}

Помимо фактического добавления свойства value для проверки, существует ли надежный способ сделать вывод, что value - это то, к чему можно добавить свойства?

Например, я знаю, что object может иметь свойства, а undefined не может, но я не заинтересован в создании списка известных вещей, которых может не хватить в будущем. Достаточно ли что-то вроде instanceof object?

Ответы [ 3 ]

3 голосов
/ 16 июня 2019

Список значений, у которых нет свойств, довольно короткий: undefined и null. Тестирование для них должно быть простым (value == null).

Обратите внимание, что все другие примитивы могут иметь свойства (через бокс), но поскольку объект в штучной упаковке теряется немедленно, нет смысла добавлять свойства к ним:

 1..test = 1;
 "test".test = 1;
 Infinity.test = 1;
 NaN.test = 1;
 true.test = 1;
 Symbol().test = 1;
 1n.test = 1;

Чтобы проверить наличие не примитивов, можно использовать typeof value === "object", но, поскольку null также является объектом (очень особенным, фактически он считается примитивом, но typeof об этом говорит), вы должны явно проверьте value !== null.

Хотя вы обычно можете добавлять свойства к объектам, они могут быть заморожены, тогда добавление свойств бесполезно, то же самое относится и к прокси.

  const obj = {};
  Object.freeze(obj);
  obj.test = 1;
  console.log(obj.test);

И поскольку Прокси не могут быть обнаружены, нет способа узнать, можно ли добавить свойство или нет.

0 голосов
/ 16 июня 2019

Как отметил Джонас Уилмс:

Плохой вариант использования. Вы просто пишете свою следующую головную боль:)

Мне нужно провести рефакторинг своего кода, чтобы ему не нужно было прыгать через обручи.

0 голосов
/ 16 июня 2019

Простая идея (хотя она и не решает полностью проблему согласно Jonas Wilms answer) может быть:

function test(value) {
    try {
        if (value.p === undefined) {
            value.p = 10;
            if (value.p === undefined) {
                return false;
            }
            delete value.p;
        }
    } catch(e) {
        return false;
    }
    return true;
}

console.log('null: ' + test(null));
console.log('undefined: ' + test(undefined));
console.log('number: ' + test(10));
console.log('object: ' + test({a:10}));
var  obj = { get p() { return false; }, set p(v) {} };
console.log('object with property name confict: ' + test(obj));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...