Wie greife ich in der folgenden Logik auf die Object.prototype-Methode zu?

92

Ich verwende die folgende Logik, um die i18n-Zeichenfolge des angegebenen Schlüssels abzurufen.

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

Ich verwende ESLint in meinem Projekt. Ich erhalte die folgende Fehlermeldung:

Greifen Sie nicht vom Zielobjekt auf die Object.prototype-Methode 'hasOwnProperty' zu. Es handelt sich um einen Fehler ohne Prototyp .

Wie ändere ich meinen Code, um diesen Fehler zu beheben? Ich möchte diese Regel nicht deaktivieren.

booYah
quelle
9
Sie sollten wahrscheinlich die Dokumente lesen. Es gibt Beispiele für korrekten Code ~ eslint.org/docs/rules/no-prototype-builtins
Phil
1
Schlagen Sie vor, zu verwenden Object.hasOwnProperty(entries,key)?
Leidenschaft
Der Code funktioniert gut. Dies ist ein Flusenfehler. Ich möchte nur die Syntax so ändern, dass die Flusenregel erfüllt ist.
BooYah
1
@passion Hiermit wird stringifiziert entries, ignoriert keyund überprüft, ob Objecteine Eigenschaft mit dieser Zeichenfolge vorhanden ist.
Oriol

Antworten:

150

Sie können darauf zugreifen über Object.prototype:

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

Das sollte sicherer sein, weil

  • Nicht alle Objekte erben von Object.prototype
  • Selbst für Objekte, die von erben Object.prototype, könnte die hasOwnPropertyMethode durch etwas anderes beschattet werden.

Der obige Code geht natürlich davon aus

  • Das Globale Objectwurde nicht beschattet oder neu definiert
  • Der Eingeborene Object.prototype.hasOwnPropertywurde nicht neu definiert
  • Es wurde kein calleigenes Eigentum hinzugefügtObject.prototype.hasOwnProperty
  • Der Eingeborene Function.prototype.callwurde nicht neu definiert

Wenn dies nicht zutrifft und Sie versuchen, sicherer zu codieren, haben Sie möglicherweise Ihren Code beschädigt!

Ein anderer Ansatz, der nicht benötigt wird, callwäre

!!Object.getOwnPropertyDescriptor(obj, prop);
Oriol
quelle
14

Für Ihren speziellen Fall gelten die folgenden Beispiele:

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

ODER

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

ODER

if({}.propertyIsEnumerable.call(entries, "key")) {
    //rest of the code
}
Zameer Ansari
quelle
11

Es scheint, dass dies auch funktionieren würde:

key in entries

da dies einen Booleschen Wert zurückgibt, ob der Schlüssel im Objekt vorhanden ist oder nicht?

Mike Mathew
quelle
3
hasOwnPropertyprüft, ob eine Zeichenfolge oder ein Symbol eine eigene Eigenschaft ist. key in entriesprüft, ob es sich um eine eigene oder eine geerbte handelt.
Oriol
0

Ich hoffe, ich werde dafür nicht herabgestimmt, wahrscheinlich auch, aber!

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

Hat, soweit ich meinen Code nie gebrochen habe 😬 Aber ich bin mir nicht sicher, ob dies in allen Webbrowsern der Fall ist ...

(Auch wenn Canadarmundefiniert ist, scheint Ihr Code return entries[key];auch dann, wenn der Schlüssel nicht in den Einträgen enthalten ist ...)

Albert James Teddy
quelle
1
Das Problem ist, dass wenn aein Prototyp vorhanden ist, der dies tut c, dies passieren wird. Js wird die Prototypenkette hochfahren
Bernardo Dal Corno