Как получить доступ к методу Object.prototype в следующей логике?

91

Я использую следующую логику, чтобы получить строку i18n данного ключа.

export function i18n(key) {
  if (entries.hasOwnProperty(key)) {
    return entries[key];
  } else if (typeof (Canadarm) !== 'undefined') {
    try {
      throw Error();
    } catch (e) {
      Canadarm.error(entries['dataBuildI18nString'] + key, e);
    }
  }
  return entries[key];
}

Я использую ESLint в своем проекте. Я получаю следующую ошибку:

Не обращайтесь к методу hasOwnProperty Object.prototype из целевого объекта. Это ошибка « нет встроенных прототипов ».

Как мне изменить свой код, чтобы устранить эту ошибку? Я не хочу отключать это правило.

буYah
источник
9
Вам, вероятно, следует прочитать документацию. Есть примеры правильного кода ~ eslint.org/docs/rules/no-prototype-builtins
Phil
1
Предлагаете использовать Object.hasOwnProperty(entries,key)?
страсть
Код работает нормально. Это ошибка линтинга. Я просто хочу изменить синтаксис, чтобы выполнялось правило линтинга.
booYah 02
1
@passion Это будет преобразовывать entries, игнорировать keyи проверять, Objectесть ли свойство с этой строкой.
Oriol

Ответы:

149

Вы можете получить к нему доступ через Object.prototype:

Object.prototype.hasOwnProperty.call(obj, prop);

Это должно быть безопаснее, потому что

  • Не все объекты наследуются от Object.prototype
  • Даже для объектов, являющихся наследниками Object.prototype, hasOwnPropertyметод может быть затенен чем-то другим.

Конечно, приведенный выше код предполагает, что

  • Глобальное Objectне было затенено или переопределено
  • Родное Object.prototype.hasOwnPropertyне было переопределено
  • Никакой callсобственной собственности не добавленоObject.prototype.hasOwnProperty
  • Родное Function.prototype.callне было переопределено

Если что-то из этого не выполняется, пытаясь кодировать более безопасным способом, вы могли бы сломать свой код!

Другой подход, который не нужен, callбыл бы

!!Object.getOwnPropertyDescriptor(obj, prop);
Ориол
источник
14

Для вашего конкретного случая подойдут следующие примеры:

if(Object.prototype.hasOwnProperty.call(entries, "key")) {
    //rest of the code
}

ИЛИ

if(Object.prototype.isPrototypeOf.call(entries, key)) {
    //rest of the code
}

ИЛИ

if({}.propertyIsEnumerable.call(entries, "key")) {
    //rest of the code
}
Замир Ансари
источник
11

Похоже, это тоже сработает:

key in entries

так как это вернет логическое значение о том, существует ли ключ внутри объекта?

Майк Мэтью
источник
3
hasOwnPropertyпроверяет, является ли строка или символ собственным свойством. key in entriesпроверяет, является ли он собственным или унаследованным.
Oriol
0

Я надеюсь, что меня не проголосуют за это, возможно, получится, но!

var a = {b: "I'm here"}
if (a["b"]) { console.log(a["b"]) }
if (a["c"]) { console.log("Never going to happen") }

До сих пор не нарушал мой код 😬 Но я не уверен, так ли это во всех веб-браузерах ...

(Кроме того, если Canadarmне определено, ваш код кажется, return entries[key];даже если ключ отсутствует в записях ...)

Альберт Джеймс Тедди
источник
1
Проблема в том, что если aесть прототип, который ДЕЙСТВИТЕЛЬНО есть c, это произойдет. Js поднимется по цепочке прототипов
Бернардо Дал Корно