JavaScript에서 객체에 특정 속성이 있는지 어떻게 확인합니까?
고려하다:
x = {'key': 1}; if ( x.hasOwnProperty('key') ) { //Do this }
그게 최선의 방법인가요?
질문자 :sheats
JavaScript에서 객체에 특정 속성이 있는지 어떻게 확인합니까?
고려하다:
x = {'key': 1}; if ( x.hasOwnProperty('key') ) { //Do this }
그게 최선의 방법인가요?
주어진 답변에 정말 혼란스럽습니다. 대부분이 완전히 틀립니다. 물론 정의되지 않은 값, 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
하나주의해야 할 점으로, : 동일한 속성은 프로토 타입과 인스턴스입니다 경우를 구별 할 수 없습니다 - 그것은 그냥 프로토 타입에서오고 있다고 가정합니다. 상황에 따라 더 관대하거나 엄격하게 변경할 수 있지만 최소한 이것이 더 도움이 될 것입니다.
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
사용하다:
var x = { 'key': 1 }; if ('key' in x) { console.log('has'); }
참고 hasOwnProperty
덕분에 오늘날 대부분 사용되지 않습니다. 올바른 해결책은 엄격 모드를 사용하고 obj.hasOwnProperty
사용하여 속성이 있는지 확인하는 것입니다. 이 답변은 적어도 널리 구현된 것만큼은 이 두 가지 보다 앞선 것입니다(예, 오래된 것입니다). 다음을 역사적 기록으로 삼으십시오.
곰 염두에 undefined
IS (불행히도) 자바 스크립트에없는 예약어는 엄격 모드를 사용하지 않는 경우. 따라서 누군가(분명히 다른 누군가)가 코드를 재정의하고 코드를 깨는 웅대한 아이디어를 가질 수 있습니다.
따라서 보다 강력한 방법은 다음과 같습니다.
if (typeof(x.attribute) !== 'undefined')
반대로 이 방법은 훨씬 더 장황하고 느립니다. :-/
일반적인 대안은 undefined 가 실제로 undefined
는지 확인하는 것입니다. 예를 들어, 값이 전달 undefined
라는 추가 매개변수를 허용하는 함수에 코드를 넣습니다. 값이 전달되지 않았는지 확인하려면 즉시 직접 호출하면 됩니다. 예:
(function (undefined) { … your code … if (x.attribute !== undefined) … mode code … })();
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!'); }
Konrad Rudolph 와 Armin Ronacher 가 지적한 안전하지만 느린 솔루션은 다음과 같습니다.
Object.prototype.hasOwnProperty = function(property) { return typeof this[property] !== 'undefined'; };
Javascript에서 다음 객체 고려
const x = {key: 1};
in
연산자를 사용하여 객체에 속성이 있는지 확인할 수 있습니다.
console.log("key" in x);
for - in
루프를 사용하여 객체의 모든 속성을 반복한 다음 특정 속성을 확인할 수도 있습니다.
for (const prop in x) { if (prop === "key") { //Do something } }
for-in
루프에 표시되지 않으므로 이 개체 속성이 열거 가능한지 여부를 고려해야 합니다. 또한 열거 가능한 속성이 프로토타입의 열거할 수 없는 속성을 가리고 있는 경우 Internet Explorer 8 및 이전 버전에서는 표시되지 않습니다.
열거 가능 여부에 관계없이 모든 인스턴스 속성 목록을 원하면 다음을 사용할 수 있습니다.
Object.getOwnPropertyNames(x);
이것은 객체에 존재하는 모든 속성의 이름 배열을 반환합니다.
리플렉션 은 Javascript 개체와 상호 작용하는 데 사용할 수 있는 메서드를 제공합니다. 정적 Reflect.has()
메서드는 함수로 in 연산자처럼 작동합니다.
console.log(Reflect.has(x, 'key')); // expected output: true console.log(Reflect.has(x, 'key2')); // expected output: false console.log(Reflect.has(object1, 'toString')); // expected output: true
마지막으로 typeof 연산자를 사용하여 객체 속성의 데이터 유형을 직접 확인할 수 있습니다.
if (typeof x.key === "undefined") { console.log("undefined"); }
속성이 개체에 없으면 정의되지 않은 문자열을 반환합니다. 그렇지 않으면 적절한 속성 유형을 반환합니다. 그러나 정의되지 않은 속성을 가질 수 있기 때문에 이것이 객체에 속성이 있는지 여부를 확인하는 유효한 방법은 아닙니다. 이 경우 typeof x.key
하면 여전히 true를 반환합니다. 키는 여전히 개체에 있음).
undefined
Javascript 속성과 직접 비교하여 속성이 존재하는지 확인할 수 있습니다.
if (x.key === undefined) { console.log("undefined"); }
키가 x 개체 undefined
것으로 특별히 설정되지 않은 경우 작동해야 합니다.
여기서 약간의 혼란을 없애자. hasOwnProperty
이미 존재한다고 가정하여 단순화하겠습니다. 이것은 현재 사용 중인 대다수의 브라우저에 해당됩니다.
hasOwnProperty
는 전달된 속성 이름이 개체에 추가된 경우 true를 반환합니다. undefined
할당된 실제 값과 완전히 독립적입니다.
따라서:
var o = {} ox = undefined var a = o.hasOwnProperty('x') // a is true var b = ox === undefined // b is also true
하지만:
var o = {} var a = o.hasOwnProperty('x') // a is now false var b = ox === undefined // b is still true
문제는 프로토타입 체인의 객체에 값이 정의되지 않은 속성이 있을 때 어떻게 됩니까? hasOwnProperty
는 false 이고 !== undefined
마찬가지입니다. 그러나 for..in
은 여전히 열거형에 나열합니다.
결론은 특정 식별자가 개체 또는 개체의 프로토타입 체인에 연결되지 않았는지 확인하는 브라우저 간 방법(Internet Explorer는 __prototype__
속성을 검색하는 경우 "아니요" 입니다. 당신이 원하는:
if ('prop' in obj) { }
일반적으로 속성이 프로토타입에서 왔는지 아니면 객체에서 왔는지 신경쓰지 않아야 합니다.
그러나 샘플 코드에서 '키'를 사용했기 때문에 객체를 해시로 취급하는 것처럼 보입니다. 이 경우 답변이 의미가 있습니다. 모든 해시 키는 객체의 속성이 되며 프로토타입에서 제공하는 추가 속성을 피할 수 있습니다.
John Resig의 답변 은 매우 포괄적이지만 명확하지 않다고 생각했습니다. 특히 "'prop' in obj"를 사용할 때.
간단한 객체를 테스트하려면 다음을 사용하십시오.
if (obj[x] !== undefined)
그것이 어떤 객체 유형인지 모르는 경우 다음을 사용하십시오.
if (obj.hasOwnProperty(x))
다른 모든 옵션은 더 느립니다...
Node.js에서 다른 사람들이 제안한 5가지 옵션에 대한 100,000,000 사이클의 성능 평가는 다음과 같습니다.
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: 4.51 s hasKey2 execution time: 0.90 s hasKey3 execution time: 0.76 s hasKey4 execution time: 0.93 s hasKey5 execution time: 2.15 s
결론적으로, Obj가 반드시 단순한 객체가 아니고 객체의 프로토타입 체인을 확인하지 않고 x가 Obj에 직접 소유되어 있는지 확인하려면 if (obj.hasOwnProperty(x))...
.
그렇지 않으면 단순한 객체를 사용하고 객체의 프로토타입 체인에 대해 걱정하지 않을 때 if (typeof(obj[x]) !== 'undefined')...
를 사용하는 것이 가장 안전하고 빠른 방법입니다.
간단한 객체를 해시 테이블로 사용하고 변태적인 작업을 하지 if (obj[x])...
를 사용하면 훨씬 읽기 쉽습니다.
예 그렇습니다 : 당신도 할 수 있다고 생각 Object.prototype.hasOwnProperty.call(x, 'key')
하는해야 또한 일 경우 x
라는 속성이 hasOwnProperty
:)
그러나 그것은 자신의 속성을 테스트합니다. 상속될 수 있는 속성이 있는지 확인하려면 typeof x.foo != 'undefined'
사용할 수 있습니다.
ES6 Reflect
객체를 사용할 수도 있습니다.
x = {'key': 1}; Reflect.has( x, 'key'); // returns true
Reflect.has
에 대한 MDN에 대한 문서는 여기 에서 찾을 수 있습니다.
정적
Reflect.has()
메서드는 in 연산자 처럼 함수로 작동합니다.
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. console.log(has.call(object, key)); /* Or */ import has from 'has'; // https://www.npmjs.com/package/has console.log(has(object, key));
if (typeof x.key != "undefined") { }
때문에
if (x.key)
x.key
가 false
확인되면 실패합니다(예: x.key = ""
).
좋아요, 상속된 속성을 원하지 않는 경우가 아니면 제가 정답을 찾은 것 같습니다.
if (x.hasOwnProperty('key'))
상속된 속성을 포함하는 몇 가지 다른 옵션은 다음과 같습니다.
if (x.key) // Quick and dirty, but it does the same thing as below. if (x.key !== undefined)
또 다른 비교적 간단한 방법은 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
우리는 훌륭한 브라우저 지원을 제공하는 세계에 있지만. 이 질문은 너무 오래되었기 때문에 다음을 추가할 것이라고 생각했습니다. 이것은 JavaScript v1.8.5 부터 사용하기에 안전합니다.
hasOwnProperty는 "객체가 지정된 속성을 해당 객체의 직접 속성으로 가지고 있는지 여부를 확인하는 데 사용할 수 있습니다. in 연산자와 달리 이 메서드는 객체의 프로토타입 체인을 확인하지 않습니다."
따라서 귀하의 질문에 따르면 속성이 객체 자체 에 직접 연결된 상태로 존재하는지 여부를 결정하는 hasOwnProperty를 사용하고 싶지 않을 것입니다.
프로토타입 체인에 속성이 있는지 확인하려면 다음과 같이 사용할 수 있습니다.
if (prop in object) { // Do something }
JavaScript는 이제 이를 확인할 수 있는 훌륭하고 효율적인 방법이 있으므로 진화하고 성장하고 있습니다.
다음은 객체에 특정 속성이 있는지 확인하는 몇 가지 쉬운 방법입니다.
hasOwnProperty()
const hero = { name: 'Batman' }; hero.hasOwnProperty('name'); // => true hero.hasOwnProperty('realName'); // => false
in
const hero = { name: 'Batman' }; 'name' in hero; // => true 'realName' in hero; // => false
undefined
키워드와 비교 const hero = { name: 'Batman' }; hero.name; // => 'Batman' hero.realName; // => undefined // So consider this hero.realName == undefined // => true (which means property does not exists in object) hero.name == undefined // => false (which means that property exists in object)
자세한 내용은 여기를 확인하십시오.
다음 접근 방식을 사용할 수 있습니다.
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);
다음은 특정 경우에 대한 또 다른 옵션입니다. :)
개체에서 구성원을 테스트하고 다음 이외의 항목으로 설정되었는지 알고 싶은 경우:
다음을 사용할 수 있습니다.
var foo = {}; foo.bar = "Yes, this is a proper value!"; if (!!foo.bar) { // member is set, do something }
오늘 2020.12.17 선택한 솔루션에 대해 Chrome v87, Safari v13.1.2 및 Firefox v83의 MacOs HighSierra 10.13.6에서 테스트를 수행합니다.
세부 정보 섹션의 스니펫에 사용된 모든 경우에 유효한 결과를 제공하기 때문에 솔루션 AF만 비교합니다. 모든 브라우저용
in
(A)가 빠르거나 가장 빠른has
(B)가 가장 느립니다.4가지 테스트 케이스를 수행합니다.
아래 스니펫은 솔루션 간의 차이점을 나타냅니다. 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!
다음은 크롬에 대한 예시 결과입니다.
myObject 객체와 "myKey" 를 키 이름으로 지정:
Object.keys(myObject).includes('myKey')
또는
myObject.hasOwnProperty('myKey')
또는
typeof myObject.myKey !== 'undefined'
마지막은 널리 사용되었지만 (다른 답변 및 의견에서 지적했듯이) Object 프로토타입에서 파생된 키에서도 일치할 수 있습니다.
객체에 "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"));
리플렉션이 있는 ECMAScript 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
object.hasOwnProperty(property)
메서드를 사용해야 합니다. 객체에 속성이 있으면 true를 반환하고 객체에 속성이 없으면 false를 반환합니다.
이 답변 을 사용하는 방법 표시
const object= {key1: 'data', key2: 'data2'}; Object.keys(object).includes('key1') //returns true
indexOf
도 사용할 수 있으며 포함하는 것을 선호 합니다.
hasOwnProperty() 메서드는 객체에 지정된 속성이 상속과 반대되는 자체 속성으로 지정되어 있는지 여부를 나타내는 부울 값을 반환합니다.
const object1 = {}; object1.property1 = 42; console.log(object1.hasOwnProperty('property1')); // expected output: true console.log(object1.hasOwnProperty('toString')); // expected output: false console.log(object1.hasOwnProperty('hasOwnProperty')); // expected output: false
특정 사용 사례에 따라 더 쉽고 짧은 옵션:
코드 조각을 실행하여 결과를 확인하세요.
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");
특히 상속 문제를 hasOwn
이 제대로 사용되는 경우는 거의 없습니다.
다음을 할 수 있을 때 일을 지나치게 복잡하게 만들지 마십시오.
var isProperty = (objectname.keyname || "") ? true : false;
대부분의 경우 간단하고 명확합니다 ...
hasOwnProperty()
검사를 사용하지 않고 객체의 속성을 반복 for(let key of Object.keys(stud)){}
메서드를 사용하세요.
for(let key of Object.keys(stud)){ console.log(key); // will only log object's Own properties }
전체 예제 및 for-in with hasOwnProperty()
function Student() { this.name = "nitin"; } Student.prototype = { grade: 'A' } let stud = new Student(); // for-in approach for(let key in stud){ if(stud.hasOwnProperty(key)){ console.log(key); // only outputs "name" } } //Object.keys() approach for(let key of Object.keys(stud)){ console.log(key); }
출처 : http:www.stackoverflow.com/questions/135448/how-do-i-check-if-an-object-has-a-specific-property-in-javascript
Promise와 Observable의 차이점은 무엇입니까? (0) | 2022.01.23 |
---|---|
jQuery의 $.ready()에 해당하는 순수 JavaScript - 페이지/DOM이 준비되었을 때 함수를 호출하는 방법 [중복] (0) | 2022.01.23 |
항상 새 탭에서 파일 열기 (0) | 2022.01.22 |
CSS calc() 함수의 Sass 변수 (0) | 2022.01.22 |
Git 리포지토리의 하위 디렉터리만 복제하려면 어떻게 합니까? (0) | 2022.01.22 |