JavaScript에서 객체에 특정 속성이 있는지 어떻게 확인합니까?
치다:
x = {'key': 1};
if ( x.hasOwnProperty('key') ) {
//Do this
}
그것이 최선의 방법입니까?
in
그리고 hasOwnProperty
나온 방법 (98 % 느리게) 나를 위해 느린 다른 사람보다. 나는 hasOwnProperty
느리게 놀랄 것이 아니라 놀랐습니다 in
.
JavaScript에서 객체에 특정 속성이 있는지 어떻게 확인합니까?
치다:
x = {'key': 1};
if ( x.hasOwnProperty('key') ) {
//Do this
}
그것이 최선의 방법입니까?
in
그리고 hasOwnProperty
나온 방법 (98 % 느리게) 나를 위해 느린 다른 사람보다. 나는 hasOwnProperty
느리게 놀랄 것이 아니라 놀랐습니다 in
.
답변:
나는 주어진 답변에 정말 혼란 스럽습니다. 대부분의 답변은 완전히 틀 렸습니다. 물론 정의되지 않은, null 또는 false 값을 가진 개체 속성을 가질 수 있습니다. 따라서 속성 확인을 typeof this[property]
줄이거 나 더 나쁜 것은 x.key
완전히 잘못된 결과를 초래할 수 있습니다.
찾고있는 내용에 따라 다릅니다. 객체에 물리적으로 속성이 포함되어 있는지 (그리고 프로토 타입 체인의 어딘가에서 나오지 않는지) 알고 싶다면 object.hasOwnProperty
갈 길입니다. 모든 최신 브라우저가이를 지원합니다. (이전 버전의 Safari-2.0.1 이상에서는 누락되었지만 해당 버전의 브라우저는 더 이상 사용되지 않습니다.)
찾고있는 것이 객체에 반복 가능한 속성이있는 경우 (객체의 속성을 반복 할 때 나타납니다) 다음을 수행 prop in object
하면 원하는 효과 가 나타납니다 .
사용하는 hasOwnProperty
것이 아마도 당신이 원하는 것이며, 대체 방법을 원할 것이라고 생각하기 때문에 다음 해결책을 제시합니다.
var obj = {
a: undefined,
b: null,
c: false
};
// a, b, c all found
for ( var prop in obj ) {
document.writeln( "Object1: " + prop );
}
function Class(){
this.a = undefined;
this.b = null;
this.c = false;
}
Class.prototype = {
a: undefined,
b: true,
c: true,
d: true,
e: true
};
var obj2 = new Class();
// a, b, c, d, e found
for ( var prop in obj2 ) {
document.writeln( "Object2: " + prop );
}
function hasOwnProperty(obj, prop) {
var proto = obj.__proto__ || obj.constructor.prototype;
return (prop in obj) &&
(!(prop in proto) || proto[prop] !== obj[prop]);
}
if ( Object.prototype.hasOwnProperty ) {
var hasOwnProperty = function(obj, prop) {
return obj.hasOwnProperty(prop);
}
}
// a, b, c found in modern browsers
// b, c found in Safari 2.0.1 and older
for ( var prop in obj2 ) {
if ( hasOwnProperty(obj2, prop) ) {
document.writeln( "Object2 w/ hasOwn: " + prop );
}
}
위의 내용은 hasOwnProperty
하나의 경고와 함께 작동하는 크로스 브라우저 솔루션 입니다. 프로토 타입과 인스턴스에 동일한 속성이있는 경우를 구별 할 수는 없으며 프로토 타입에서 온 것으로 가정합니다. 상황에 따라 좀 더 관대하거나 엄격하게 바꿀 수 있지만 최소한 더 도움이 될 것입니다.
var w = opts.w || 100;
. 그러나 당신이 어떤 종류의 라이브러리에 있다면 약간의 부분을 조금 더 가야 할 수도 있습니다.
__proto__
는 null? 간단한 impl : function hasOwnProperty(obj, prop) { var temp = obj.__proto__; obj.__proto__ = null; var ret = prop in obj; obj.__proto__ = temp; return ret; }
(케이스 포함 obj.constructor.prototype
).
__proto__
은 비표준이며 일부 구형 브라우저에서는 작동하지 않습니다. 그리고 최근 Object.getPrototypeOf
에 표준을 추가하더라도 기존 개체의 프로토 타입을 변경할 수는 없습니다.
for(prop in object)
루프는 열거 속성을 반복 할. 그러나 열거 형 체인에 속성이 prop in object
있는지 여부 object
를 prop
독립적으로 열거 할 수 있는지 여부를 확인합니다.
와 함께 Underscore.js
또는 ( 더 나은 ) lodash
:
_.has(x, 'key');
어떤 호출 Object.prototype.hasOwnProperty
이지만 (a) 입력하기가 더 짧고 (b) "안전 참조 hasOwnProperty
"를 사용합니다 (즉, hasOwnProperty
덮어 쓴 경우에도 작동 함 ).
특히 lodash는 다음 _.has
과 같이 정의 합니다.
function has(object, key) {
return object ? hasOwnProperty.call(object, key) : false;
}
// hasOwnProperty = Object.prototype.hasOwnProperty
npm install lodash.has
되는 has
함수 로 npm 모듈을 노출 시킬 수 있습니다. 또한 lodash.has/index.js
매우 인기 있고 신뢰할 수있는 라이브러리의 작동 방식 을 살펴 보는 것도 통찰력이 있습니다 .
lodash
의 버전이 함께 작동 : .has(undefined, 'someKey') => false
잠시 underscore
반환undefined
lodash
"아직 또 다른"종속성으로 추가하려고하는 모든 사람에게 : 이런 종류의 라이브러리는 상당히 일반적인 라이브러리입니다. 바퀴를 재발견하십시오.
이건 어떤가요?
var x = {'key': 1};
if ('key' in x) {
console.log('has');
}
in
운영자를 사용해야하는지에 대한 자세한 내용은 다루지 않습니다. 또한 in
운영자는 뛰어난 브라우저 지원 기능을 가지고 있음에 유의하십시오. IE 5.5+, Chrome 1.0+, Firefox 1.0+, Safari 3.0+
stackoverflow.com/questions/2920765/…
in
또한 작업자 는 프로토 타입 속성을 확인하고 hasOwnProperty
사용자 정의 속성 만 반복합니다. 참조 : developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
'key' in x
이렇게 배열 작업을. 증명 : stackoverflow.com/questions/33592385/…
참고 : 다음은 현재 엄격 모드로 인해 더 이상 사용되지 않습니다 hasOwnProperty
. 올바른 해결책은 엄격 모드를 사용하고을 사용하여 속성이 있는지 확인하는 것 obj.hasOwnProperty
입니다. 이 답변 은 적어도 광범위하게 구현 된 것처럼이 두 가지 보다 앞서 있습니다 (그렇습니다. 다음을 역사적 메모로 사용하십시오.
엄격 모드를 사용하지 않는 경우 JavaScript에서 예약어가 아님을undefined
유감스럽게 생각 하십시오. 따라서 누군가 (다른 사람은 분명히) 그것을 재정의하고 코드를 깨뜨리는 위대한 아이디어를 가질 수 있습니다.
따라서보다 강력한 방법은 다음과 같습니다.
if (typeof(x.attribute) !== 'undefined')
반대로,이 방법은 훨씬 더 장황하고 느립니다. :-/
일반적인 대안은 값이 전달되지 않는 추가 매개 변수 ()를 허용하는 함수에 코드를 삽입하여 실제로 정의되지 않은 것을 확인하는 것 undefined
입니다 . 값이 전달되지 않도록하려면 다음과 같이 즉시 직접 호출하면됩니다.undefined
(function (undefined) {
… your code …
if (x.attribute !== undefined)
… mode code …
})();
void 0
정식를 반환 정의 undefined
, 하나는 할 수 x.attribute !== void 0
?
(function (undefined) { // undefined is actually undefined here })();
if (x.key !== undefined)
Armin Ronacher 는 이미 저를 이겼습니다 .
Object.prototype.hasOwnProperty = function(property) {
return this[property] !== undefined;
};
x = {'key': 1};
if (x.hasOwnProperty('key')) {
alert('have key!');
}
if (!x.hasOwnProperty('bar')) {
alert('no bar!');
}
안전하고 있지만, 느린 솔루션, 지적 으로 콘라드 루돌프 와 아르 민 Ronacher 될 것이다 :
Object.prototype.hasOwnProperty = function(property) {
return typeof this[property] !== 'undefined';
};
x.hasOwnProperty('toString') === true;
Object.prototype
이미 내장되어 hasOwnProperty
있습니다. 잘못된 구현으로 덮어 씁니다 (1. 속성의 값 undefined
은 2 일 수 있습니다. 상속 된 속성에 잘못된 긍정을 줄 것입니다). 잘못된 답변은 삭제할 수 있으며 삭제해야합니다. Resig의 답변을 보았을 때 08 년 9 월에 다시 할 수 있는지 모르겠 으므로 지금 제안하십시오.
in
연산자를 사용하여 속성이 객체에 존재하는지 확인할 수 있습니다 .
x = {'key': 1};
alert("key" in x);
루프를 사용하여 객체의 모든 속성을 for - in
반복 한 다음 특정 속성을 확인할 수도 있습니다.
for (prop in x) {
if (prop == "key") {
//Do something
}
}
열거 할 수없는 속성은 for-in
루프에 표시되지 않으므로이 개체 속성을 열거 할 수 있는지 고려해야합니다 . 또한 열거 가능한 속성이 프로토 타입의 열거 할 수없는 속성을 음영 처리하는 경우 Internet Explorer 8 및 이전 버전 에는 표시되지 않습니다 .
열거 가능 여부에 관계없이 모든 인스턴스 속성 목록을 원할 경우
Object.getOwnPropertyNames(x);
객체에 존재하는 모든 속성의 이름 배열이 반환됩니다.
마지막으로 typeof 연산자를 사용하여 객체 속성의 데이터 유형을 직접 확인할 수 있습니다.
if (typeof x.key == "undefined") {
alert("undefined");
}
속성이 개체에 없으면 문자열 undefined를 반환합니다. 그렇지 않으면 적절한 속성 유형을 반환합니다. 그러나 객체에 속성이 있는지 여부를 확인하는 올바른 방법은 아닙니다. 정의되지 않은 속성을 설정할 수 있기 때문에 typeof x.key
키를 계속 사용하더라도 여전히 true를 반환합니다. 개체에서).
업데이트 : 정의되지 않은 자바 스크립트 속성과 비교하여 속성이 존재하는지 확인할 수 있습니다
if (x.key === undefined) {
alert("undefined");
}
undefined
x 객체에 키가 특별히 설정되어 있지 않으면 작동 합니다.
여기에 약간의 혼란을 줄이자. 먼저, hasOwnProperty
이미 존재 한다고 가정하여 단순화합시다 . 이것은 현재 사용중인 대다수의 현재 브라우저에 해당됩니다.
hasOwnProperty
전달 된 속성 이름이 객체에 추가 된 경우 true를 반환합니다. 정확히 할당 된 실제 값과는 완전히 독립적입니다 undefined
.
그 후:
var o = {}
o.x = undefined
var a = o.hasOwnProperty('x') // a is true
var b = o.x === undefined // b is also true
하나:
var o = {}
var a = o.hasOwnProperty('x') // a is now false
var b = o.x === undefined // b is still true
문제는 프로토 타입 체인의 객체에 정의되지 않은 값의 속성이있는 경우 어떻게됩니까? hasOwnProperty
그것에 대해 거짓이 될 것 !== undefined
입니다. 그러나 for..in
여전히 열거 형에 나열합니다.
결론은 Internet Explorer가 노출하지 않기 때문에 브라우저 간 방법이 없기 때문에 __prototype__
특정 식별자가 프로토 타입 체인의 객체 또는 다른 것에 부착되지 않았 음을 확인하는 것입니다.
속성을 검색하는 경우 "아니오". 당신이 원하는 :
if ('prop' in obj) { }
일반적으로 속성이 프로토 타입 또는 객체에서 제공되는지 여부는 신경 쓰지 않아야합니다.
그러나 샘플 코드에서 '키'를 사용했기 때문에 객체를 해시로 취급하는 것처럼 보입니다.이 경우 대답이 의미가 있습니다. 모든 해시 키는 객체의 속성이므로 프로토 타입이 제공하는 추가 속성을 피할 수 있습니다.
John Resig의 답변은 매우 포괄적 이었지만 명확하지 않다고 생각했습니다. 특히 obj에서 " 'prop'를 사용할 때.
in
운전자가 뛰어난 브라우저 지원이 IE 5.5+, Chrome 1.0+, Firefox 1.0+, Safari 3.0+
stackoverflow.com/questions/2920765/...을
in
연산자 사용에 관한 다른 의견에서 지적한 바와 같이 : "이것은 좁은 의미로 '객체'와 함께 작동하므로 {}로 선언되거나 생성자를 사용하여 생성되었으므로 배열이나 기본 요소를 허용하지 않습니다. OP가 요구 한 것은 아니지만 다른 답변은보다 광범위한 기술을 제시합니다 (배열, 문자열 등으로 작업).
간단한 객체를 테스트하려면 다음을 사용하십시오.
if (obj[x] !== undefined)
사용중인 개체 유형을 모르는 경우 다음을 사용하십시오.
if (obj.hasOwnProperty(x))
다른 모든 옵션은 느립니다.
세부
Nodejs에서 100,000,000 사이클의 성능 평가는 다음과 같이 다른 사람들이 제안한 5 가지 옵션입니다.
function hasKey1(k,o) { return (x in obj); }
function hasKey2(k,o) { return (obj[x]); }
function hasKey3(k,o) { return (obj[x] !== undefined); }
function hasKey4(k,o) { return (typeof(obj[x]) !== 'undefined'); }
function hasKey5(k,o) { return (obj.hasOwnProperty(x)); }
평가 결과에 따르면 객체 자체뿐만 아니라 객체의 프로토 타입 체인을 구체적으로 확인하지 않는 한 일반적인 형식을 사용해서는 안됩니다 if (X in Obj)...
. 사용 사례에 따라 2 ~ 6 배 더 느립니다.
hasKey1 execution time: 4s 510.427785ms
hasKey2 execution time: 0s 904.374806ms
hasKey3 execution time: 0s 760.336193ms
hasKey4 execution time: 0s 935.19901ms
hasKey5 execution time: 2s 148.189608ms
결론적으로 Obj가 단순한 객체가 아니고 객체의 프로토 타입 체인을 확인하지 않고 Obj가 x를 직접 소유하고 있는지 확인하려면 'if (obj.hasOwnProperty (x)) ...'를 사용하십시오.
그렇지 않으면 간단한 객체를 사용하고 객체의 프로토 타입 체인에 대해 걱정하지 않는 경우 사용하는 if (typeof(obj[x]) !== 'undefined')...
것이 가장 안전하고 빠른 방법입니다.
간단한 객체를 해시 테이블로 사용하고 변태 작업을 수행하지 if (obj[x])...
않으면 훨씬 더 읽기 쉬운 것으로 사용합니다.
즐기세요
ES6 Reflect
객체를 사용할 수도 있습니다 .
x = {'key': 1};
Reflect.has( x, 'key'); // returns true
대한 MDN에 서 Reflect.has
찾을 수 있습니다 여기에 .
정적
Reflect.has()
메서드는 in 연산자 처럼 함수로 작동합니다.
상속 된 속성을 원하지 않는 경우 정답을 얻은 것처럼 보입니다.
if (x.hasOwnProperty('key'))
상속 된 속성을 포함하는 다른 옵션은 다음과 같습니다.
if (x.key) // Quick and dirty, but it does the same thing as below.
if (x.key !== undefined)
var x = { key: false };
x.key
object.hasOwnProperty(key))
이 방법은 문제가있는 객체의 속성으로 인해 그림자로 표시 { hasOwnProperty: false }
되거나 객체가 null 객체 일 수 있으므로이 방법을 사용 하지 마십시오 (Object.create(null))
.
가장 좋은 방법은 다음을 수행하는 것입니다 Object.prototype.hasOwnProperty.call(object, key)
.
const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope.
/* or */
import has from 'has'; // https://www.npmjs.com/package/has
// ...
console.log(has.call(object, key));
또 다른 비교적 간단한 방법은을 사용하는 것 Object.keys
입니다. 이것은 array
배열의 모든 기능을 얻음을 의미 하는를 반환합니다 .
var noInfo = {};
var info = {something: 'data'};
Object.keys(noInfo).length //returns 0 or false
Object.keys(info).length //returns 1 or true
우리는 훌륭한 브라우저를 지원하는 세계에 있지만. 이 질문이 너무 오래 되었기 때문에 이것을 추가한다고 생각했습니다. 이것은 JS v1.8.5 부터 사용하는 것이 안전합니다.
Object.keys(info).indexOf('someotherthing') !== -1
hasOwnProperty는 "객체의 지정된 속성이 해당 객체의 직접 속성으로 지정되어 있는지 여부를 확인하는 데 사용할 수 있습니다. in 연산자와 달리이 메서드는 객체의 프로토 타입 체인을 검사하지 않습니다."
따라서 아마도 귀하의 질문에 보이는 것처럼 속성이 객체 자체 에 직접 첨부되어 있는지 여부를 결정하는 hasOwnProperty를 사용하고 싶지 않습니다 .
속성이 기본 프로토 타입 체인에 있는지 확인하려면 다음과 같이 사용하십시오.
if( prop in object ){ // do something }
이게 도움이 되길 바란다.
대규모 다운 보팅 위험이있는 특정 사례에 대한 또 다른 옵션이 있습니다. :)
객체의 멤버를 테스트하고 다음과 다른 것으로 설정되어 있는지 알고 싶은 경우 :
다음을 사용할 수 있습니다.
var foo = {};
foo.bar = "Yes, this is a proper value!";
if (!!foo.bar) {
// member is set, do something
}
ECMA Script 6 솔루션. 다음과 같은 래퍼를 만듭니다.
/**
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
객체에 "hasOwnProperty"메소드가 있지만 때때로 객체가 null이거나 객체에 일부 속성이있을 수 있으므로이 메소드를 직접 호출하지 않는 것이 좋습니다. { hasOwnProperty: false }
더 좋은 방법은 다음과 같습니다.
// 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"));
다음과 같은 접근법을 사용할 수 있습니다.
var obj = {a:1}
console.log('a' in obj) //1
console.log(obj.hasOwnProperty('a')) //2
console.log(Boolean(obj.a)) //3
다음 접근법의 차이점은 다음과 같습니다.
var obj = {
a:2,
__proto__ :{b:2}
}
console.log('b' in obj)
console.log(Boolean(obj.b))
var obj = {
a:2,
__proto__ :{b:2}
}
console.log(obj.hasOwnProperty('b'))
var obj = {
b : undefined
}
console.log(Boolean(obj.b))
console.log('b' in obj);
확인하는 키가 변수에 저장된 경우 다음과 같이 확인할 수 있습니다.
x = {'key': 1};
y = 'key';
x[y];
당신이 할 수있을 때 왜 지나치게 복잡한 일 :
var isProperty = (objectname.keyname || "") ? true : false;
대부분의 경우 간단하고 명확합니다 ...
const objectName = { keyname: false };
이므로 true를 반환해야합니다 . 그러나 값이 false이므로이 논리를 사용하여 false를 반환합니다. keyname
objectname