JavaScript 객체에 키가 있는지 확인 중입니까?


2965

JavaScript 객체 또는 배열에 특정 키가 있는지 어떻게 확인합니까?

키가 존재하지 않고 액세스하려고하면 false를 반환합니까? 아니면 오류를 던져?


2
JavaScript의 모든 것 (거의 모든 것)은 객체이거나 하나로 캐스팅 할 수 있습니다. 여기에서 @PatrickM이 지적한 것처럼 의사 연관 배열이 생성됩니다.
Andrew Larsson

이 벤치 마크 jsben.ch/#/WqlIl 은이 검사를 수행하는 가장 일반적인 방법에 대한 개요를 제공합니다.
EscapeNetscape

빠른 해결 방법, 일반적으로 나는 property.key = property.key || 'some default value'그 키가 어떤 가치로 존재하기를 원할 경우를 대비하여
간다

답변:


4115

정의되지 않은 검사는 키가 있는지 여부를 테스트하는 정확한 방법이 아닙니다. 키가 있지만 실제로 값이 있으면 undefined어떻게됩니까?

var obj = { key: undefined };
obj["key"] !== undefined // false, but the key exists!

대신 in연산자 를 사용해야합니다 .

"key" in obj // true, regardless of the actual value

키가 존재하지 않는지 확인하려면 괄호를 사용해야합니다.

!("key" in obj) // true if "key" doesn't exist in object
!"key" in obj   // ERROR!  Equivalent to "false in obj"

또는 상속 된 속성이 아닌 객체 인스턴스의 속성을 특별히 테스트하려면 hasOwnProperty다음을 사용하십시오 .

obj.hasOwnProperty("key") // true

있는 방법 사이의 성능 비교를 들어 in, hasOwnProperty키가 undefined,이 볼 벤치 마크


83
수동으로 정의 된 값이 undefined 인 속성을 갖는 것은 전혀 의미가 없습니다. 정말 옥시 모 론일 것입니다.
joebert

259
속성을 의도적으로 정의되지 않은 유스 케이스가 있다고 확신합니다.
Ates Goral

168
유효한 사용 사례 : Gecko 1.9.1 [Firefox 3.5]에는 window.onhashchange 속성이 없습니다. Gecko 1.9.2 [Firefox 3.6]은이 속성이 정의되지 않은 것으로 설정되어 있습니다 (해시가 변경 될 때까지). 해시 기록 또는 브라우저 버전을 감지하려면 window.hasOwnProperty ( "onhashchange");
SamGoody

7
null == 존재하지 않는 PHP에도 비슷한 문제가 있습니다. stackoverflow.com/q/418066/372654 불행히도 null도 사용됩니다.
Halil Özgür

80
@joebert 무언가가 말도 안된다고해서 프로덕션 코드에서 발견되지 않는다는 의미는 아닙니다. 무의미한 일을하는 많은 라이브러리가 있습니다.
Crashworks

298

빠른 답변

JavaScript 객체 또는 배열에 특정 키가 있는지 어떻게 확인합니까? 키가 존재하지 않고 액세스하려고하면 false를 반환합니까? 아니면 오류를 던져?

(연관) 배열 스타일 또는 객체 스타일을 사용하여 누락 된 속성에 직접 액세스하면 정의되지 않은 값 이 반환됩니다 상수 됩니다.

느린하고 신뢰할 수 있는 연산자와 hasOwnProperty 방법

사람들이 이미 여기에서 언급했듯이 "정의되지 않은"상수와 연관된 속성을 가진 개체를 가질 수 있습니다.

 var bizzareObj = {valid_key:  undefined};

이 경우에는 hasOwnProperty 키가 정말이 있는지 알고 연산자를. 그러나 가격은 얼마입니까?

그래서 나는 당신에게 ...

연산자와 hasOwnProperty 는 Javascript에서 속성 설명자 메커니즘을 사용하는 "메소드"입니다 (Java에서 Java 리플렉션과 유사).

http://www.ecma-international.org/ecma-262/5.1/#sec-8.10

속성 설명자 유형은 명명 된 속성 속성의 조작 및 수정을 설명하는 데 사용됩니다. 속성 설명자 유형의 값은 각 필드의 이름이 속성 이름이고 해당 값이 8.6.1에 지정된 해당 속성 값인 명명 된 필드로 구성된 레코드입니다. 또한 모든 필드가 있거나 없을 수 있습니다.

