Jak uzyskać dostęp do metody Object.prototype w następującej logice?

91

Używam następującej logiki, aby uzyskać ciąg i18n podanego klucza.

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

W moim projekcie używam ESLint. Otrzymuję następujący błąd:

Nie uzyskuj dostępu do metody Object.prototype „hasOwnProperty” z obiektu docelowego. Jest to błąd typu „ brak wbudowanych prototypów ”.

Jak zmienić kod, aby rozwiązać ten błąd? Nie chcę wyłączać tej reguły.

booYah
źródło
9
Powinieneś prawdopodobnie przeczytać dokumentację. Istnieją przykłady poprawnego kodu ~ eslint.org/docs/rules/no-prototype-builtins
Phil
1
Sugerujesz użycie Object.hasOwnProperty(entries,key)?
pasja
Kod działa poprawnie. To jest błąd lintingu. Chcę tylko zmodyfikować składnię, aby reguła lintingu była spełniona.
booYah
1
@passion To będzie ciągnąć entries, ignorować keyi sprawdzać, czy Objectma właściwość z tym ciągiem.
Oriol

Odpowiedzi:

149

Możesz uzyskać do niego dostęp przez Object.prototype:

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

To powinno być bezpieczniejsze, ponieważ

  • Nie wszystkie obiekty dziedziczą po Object.prototype
  • Nawet w przypadku obiektów, które dziedziczą Object.prototype, hasOwnPropertymetoda może być zasłonięta czymś innym.

Oczywiście powyższy kod zakłada, że

  • Globalność Objectnie została zastąpiona cieniem ani przedefiniowana
  • Natywny Object.prototype.hasOwnPropertynie został przedefiniowany
  • Żadna callwłasna nieruchomość nie została dodana doObject.prototype.hasOwnProperty
  • Natywny Function.prototype.callnie został przedefiniowany

Jeśli któryś z nich nie działa, próbując kodować w bezpieczniejszy sposób, mogłeś złamać kod!

Innym podejściem, które nie musi callbyć

!!Object.getOwnPropertyDescriptor(obj, prop);
Oriol
źródło
14

W Twoim konkretnym przypadku sprawdzą się następujące przykłady:

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

LUB

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

LUB

if({}.propertyIsEnumerable.call(entries, "key")) {
    //rest of the code
}
Zameer Ansari
źródło
11

Wygląda na to, że to również zadziała:

key in entries

ponieważ to zwróci wartość logiczną o tym, czy klucz istnieje wewnątrz obiektu?

Mike Mathew
źródło
3
hasOwnPropertysprawdza, czy ciąg lub symbol jest własną własnością. key in entriessprawdza, czy jest to własność, czy dziedziczenie.
Oriol
0

Mam nadzieję, że prawdopodobnie nie zostanę za to odrzucony, prawdopodobnie tak, ale!

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

Jak dotąd nigdy nie złamał mojego kodu Ale nie jestem pewien, czy tak jest we wszystkich przeglądarkach internetowych ...

(Ponadto, jeśli Canadarmjest niezdefiniowany, wydaje się, że kod wydaje się, return entries[key];nawet jeśli klucza nie ma we wpisach ...)

Albert James Teddy
źródło
1
Problem polega na tym, że jeśli ama prototyp, który MA c, to się wydarzy. Js wejdzie w górę łańcucha prototypów
Bernardo Dal Corno