2009-07-17 3 views
6

방금 ​​jquery를 사용하기 시작했으며 선택기를 사용하여 정말 즐겁습니다. 관용구가 객체 트리 (예 : JSON 쿼리 결과)를 트래버스하는 아주 좋은 방법이라고 생각합니다. 나는이 같은 객체가있는 경우 예를 들어, :DOM 요소 대신 일반 자바 스크립트 객체 용 jquery 선택기

var obj = { 'foo': 1, 'bar': 2, 
      'child': { 'baz': [3, 4, 5] } 
      }; 

나는 $ 같은 것을 쓸 수 싶어요 ('아이 바즈을 : 마지막으로', OBJ) 나는 체인을 인식 5.하지 않을 수 하지만 여전히 선택 연산자가 좋을 것 같습니다. 그런 짐승이 있는지, 아니면 가장 쉬운 방법으로 짐을 쓴다는 것은 누구나 알 수 있습니까?

last = obj.child.baz.slice(-1)[0]; 

몇 가지 다른 예 :

+0

에 의해 루프에게 다음을 jQuery로 요소를 포장하는 것입니다 -1]; ? –

+0

이 장난감 예제에서는 효과가 있지만 더 깊은 나무와 큰 개체는 빠르게 분해됩니다. 예를 들어, 네트워크 패킷을 나타내는 트리를 사용하는 프로그램에서 작업하고 있는데 도달 할 수없는 패킷에 대한 ICMP 프레임을 얻기 위해 $ ('icmp [code = UNREACHABLE]', packetlist)를 작성하고 싶습니다. – brendan

답변

5

다음은 jQuery 자체가 객체에서 작동하도록하기위한 개념 증명 구현입니다. 객체 래퍼 (FakeNode)을 통해, 당신은 사용에 jQuery를 속일 수 내장 된 일반 자바 스크립트 객체에 선택 엔진 (지글 지글) :

function FakeNode(obj, name, parent) { 
    this.obj = obj; 
    this.nodeName = name; 
    this.nodeType = name ? 1 : 9; // element or document 
    this.parentNode = parent; 
} 

FakeNode.prototype = { 
    documentElement: { nodeName: "fake" }, 

    getElementsByTagName: function (tagName) { 
     var nodes = []; 

     for (var p in this.obj) { 
      var node = new FakeNode(this.obj[p], p, this); 

      if (p === tagName) { 
       nodes.push(node); 
      } 

      Array.prototype.push.apply(nodes, 
       node.getElementsByTagName(tagName)); 
     } 

     return nodes; 
    } 
}; 

function $$(sel, context) { 
    return $(sel, new FakeNode(context)); 
} 

및 사용은 다음과 같습니다

var obj = { 
    foo: 1, 
    bar: 2, 
    child: { 
     baz: [ 3, 4, 5 ], 
     bar: { 
      bar: 3 
     } 
    } 
}; 

function test(selector) { 
    document.write("Selector: " + selector + "<br>"); 

    $$(selector, obj).each(function() { 
     document.write("- Found: " + this.obj + "<br>"); 
    }); 
} 

test("child baz"); 
test("bar"); 

주는 일 출력 :

물론
 
Selector: child baz 
- Found: 3,4,5 
Selector: bar 
- Found: 2 
- Found: [object Object] 
- Found: 3 

, 당신은 더 복잡한 선택기를 지원하기 위보다 훨씬 더 구현해야 할 것이다.

나는 너 jLinq을 보았습니까?

+0

그것은 매우 귀엽다, 고마워! 그리고 jLinq도 보지 못했습니다. – brendan

+0

이것은 매우 흥미로운 대답입니다. – ken

0

배열 객체가 사용할 수있는 몇 가지 방법이 잘

first = obj.child.baz.slice(0,1)[0]; 
allExceptFirst = obj.child.baz.slice(1); 
allExceptLast = obj.child.baz.(0,-1); 
+0

감사합니다. 예, 지금 제가하는 일입니다. 그러나 선택자는 내 생각에 훨씬 더 강력합니다. 재미있는 요소를 찾기 위해 걷고있는 특정 객체의 정확한 모양을 알 필요가 없기 때문입니다. 나는 jquery가 html.body.table [1] .tr을 만들지 않는 좋은 이유가 있다고 생각한다. – brendan

0

을, 나는 순수한 개체 액세스가 jQuery를 같은보다 더 보이는 말할 개인적 것 검색어. 깔끔한 것 중 하나는 슬라이싱 및 기타 필터링 기술입니다.

당신이 정말로 개체 액세스 쿼리 경기하기를 원했지만 경우, 다음과 같은 몇 가지 가능성 (XPath를 생각하는) 것 :하지만 결국

var obj = { 
    foo: 1, 
    bar: 2, 
    child: { 
     foo: { 
      baz: [3, {a: 1}, {a: 2, b: 3}]}, 
     bar: { 
      baz: [42, {a: 123}, {a: -1}]}, 
     baz: null}}; 

// Implicitly start in the Global object, unless a context is provided. 
// Keys in JavaScript objects are essentially stored in order (not valid for 
// *all* flavors, but it's close to standard. So you could do slicing on keys.) 

// Selects (does not return them) 
// obj.child.foo.baz[1].a 
// obj.child.foo.baz[2].a 
// obj.child.bar.baz[1].a 
// obj.child.bar.baz[2].a 
// Then performs an aggregate that returns value 125. 
$('obj.child[:2].baz[1:].a').sum() 

// Selects obj.foo, obj.bar, obj.child.foo.baz[0] and obj.child.bar.baz[0] 
$('obj *[typeof(number)]') 

// Selects obj.foo and obj.child.foo 
$('obj foo') 

// Other possible methods: delete(), set(), get() (as an array of values), 
// min(), max(), avg(), merge() etc etc. 

, 나는 이것이 매우 유용 표시되지 않습니다. 하지만 어쩌면 = 같은 생각입니다.)

0

간단하고 쉬운 방법은 당신이 obj.child.baz 싫어하는 이유 [obj.child.baz.length가 각

var obj = { 'foo': 1, 'bar': 2, 
     'child': { 'baz': [3, 4, 5] } 
     }; 

$(obj).each(function(){ 
console.log(this); 
if(this.hasOwnProperty('foo')) 
{ 
    console.log("hey i found " + this.foo); 
} 
});