[javascript] ‘정의되지 않은 속성을 읽을 수 없음’오류를 방지하는 방법은 무엇입니까?

내 코드에서는 여러 개체가 서로 중첩 된 항목이있는 배열을 다루지 만 일부는 그렇지 않습니다. 다음과 같이 보입니다.

// where this array is hundreds of entries long, with a mix
// of the two examples given
var test = [{'a':{'b':{'c':"foo"}}}, {'a': "bar"}];

때때로 배열을 반복해야하고 불일치로 인해 다음과 같은 오류가 발생하기 때문에 문제가 발생합니다.

for (i=0; i<test.length; i++) {
    // ok on i==0, but 'cannot read property of undefined' on i==1
    console.log(a.b.c);
}

나는 말할 수 있다는 것을 알고 if(a.b){ console.log(a.b.c)}있지만, 서로 중첩 된 개체가 5 개 또는 6 개까지있는 경우 이것은 매우 지루합니다. 존재하는 경우에만 console.log를 수행하고 오류를 발생시키지 않고 수행 할 수있는 다른 (더 쉬운) 방법이 있습니까?



답변

업데이트 :

  • ECMAScript 2020 이상에 따라 JavaScript를 사용하는 경우 선택적 체인을 참조하십시오. .
  • TypeScript는 버전 3.7 에서 선택적 체인에 대한 지원을 추가했습니다 .
// use it like this
obj?.a?.lot?.of?.properties

ECMASCript 2020 이전의 JavaScript 또는 버전 3.7 이전의 TypeScript에 대한 솔루션 :

빠른 해결 방법은 ES6 화살표 기능 과 함께 try / catch 도우미 기능을 사용하는 것입니다 .

function getSafe(fn, defaultVal) {
    try {
        return fn();
    } catch (e) {
        return defaultVal;
    }
}

// use it like this
getSafe(() => obj.a.lot.of.properties);

// or add an optional default value
getSafe(() => obj.a.lot.of.properties, 'nothing');

작업 스 니펫 :

자세한 내용은 이 기사 를 참조하십시오.


답변

당신이하는 일은 예외를 일으킨다.

당신은 항상 할 수 있습니다

try{
   window.a.b.c
}catch(e){
   console.log("YO",e)
}

그러나 나는 당신의 사용 사례를 생각하지 않을 것입니다.

익숙하지 않은 6 단계 중첩 데이터에 액세스하는 이유는 무엇입니까? 이를 정당화하는 사용 사례는 무엇입니까?

일반적으로 어떤 종류의 개체를 다루고 있는지 실제로 확인하고 싶습니다.

또한 참고로 if(a.b)ab가 0이거나 “0”인 경우에도 false를 반환하기 때문에 다음 과 같은 문을 사용해서는 안됩니다 . 대신 확인하십시오a.b !== undefined


답변

질문을 올바르게 이해하고 있다면 객체에 속성이 포함되어 있는지 확인하는 가장 안전한 방법이 필요합니다.

가장 쉬운 방법은 in연산자 를 사용하는 것 입니다 .

window.a = "aString";
//window should have 'a' property
//lets test if it exists
if ("a" in window){
    //true
 }

if ("b" in window){
     //false
 }

물론 원하는만큼 깊이 중첩 할 수 있습니다.

if ("a" in window.b.c) { }

이것이 도움이되는지 확실하지 않습니다.


답변

당신이 사용하는 경우 lodash을 , 당신은 “이”기능을 사용할 수 있습니다. 네이티브 “in”과 유사하지만 경로를 허용합니다.

var testObject = {a: {b: {c: 'walrus'}}};
if(_.has(testObject, 'a.b.c')) {
  //Safely access your walrus here
}


답변

이 시도. a.b정의되지 않은 경우 if예외없이 문을 떠납니다 .

if (a.b && a.b.c) {
  console.log(a.b.c);
}


답변

이것은 깊거나 복잡한 json 객체로 작업 할 때 일반적인 문제이므로 코드를 읽을 수 없게 만드는 try / catch 또는 여러 검사를 포함하지 않으려 고 노력합니다. 일반적으로이 작은 코드 조각을 모든 절차에서 사용하여 작업을 수행합니다.

/* ex: getProperty(myObj,'aze.xyz',0) // return myObj.aze.xyz safely
 * accepts array for property names:
 *     getProperty(myObj,['aze','xyz'],{value: null})
 */
function getProperty(obj, props, defaultValue) {
    var res, isvoid = function(x){return typeof x === "undefined" || x === null;}
    if(!isvoid(obj)){
        if(isvoid(props)) props = [];
        if(typeof props  === "string") props = props.trim().split(".");
        if(props.constructor === Array){
            res = props.length>1 ? getProperty(obj[props.shift()],props,defaultValue) : obj[props[0]];
        }
    }
    return typeof res === "undefined" ? defaultValue: res;
}


답변

당신이있는 경우 lodash 당신은 사용할 수있는 .get방법을

_.get(a, 'b.c.d.e')

또는 기본값 제공

_.get(a, 'b.c.d.e', default)