2016-12-05 8 views
0

자바 스크립트에는 많은 하위 속성과 객체가있는 객체가 있습니다. ..자바 어설트 객체 체인

obj.eventOfType = (el.openSocial && el.openSocial.embed && el.openSocial.embed.context && 
        el.openSocial.embed.context.openSocial && el.openSocial.embed.context.openSocial.connections && 
        el.openSocial.embed.context.openSocial.connections.generator && el.openSocial.embed.context.openSocial.connections.generator.displayName) ? 
       el.openSocial.embed.context.openSocial.connections.generator && el.openSocial.embed.context.openSocial.connections.generator.displayName || ""; 

이 아주 좋은 보이지 않는 그래서 함수에 대한 생각이 쓴 :

그래서 내 몇 줄의 코드는 다음과 같이, 유래에 따라서

/** 
    * assert path exists as subobject chain within obj 
    * 
    * @param obj {object} the object to search for <code>path</code> in 
    * @param path {String} the path to search within <code>obj</code>. oatgh must not start wirth the object itself. 
    * @return {boolean} whether <code>path</code> exists within <code>obj</code> or not 
    * example: to check if the windows document body has a fist item element you would use 
    * if (assertChain(window, "document.body.firstChild")) {} 
    * instead of 
    * if (window && window.document && window.document.body && window.document.body.firstChild) {} 
    */ 
    function assertChain(obj, path) { 
     var o = obj, 
      ret = ("object" === $.type(obj) && "string" === $.type(path)); 

     if (ret) { 
      $(path.split(".") || {}).each(function(ignore, value) { 
       ret = value in o; 
       if (ret) { 
        o = o[value]; 
       } 
       return ret; 
      }); 
     } 
     return ret; 
    } 

    var t = assertChain(dataItem, "dataItem.openSocial.embed.context.connectionsContentUrl") && dataItem.openSocial.embed.context.connectionsContentUrl; 

    dataItem.xcc = dataItem.xcc || {}; //Access it 

를 I 이 항목을 찾았습니다.

var isDefined = function(value, path) { 
    path.split('.').forEach(function(key) { value = value && value[key]; }); 
    return (typeof value != 'undefined' && value !== null); 
}; 

var t = {a: {a1: 33, a12: {aa1d: 444, cc: 3}}, b: 00}; 

var results = ''; 
['a.a12.cc', 'a.a1.cc'].forEach(function(path) { 
    results += 't[' + path + '] = ' + isDefined(t, path) + '\n'; 
}); 

document.body.appendChild(document.createElement('pre')).textContent = results; 

어느 쪽이 최선입니까?

+0

"최고"는 무엇을 의미합니까? –

+0

나는 3 자 진술이라고 말해야 만합니다. – Rajesh

+0

질문이 명확하지 않지만 '시도 잡기'를 사용할 수 있습니다. 'var a = null; {a = el.openSocial.embed.context.openSocial.connections.generator.displayName} catch (예) {a = ''}'를 시도하십시오. 또한 개선 목적 만있는 경우 [CodeReviews] (http://codereview.stackexchange.com/)가 올바른 위치에 있습니다. – Rajesh

답변

0

위의 코드는 약간 개선되었습니다.

내 함수는 주어진 경로 속성 인 undefined을 반환합니다. undefined가 발견되면 더 많은 것은 인 무엇, 그것은 반복을 중지 코드에

const assertProperty = (object, path) => { 
 
    if(typeof object !== 'object' || typeof path !== 'string') 
 
    return 
 
    
 
    let scrap = object 
 
    
 
    path.split('.').every((part) => scrap = scrap[part]) 
 
    
 
    return scrap 
 
} 
 

 
let test = { 
 
    a: { 
 
    b: { 
 
     c: { 
 
     d : { 
 
      e: {} 
 
     } 
 
     } 
 
    } 
 
    } 
 
} 
 

 
console.log(assertProperty(test, 'a.b.c.d')) 
 

 
console.log(assertProperty(test, 'a.b.c.d.e.f.g'))

(대해 forEach를 반복하는 경로 배열의 끝을 전까지 계속됩니다), 당신은 그것을 좋아 사용할 수 있습니다

var displayName = assertProperty(el, 'openSocial.embed.context.openSocial.connections.generator.displayName') || ''