1872 Stimmen

Wie prüfe ich, ob ein Objekt eine bestimmte Eigenschaft in JavaScript hat?

Wie prüfe ich, ob ein Objekt eine bestimmte Eigenschaft in JavaScript hat?

Bedenken Sie:

x = {'key': 1};
if ( x.hasOwnProperty('key') ) {
    //Do this
}

Ist das der beste Weg?

32 Stimmen

Ich habe einen jsperf-Test mit den Antworten aller geschrieben, um zu sehen, wer am schnellsten ist: jsperf.com/wörterbuch-enthaelt-schluessel

0 Stimmen

('propertyName' in Object) ? 'Eigenschaft ist vorhanden' : 'Eigenschaft ist nicht vorhanden'

2 Stimmen

@styfle danke für den jsperf-Test. in y hasOwnProperty herausgekommen Weg für mich langsamer als die anderen (98 % langsamer). Ich bin nicht überrascht über hasOwnProperty langsamer zu sein, aber ich bin überrascht über in .

4voto

Kamil Kiełczewski Punkte 69048

Leistung

Heute 2020.12.17 führe ich Tests auf MacOs HighSierra 10.13.6 mit Chrome v87, Safari v13.1.2 und Firefox v83 für ausgewählte Lösungen durch.

Ergebnisse

Ich vergleiche nur die Lösungen A-F, da sie für alle im Ausschnitt im Abschnitt Details verwendeten Fälle gültige Ergebnisse liefern. Für alle Browser

  • Lösung basierend auf in (A) schnell oder am schnellsten ist
  • Lösung (E) ist am schnellsten für Chrome für große Objekte und am schnellsten für Firefox für kleine Arrays, wenn der Schlüssel nicht existiert
  • Lösung (F) ist am schnellsten (~ >10x als andere Lösungen) für kleine Arrays
  • Lösungen (D,E) sind recht schnell
  • Lösung auf Basis von Losash has (B) ist am langsamsten

enter image description here

Einzelheiten

Ich führe 4 Testfälle durch:

  • wenn das Objekt 10 Felder hat und der gesuchte Schlüssel vorhanden ist - können Sie es ausführen HIER
  • wenn das Objekt 10 Felder hat und der gesuchte Schlüssel nicht existiert, können Sie es ausführen HIER
  • wenn das Objekt 10000 Felder hat und der gesuchte Schlüssel vorhanden ist - können Sie es ausführen HIER
  • wenn das Objekt 10000 Felder hat und der gesuchte Schlüssel vorhanden ist - können Sie es ausführen HIER

Der folgende Ausschnitt zeigt die Unterschiede zwischen den Lösungen A B C D E F G H I J K

// SO https://stackoverflow.com/q/135448/860099

// src: https://stackoverflow.com/a/14664748/860099
function A(x) {
  return 'key' in x
}

// src: https://stackoverflow.com/a/11315692/860099
function B(x) {
  return _.has(x, 'key')
}

// src: https://stackoverflow.com/a/40266120/860099
function C(x) {
  return Reflect.has( x, 'key')
}

// src: https://stackoverflow.com/q/135448/860099
function D(x) {
  return x.hasOwnProperty('key')
}

// src: https://stackoverflow.com/a/11315692/860099
function E(x) {
  return Object.prototype.hasOwnProperty.call(x, 'key')
}

// src: https://stackoverflow.com/a/136411/860099
function F(x) {
  function hasOwnProperty(obj, prop) {
      var proto = obj.__proto__ || obj.constructor.prototype;
      return (prop in obj) &&
          (!(prop in proto) || proto[prop] !== obj[prop]);
  }
  return hasOwnProperty(x,'key')
}

// src: https://stackoverflow.com/a/135568/860099
function G(x) {
  return typeof(x.key) !== 'undefined'
}

// src: https://stackoverflow.com/a/22740939/860099
function H(x) {
  return x.key !== undefined
}

// src: https://stackoverflow.com/a/38332171/860099
function I(x) {
  return !!x.key
}

// src: https://stackoverflow.com/a/41184688/860099
function J(x) {
  return !!x['key']
}

// src: https://stackoverflow.com/a/54196605/860099
function K(x) {
  return Boolean(x.key)
}

// --------------------
// TEST
// --------------------

let x1 = {'key': 1};
let x2 = {'key': "1"};
let x3 = {'key': true};
let x4 = {'key': []};
let x5 = {'key': {}};
let x6 = {'key': ()=>{}};
let x7 = {'key': ''};
let x8 = {'key': 0};
let x9 = {'key': false};
let x10= {'key': undefined};
let x11= {'nokey': 1};

let b= x=> x ? 1:0;

console.log('  1 2 3 4 5 6 7 8 9 10 11');

[A,B,C,D,E,F,G,H,I,J,K ].map(f=> {  
  console.log(
    `${f.name} ${b(f(x1))} ${b(f(x2))} ${b(f(x3))} ${b(f(x4))} ${b(f(x5))} ${b(f(x6))} ${b(f(x7))} ${b(f(x8))} ${b(f(x9))} ${b(f(x10))}  ${b(f(x11))} `
  )})