반면에 객체 메소드 또는 키를 호출하면 Javascript [[Get]] 메커니즘이 사용됩니다. 훨씬 빠릅니다!

기준

http://jsperf.com/checking-if-a-key-exists-in-a-javascript-array

JS의 키 액세스 비교.

사용 연산자
var result = "Impression" in array;

결과는

12,931,832 ±0.21% ops/sec      92% slower 
hasOwnProperty 사용
var result = array.hasOwnProperty("Impression")

결과는

16,021,758 ±0.45% ops/sec     91% slower
요소에 직접 액세스 (브래킷 스타일)
var result = array["Impression"] === undefined

결과는

168,270,439 ±0.13 ops/sec     0.02% slower 
요소에 직접 액세스 (객체 스타일)
var result = array.Impression  === undefined;

결과는

168,303,172 ±0.20%     fastest

편집 : 속성에 undefined값 을 할당하는 이유는 무엇입니까 ?

그 질문은 나를 당혹스럽게한다. Javascript에는 다음 null과 같은 문제를 피하기 위해 부재 객체에 대한 참조가 두 개 이상 undefined있습니다.

null는 객체 값의 의도적 인 부재 또는 단기적으로 확인 된 값 결여를 나타내는 기본 값입니다 . 한편, undefined알 수없는 값 (정의되지 않음)입니다. 적절한 값으로 나중에 사용할 특성이있는 경우 초기 순간에 특성 에 값이없는 것으로 확인 되므로 null대신 참조를 사용 하십시오 .undefined

비교:

var a = {1: null}; 
console.log(a[1] === undefined); // output: false. I know the value at position 1 of a[] is absent and this was by design, i.e.:  the value is defined. 
console.log(a[0] === undefined); // output: true. I cannot say anything about a[0] value. In this case, the key 0 was not in a[].

권하다

undefined값이있는 물체는 피하십시오 . 가능할 때마다 직접 확인하고 null속성 값을 초기화 하는 데 사용하십시오 . 그렇지 않으면 느린 in연산자 나 hasOwnProperty()방법을 사용하십시오 .

편집 : 2018 년 12 월 4 일-더 이상 관련이 없습니다.

사람들이 언급했듯이, 최신 버전의 Javascript 엔진 (firefox 제외)은 액세스 속성에 대한 접근 방식을 변경했습니다. 현재 구현은이 특별한 경우에 이전 구현보다 느리지 만 액세스 키와 객체의 차이는 무시할 수 있습니다.


1
IE8 +와 같이 일반적으로 사용되는 모든 브라우저에서 이러한 방법을 모두 사용할 수 있습니까?
Justin

11
벤치마킹 +1 감사합니다. 이것이 바로 내가 찾던 정보입니다. 키가 undefined 값을 포함하도록 지정하거나 기대하지 않는 코드 작성에 대한 확실한 주장 .
TJ Compton

Underscore.js의 has () 비교 방법이 궁금해서 jsperf ( version 11 )에 추가했습니다 . in 및 hasOwnProperty ()와 함께 느린 그룹에 속합니다.
mpoisot

3
내가 해시 값으로 정의되지 않은 설정합니다 이유 중 하나는 실제로 해시에서 해당 속성의 키를 삭제하고 싶었지만이다 delete hash[key]입니다 보다 훨씬 느립니다 hash[key] = undefined . 물론이 경우에는 in연산자 가 필요하지 않지만 "값을 정의되지 않은 상태로 설정하는 것을 항상 피해야합니다"라는 반례의 역할을합니다.
Alan Tam

1
@ HüseyinYağlı에서 언급했듯이 jsperf 링크 를 확인하면 이 답변이 처음 작성된 이후로 대부분의 브라우저에서 다른 방법간에 성능이 크게 변경되었습니다. Firefox는 배열이나 객체 메소드를 사용하여 여전히 큰 이점을 제공하는 몇 안되는 제품 중 하나이지만 다른 많은 브라우저의 경우 그 차이는 무시할 수 있습니다.
kevinmicke

144

반환 undefined됩니다.

var aa = {hello: "world"};
alert( aa["hello"] );      // popup box with "world"
alert( aa["goodbye"] );    // popup box with "undefined"

undefined특별한 상수 값입니다. 예를 들어

// note the three equal signs so that null won't be equal to undefined
if( aa["goodbye"] === undefined ) {
    // do something
}

