2011-12-02 5 views
3

나는 개체의 집합을 가지고 있고 나도어떻게 가상 객체 캐시를 만들 수 있습니까?

  • 빌드에 새 개체 나
  • 로드 기존 객체를 동일한 구문을 사용할 수 있어야합니다.

나는 개체와 개체를 사용하여 만든 컨텍스트를 사용하고이 데이터를 사용하여 개체가 이전에 만들어 졌는지 확인하는 "캐시"를 만들었습니다. 예를 들어, 내가 theObject = new myObject(param1, param2)을 빌드하면, 캐시는 오브젝트를 { obj: theObject, context: { param1: param1, param2: param2 } }으로 저장하고, param1param2의 동일한 값을 갖는 컨텍스트를 제공하면 다시로드됩니다.

myObject = function(param1, param2) { 
    var context = { param1: param1, param2: param2 }; 
    var cacheHit = this.cache.find(context); 

    if (cacheHit) return cacheHit; // <-- Doesn't work :(

    this.param1 = param1; 
    this.param2 = param2; 
    this.cache.save(this, context); 
}; 

myObject.prototype = { cache: new myCacheObject }; // Shared cache in all instances 

는 슬프게도, 나는 new 키워드가 나는 return 문을 사용할 수 없다는 것을 의미 배운 :

은 내가 영리 당하고과 같은 객체를 구축 할 수있을 것이라고 생각했다. 캐시 컬렉션을 내부화하여 내장 된 캐시없이 비슷한 개체를 만들 수 있으며 동일한 작업을 수행 할 수 있습니다. 그러나 나는 new 키워드로이 작업을 수행 할 수 있다고 생각하지 않습니다.

어떻게해야합니까?

업데이트는 :

그것은이 방법이 실제로 일을한다는 것을 밝혀 내 문제는 (이 자바 스크립트 상속 특히 때문에) 상속에 따른되었다. 이 객체를 확장 할 때, 나는 다음과 같은 구문을 사용 : 값을 반환하는 아이를 강제 할 수없는 부모의 생성자를 호출하기 때문에

myObject = function(param1, param2) { 
    if (arguments.length) { 
    var context = { param1: param1, param2: param2 }; 
    var cacheHit = this.cache.find(context); 

    if (cacheHit) return cacheHit; 

    this.param1 = param1; 
    this.param2 = param2; 
    this.cache.save(this, context); 
    } 
}; 

// Extended from myObject 
anotherObject = function(foo, bar) { 
    // Call parent constructor 
    myObject.call(this, foo, bar); 
}; 

anotherObject.prototype = new myObject; 
anotherObject.prototype.constructor = anotherObject; 

을, 아이는 명시 적를 의미한다.

anotherObject = function(foo, bar) { 
    return myObject.call(this, foo, bar); 
}; 

희망, 내가 자식 클래스 생성자에서 아무것도 수행하는 경우, 이후이 일을 깨끗한 방법으로 가지고 올 수, 나는 값이 반환 된 경우 항상 확인해야합니다.

anotherObject = function(foo, bar) { 
    var possibleCacheHit = myObject.call(this, foo, bar); 
    if (possibleCacheHit) return possibleCacheHit; 

    // Do stuff 
}; 
+2

'.find '의 구현은 무엇입니까? 두 객체가 따로 생성된다면'.find'가 결과를주지 않는 이유가있을 수 있습니다 :'{}! == {}'는'true'를 반환합니다. – pimvdb

+0

오브젝트를 반복하고 값을 (재귀 적으로) 제공된 오브젝트와 비교하여 각 패스에서 오브젝트를 불일치시킵니다. – Koviko

+0

알 겠지만 정확히 "비교"되는 것은 무엇입니까? 나는 내용에 관계없이'=='/'==='가 기존 객체를 새로 생성 된 객체와 비교할 때 실패 할 것이기 때문에 묻습니다. – pimvdb

답변

4

나는 new 키워드가 나는 return 문을 사용할 수 없다는 것을 의미 배웠다.

럭키 너, that's not true. null이 아닌 오브젝트 참조 (자세한 내용은 링크 된 응답 참조)을 반환하면 new 연산자를 사용하면 실제로 원하는 것을 수행 할 수 있습니다.

var someObj = getObject("a","b"); 

캐시에서 인 myObject의 인스턴스를 반환 :

+0

어떻게 알지 못했습니까? – zzzzBov

+2

JavaScript가'****'ing이 아닙니다. _awesome_ –

+0

아, 그래서 영리 해지고있었습니다. : 3 내가 겪고있는 문제는 실제로이 객체가 아니라이 객체 자체의 상속과 관련이 있음이 밝혀졌습니다. 질문으로 업데이트로 자세히 설명하겠습니다. – Koviko

3

그냥 새로운 키워드를 사용하지 않는, 또는 적어도

var getObject = function(param, param2) { 
    var context, cacheHit, obj; 
    context = { param1: param1, param2: param2 }; 
    cacheHit = this.cache.find(context); 
    if (cacheHit) { 
    return cacheHit 
    } 

    obj = new myObject(param1, param2); 
    this.cache.save(obj, context); 
    return obj; 
} 

나중에 캐싱 기능 밖에 사용하지 마십시오 , 존재하는 경우 또는 새 것을 작성하십시오.

+0

이것은 또 다른 좋은 제안이지만 OP가 원래 가지고 있던대로'new'를 사용할 수 있습니다. –

+0

물론, 자바 스크립트에서는'new'를 사용할 필요가 없습니다. 자바 배경에서 오는 많은 사람들은 본질적으로 그것이 필요한지 여부에 관계없이 모든 객체의 생성을 위해 그것을 본능적으로 사용합니다. 또한보십시오 : http://yuiblog.com/blog/2006/11/13/javascript-we-hardly-new-ya/ –

+0

나는 의견이 맞지 않지만, 논쟁이 있습니다 : http://stackoverflow.com/a/383503/139010 및 http://stackoverflow.com/a/6375304/139010 –

관련 문제