2010-12-15 2 views
2

이 폐쇄 작동 :y-combinator를 사용하여이 클로저에 대한 객체 참조를 가져올 수 있습니까?

var o = { 
    foo: 5 
}; 

o.handler = function(obj){ 
    return function() { 
     alert(obj.foo); 
    }; 
}(o); 

o.handler(); //alert('5') 

는 아마도 Y-콤비 동작과 유사 뭔가, 인라인 핸들러를 정의 할 수있다? 학문적 호기심

var o = { 
    foo: 5, 
    handler: function(obj){ 
     return function() { 
      alert(obj.foo); 
     }; 
    }(o); //pointer to o? ----------------------------- 
}; 

, 내가 생산 코드에서이 작업을 수행하려고하고 있지 않다

intro to the y-combinator

답변

1

아니,이 때문에 객체 리터럴의 정의시, 불가능하다, 변수 o은 정의되지 않았으며 정의시 this 참조는 o을 참조하지 않습니다.

외부 함수에서 this에 대한 임시 참조를 사용하고이를 클로저에 전달하면 작동하지만 오브젝트를 전달하지 않아서 foo 속성을 가져올 수 없습니다. o가 정의되어 있지대로를 참조 할 때, 당신의 접근 방식도 가능하지 않다,

var o = { 
    foo: 5, 
    handler: function() { 
     alert(this.foo); 
    } 
}; 

실제로 ... 방법을 많이 쉽게 :

var o = { 
    foo: 5, 
    handler:function(){ 
     var self = this; 
     return function() { 
      alert(self.foo); 
     }; 
    } 
}; 

var h = o.handler(); 
h(); 
+0

'항상'(바로 그 중 하나가 아닙니다) –

+1

@pst 맞습니다.이 경우에는 '창'을 참조 할 것입니다. –

0

당신은 여기 this 키워드를 사용할 수 있습니다 그것.

+1

그러나 이것은 handler가 다른 수신기에서 호출되거나 (콜백으로 전달되는 경우) 'this'가 다를 수있는 것과 똑같이 * 동일하지 않습니다. –

1

객체 리터럴 과 함께 자체적으로과 같이 다른 사람이 지적한 것처럼 불가능합니다. 그러나 프로세스를 래핑 할 수 있습니다. Wether이든 아니든 "무엇이든 추가"는 논쟁의 여지가 있습니다. 이것은 Y-Combinator (아마도 그것의 절반)와 같지 않습니다. 왜냐하면 "재귀 적 이름"을 부여하려고하지 않기 때문입니다 (Y-Combinators가 일류 함수와 클로저 또는 시뮬레이션 방법).

function bindMany (dict, res) { 
    res = res || {} 
    for (var k in dict) { 
    if (dict.hasOwnProperty(k)) { 
     var v = dict[p] 
     res[k] = v instanceof Function ? v(res) : v 
    } 
    } 
    return res 
} 

var o = bindMany({ 
    foo: 5, 
    handler: function(obj){ 
    return function() { 
     alert(obj.foo) 
    } 
    } 
}) 

는 테스트하지,하지만 수행 될 수 있다는 접근 방식을 보여줍니다. 여기에 미묘한 문제가 있으며 프로토 타입 체인이 dict/res (있는 경우) - 독자의 연습 문제입니다.

해피 코딩.