이것은 아마도 누락 된 키를 확인하는 가장 좋은 방법입니다. 그러나 아래 주석에서 지적했듯이 이론적으로 실제 값을 원할 수도 있습니다 undefined. 나는 이것을 할 필요가 없었고 내가 왜 원했던 지 알 수없는 이유를 생각할 수는 없지만 완전성을 위해 in연산자를 사용할 수 있습니다.

// this works even if you have {"goodbye": undefined}
if( "goodbye" in aa ) {
    // do something
}

8
키가 있지만 값이 실제로 정의되지 않은 경우 어떻게합니까?
Ates Goral

13
undefined와 비교할 때 == 대신 ===를 사용해야합니다. 그렇지 않으면 null은 undefined와 같습니다.
Matthew Crumley

10
엘리의 답변이 완전히 정확하지는 않습니다. 어쨌든 (물론이 작업을 수행해서는 안 됨) undefined는 특별한 상수 값이 아닙니다. 실제로 예약 된 키워드가 아니므로 덮어 쓸 수 있습니다 (예 : that) var undefined = 42;. 정의되지 않은 소품을 테스트 할 때는 항상를 사용해야 ((typeof variable) === "undefined")합니다.
ssice

1
@ssice undefined쓰기 가능한 속성은 사양에 따라 아니다 ecma-international.org/ecma-262/5.1/#sec-15.1.1.3
therealrootuser

1
이전 버전의 JavaScript에서 'undefined'및 'NaN'은 다시 정의하거나 다른 값을 할당 할 수있는 변경 가능한 변수 였습니다. 이것은 나쁜 일이었습니다. ECMAScript 5에서 수정되었습니다.
jkdev


29
"key" in obj

배열 키와 매우 다른 객체 속성 값만 테스트 할 가능성이 있음


이 코드는 클래스 프로토 타입에 정의 된 키에도 적용됩니다. function A () {}; A.prototype.b = 2; var a = new A (); 그렇다면 'b'는 사실입니다. a.hasOwnProperty ( 'b')는 물론 거짓입니다.
Alexander

24

자바 스크립트 객체에 속성이 있는지 확인하는 세 가지 방법 :

  1. !! obj.theProperty
    값을 bool로 변환합니다. 'false'값을 제외한 모든 값에 대해 TRUE를 반환합니다.
  2. obj의 'theProperty'
    는 값에 관계없이 속성이 존재하면 true를 반환합니다 (비어 있음).
  3. obj.hasOwnProperty ( 'theProperty')
    프로토 타입 체인을 확인하지 않습니다. (모든 객체에는 'toString'메서드가 있으므로 1과 2는 true를 반환하고 3은 false를 반환 할 수 있습니다.)

참고:

http://book.mixu.net/node/ch5.html


!! obj.theProperty는 값이 정의되지 않으면 실패합니다. 예 :var a = {a : undefined, b : null}; !!a.a **will return false**
ARJUN

15

underscore.js 라이브러리를 사용하는 경우 객체 / 배열 작업이 간단 해집니다.

귀하의 경우 _.has 메소드를 사용할 수 있습니다. 예:

yourArray = {age: "10"}

_.has(yourArray, "age")

true를 반환

그러나,

_.has(yourArray, "invalidKey")

거짓을 돌려 준다


15

대답:

if ("key" in myObj)
{
    console.log("key exists!");
}
else
{
    console.log("key doesn't exist!");
}

설명:

in키가 객체에있는 경우 운영자는 확인합니다. 값이 정의되어 있지 않은지 확인한 경우 : if (myObj["key"] === 'undefined'), 값이 있는 객체에 키가있을 수 있으므로 문제가 발생할 수 있습니다 undefined.

따라서 먼저 in연산자를 사용하고 이미 알고있는 키 안에있는 값을 비교하는 것이 훨씬 좋습니다 .


12

여기에 매우 유용한 도우미 함수가 있습니다.

이것은 keyExists(key, search)객체 또는 배열 내에서 키를 쉽게 조회하는 데 사용할 수 있습니다!

찾으려는 키를 전달하고 찾으려는 obj (객체 또는 배열)를 검색하십시오.

function keyExists(key, search) {
        if (!search || (search.constructor !== Array && search.constructor !== Object)) {
            return false;
        }
        for (var i = 0; i < search.length; i++) {
            if (search[i] === key) {
                return true;
            }
        }
        return key in search;
    }