console.log('\nLegend: Columns (cases)');
console.log('1.  key = 1 ');
console.log('2.  key = "1" ');
console.log('3.  key = true ');
console.log('4.  key = [] ');
console.log('5.  key = {} ');
console.log('6.  key = ()=>{} ');
console.log('7.  key = "" ');
console.log('8.  key = 0 ');
console.log('9.  key = false ');
console.log('10. key = undefined ');
console.log('11. no-key ');

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"> </script>

This shippet only presents functions used in performance tests - it not perform tests itself!

Und hier sind Beispielergebnisse für Chrom

enter image description here

3voto

arkod Punkte 1665

Hier ist eine weitere Option für einen speziellen Fall:)

Wenn Sie auf ein Element eines Objekts testen wollen und wissen wollen, ob es auf etwas anderes als:

  • ''
  • falsch
  • null
  • undefiniert
  • 0 ...

dann können Sie verwenden:

var foo = {};
foo.bar = "Yes, this is a proper value!";
if (!!foo.bar) {
    // member is set, do something
}

0 Stimmen

Kompakt und praktisch

1 Stimmen

Ein Linter wird das nicht mögen: eslint.org/docs/rules/no-extra-boolean-cast

3voto

bristweb Punkte 480

einige einfachere und kürzere Optionen je nach dem spezifischen Anwendungsfall:

  1. um zu prüfen, ob die Eigenschaft existiert, unabhängig vom Wert, verwenden Sie die im Operator ("a" in b)
  2. um einen Eigenschaftswert einer Variablen zu prüfen, verwenden Sie Klammerschreibweise (obj[v])
  3. um einen Eigenschaftswert als wahr zu überprüfen, verwenden Sie optional Verkettung (?.)
  4. um einen Eigenschaftswert boolesch zu prüfen, verwenden Sie Doppel-Nicht / Peng-Peng / (!!)
  5. um einen Standardwert für die Prüfung auf null / undefiniert festzulegen, verwenden Sie nullischer Koaleszenzoperator (??)
  6. um einen Standardwert für die Falschwertprüfung festzulegen, verwenden Sie Kurzschluss logischer OR-Operator (||)

Führen Sie das Codeschnipsel aus, um die Ergebnisse zu sehen:

let obj1 = {prop:undefined};
console.log(1,"prop" in obj1);
console.log(1,obj1?.prop);

let obj2 = undefined;
//console.log(2,"prop" in obj2); would throw because obj2 undefined
console.log(2,"prop" in (obj2 ?? {}))
console.log(2,obj2?.prop);

let obj3 = {prop:false};
console.log(3,"prop" in obj3);
console.log(3,!!obj3?.prop);

let obj4 = {prop:null};
let look = "prop"
console.log(4,"prop" in obj4);
console.log(4,obj4?.[look]);

let obj5 = {prop:true};
console.log(5,"prop" in obj5);
console.log(5,obj5?.prop === true);

let obj6 = {otherProp:true};
look = "otherProp"
console.log(6,"prop" in obj6);
console.log(6,obj6.look); //should have used bracket notation

let obj7 = {prop:""};
console.log(7,"prop" in obj7);
console.log(7,obj7?.prop || "empty"); 

Ich sehe nur sehr wenige Fälle, in denen hasOwn ordnungsgemäß verwendet wird, insbesondere angesichts seiner Erbschaftsangelegenheiten

2voto

Harm Punkte 777

Eine ECMAScript 6-Lösung mit Reflection. Erstellen Sie einen Wrapper wie:

/**
Gets an argument from array or object.
The possible outcome:
- If the key exists the value is returned.
- If no key exists the default value is returned.
- If no default value is specified an empty string is returned.
@param obj    The object or array to be searched.
@param key    The name of the property or key.
@param defVal Optional default version of the command-line parameter [default ""]
@return The default value in case of an error else the found parameter.
*/
function getSafeReflectArg( obj, key, defVal) {
   "use strict";
   var retVal = (typeof defVal === 'undefined' ? "" : defVal);
   if ( Reflect.has( obj, key) ) {
       return Reflect.get( obj, key);
   }
   return retVal;
}  // getSafeReflectArg

0 Stimmen

Ist dies der beste Weg, um es zu tun, wenn Sie >= ES6 Ziel sind?

1 Stimmen

Imho ist es die kürzeste und einfachste Antwort, aber vielleicht nicht die schnellste bei der Codeausführung. Aber Geschwindigkeit ist nicht (mehr) ein Thema.

0 Stimmen

Warum Post die gleiche Antwort zweimal? Du könntest doch einfach den bestehenden Beitrag hochstufen...?

2voto

vikram jeet singh Punkte 3226

Es gibt eine Methode, "hasOwnProperty", die auf einem Objekt existiert, aber es wird nicht empfohlen, diese Methode direkt aufzurufen, weil es manchmal sein könnte, dass das Objekt null ist oder eine Eigenschaft auf dem Objekt existiert wie: { hasOwnProperty: false }

Ein besserer Weg wäre also:

// Good
var obj = {"bar": "here bar desc"}
console.log(Object.prototype.hasOwnProperty.call(obj, "bar"));

// Best
const has = Object.prototype.hasOwnProperty; // Cache the lookup once, in module scope.
console.log(has.call(obj, "bar"));

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X