web-dev-qa-db-ja.com

次のロジックでObject.prototypeメソッドにアクセスするにはどうすればよいですか?

次のロジックを使用して、指定されたキーの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を使用しています。次のエラーが表示されます。

ターゲットオブジェクトからObject.prototypeメソッド 'hasOwnProperty'にアクセスしないでください。これは「no-prototype-builtins」エラーです。

このエラーを解決するためにコードを変更するにはどうすればよいですか?このルールを無効にしたくありません。

32
booYah

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);
57
Oriol

これもうまくいくようです:

key in entries

キーがオブジェクト内に存在するかどうかについてブール値を返すので?

5
Mike Mathew

特定のケースでは、次の例が機能します。

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

OR

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

OR

if({}.propertyIsEnumerable.call(entries, "key")) {
    //rest of the code
}
2
student