// How to use it:
// Searching for keys in Arrays
console.log(keyExists('apple', ['apple', 'banana', 'orange'])); // true
console.log(keyExists('fruit', ['apple', 'banana', 'orange'])); // false

// Searching for keys in Objects
console.log(keyExists('age', {'name': 'Bill', 'age': 29 })); // true
console.log(keyExists('title', {'name': 'Jason', 'age': 29 })); // false

꽤 안정적이었으며 브라우저 간 잘 작동합니다.


6
약간 혼란스러워 보입니다. 첫째로, Array를 검색 할 때이 메소드는 키가 아닌 값을 확인합니다 . 둘째, 내장 Array.indexOf메소드를 사용할 수 있는데 왜 이런 배열을 반복 합니까? (값을 찾고 있다면)
Nick F

9

바닐라 js

yourObjName.hasOwnProperty(key) : true ? false;

es2015에서 객체에 속성이 하나 이상 있는지 확인하려는 경우

Object.keys(yourObjName).length : true ? false

7

ES6 솔루션

Array#some및 사용 Object.keys. 돌아올 것이다 사실 지정된 키가 개체 나에있는 경우 거짓 그렇지 않은 경우.

var obj = {foo: 'one', bar: 'two'};
    
function isKeyInObject(obj, key) {
    var res = Object.keys(obj).some(v => v == key);
    console.log(res);
}

isKeyInObject(obj, 'foo');
isKeyInObject(obj, 'something');

한 줄 예.

console.log(Object.keys({foo: 'one', bar: 'two'}).some(v => v == 'foo'));


1
개체의 숫자를 지정할 수없는 속성에 대해서는 실패합니다.
Sid

@Sid 예를 들어주세요.
친절한 사용자

여기 요 let joshua = {이름 : 'Joshua', 주소 : 'London'}; Object.defineProperty (joshua, 'isMarried', {값 : true, 열거 가능 : false}); console.log ( 'isMarried'in Object.keys (joshua))
Sid

내 객체에 솔루션을 적용하고 있습니다. 첫 번째 출력에 맞지 않아야합니까? console.log (Object.keys (joshua) .some (v => v == 'isMarried')); console.log (joshua.isMarried);
Sid

1
미안하지만 두 번째 콘솔 명령문의 출력을 확인 했습니까? Object.defineProperty는 점 표기법을 사용하여 속성을 설정하는 것과 같습니다.
Sid

6

우리는 사용할 수 있습니다- hasOwnProperty.call(obj, key);

underscore.js 방법 -

if(_.has(this.options, 'login')){
  //key 'login' exists in this.options 
}

_.has = function(obj, key) {
  return hasOwnProperty.call(obj, key);
};

5

확인하는 가장 쉬운 방법은

"key" in object

예를 들면 다음과 같습니다.

var obj = {
  a: 1,
  b: 2,
}
"a" in obj // true
"c" in obj // false

true 값을 반환 하면 객체에 키가 있음을 의미합니다.


4

이있는 사람들을 위해 lodash자신의 프로젝트에 포함 된
lodash의이 _.get의 "깊은"키를 얻기 위해 시도하는 방법은 :

객체의 경로에서 값을 가져옵니다. 해석 된 값이 정의되지 않은 경우 defaultValue가 그 자리에 리턴됩니다.

var object = { 'a': [{ 'b': { 'c': 3 } }] };

console.log(
  _.get(object, 'a[0].b.c'),           // => 3
  _.get(object, ['a', '0', 'b', 'c']), // => 3
  _.get(object, 'a.b.c'),              // => undefined 
  _.get(object, 'a.b.c', 'default')    // => 'default'
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>


이렇게하면 해당 키 가 정의되어 있는지 확인하지만 깊이 가 정의 되지 않은 경우 프로그램 흐름에 해를 끼칠 수있는 오류가 발생하지 않습니다.


4

키가 있는지 반드시 확인하는 것은 아니지만 값의 진실성을 확인합니다. 어느 undefinednull가을에서.

Boolean(obj.foo)

이 솔루션은 typescript를 사용하고 문자열을 사용 'foo' in obj하거나 obj.hasOwnProperty('foo') 키가 있는지 여부를 확인 하기 때문에 나에게 가장 효과적입니다 .


3

객체에서 임의의 깊이의 키를 확인하고 잘못된 값을 설명하려면 유틸리티 기능에 대해 다음 줄을 고려하십시오.

var keyExistsOn = (o, k) => k.split(".").reduce((a, c) => a.hasOwnProperty(c) ? a[c] || 1 : false, Object.assign({}, o)) === false ? false : true;

결과

var obj = {
    test: "",
    locals: {
        test: "",
        test2: false,
        test3: NaN,
        test4: 0,
        test5: undefined,
        auth: {
            user: "hw"
        }
    }
}

keyExistsOn(obj, "")
> false
keyExistsOn(obj, "locals.test")
> true
keyExistsOn(obj, "locals.test2")
> true
keyExistsOn(obj, "locals.test3")
> true
keyExistsOn(obj, "locals.test4")
> true
keyExistsOn(obj, "locals.test5")
> true
keyExistsOn(obj, "sdsdf")
false
keyExistsOn(obj, "sdsdf.rtsd")
false
keyExistsOn(obj, "sdsdf.234d")
false
keyExistsOn(obj, "2134.sdsdf.234d")
false
keyExistsOn(obj, "locals")
true
keyExistsOn(obj, "locals.")
false
keyExistsOn(obj, "locals.auth")
true
keyExistsOn(obj, "locals.autht")
false
keyExistsOn(obj, "locals.auth.")
false
keyExistsOn(obj, "locals.auth.user")
true
keyExistsOn(obj, "locals.auth.userr")
false
keyExistsOn(obj, "locals.auth.user.")
false
keyExistsOn(obj, "locals.auth.user")
true

이 NPM 패키지도 참조하십시오 : https://www.npmjs.com/package/has-deep-value


3
const object1 = {
  a: 'something',
  b: 'something',
  c: 'something'
};

const key = 's';

// Object.keys(object1) will return array of the object keys ['a', 'b', 'c']

Object.keys(object1).indexOf(key) === -1 ? 'the key is not there' : 'yep the key is exist';

3

'배열'세계에서는 인덱스를 일종의 키로 볼 수 있습니다. 놀랍게도 in연산자 (객체에 적합한 선택)는 배열에서도 작동합니다. 존재하지 않는 키의 반환 값은undefined

let arr = ["a","b","c"]; // we have indexes: 0,1,2
delete arr[1];           // set 'empty' at index 1
arr.pop();               // remove last item

console.log(0 in arr,  arr[0]);
console.log(1 in arr,  arr[1]);
console.log(2 in arr,  arr[2]);


2

yourArray.indexOf (yourArrayKeyName)> -1

fruit = ['apple', 'grapes', 'banana']

fruit.indexOf('apple') > -1

진실


fruit = ['apple', 'grapes', 'banana']

fruit.indexOf('apple1') > -1

그릇된


0

이 예제는 다른 방법들 사이의 차이점을 보여줄 수 있습니다. 귀하의 요구에 맞는 것을 선택하는 데 도움이되기를 바랍니다.

// Lets create object `a` using create function `A`
function A(){};
A.prototype.onProtDef=2;
A.prototype.onProtUndef=undefined;
var a=new A();
a.ownProp = 3;
a.ownPropUndef = undefined;

// Let's try different methods:

a.onProtDef; // 2
a.onProtUndef; // undefined
a.ownProp; // 3
a.ownPropUndef; // undefined
a.whatEver; // undefined
a.valueOf; // ƒ valueOf() { [native code] }

a.hasOwnProperty('onProtDef'); // false
a.hasOwnProperty('onProtUndef'); // false
a.hasOwnProperty('ownProp'); // true
a.hasOwnProperty('ownPropUndef'); // true
a.hasOwnProperty('whatEver'); // false
a.hasOwnProperty('valueOf'); // false

'onProtDef' in a; // true
'onProtUndef' in a; // true
'ownProp' in a; // true
'ownPropUndef' in a; // true
'whatEver' in a; // false
'valueOf' in a; // true (on the prototype chain - Object.valueOf)

Object.keys(a); // ["ownProp", "ownPropUndef"]

-1

JavaScript Destructuring을 사용한 새로운 멋진 솔루션 :

let obj = {
    "key1": "value1",
    "key2": "value2",
    "key3": "value3",
};

let {key1, key2, key3, key4} = obj;

// key1 = "value1"
// key2 = "value2"
// key3 = "value3"
// key4 = undefined

// Can easily use `if` here on key4
if(!key4) { console.log("key not present"); } // Key not present

JavaScript Destructuring의 다른 사용을 확인하십시오

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.