2014-09-29 5 views
1

함수의 싱글 톤 버전을 반환하기 위해 함수 프로토 타입을 확장하려고합니다.Function.prototype에서 "this"에 액세스 할 수 없습니까?

Function.prototype.once = function() { 
    var called = false, memo; 
    return function() { 
     console.log('AP', this); 
     if (!called) memo = this.apply(this, arguments); 
     called = true; 
     return memo; 
    } 
} 

콘솔은 창 개체를 기록합니다. 왜 이것입니다! = 현재 기능입니까? 어떻게 해결할 수 있을까요?

+2

해피 코드 워 : – Florent

답변

7

당신은 바인드 단순히 당신이 이전 var self = this 트릭에 리조트 (즉, 이상 폐쇄 될 수있는 변수에 this에 대한 참조를 얻을)하는 중 필요하므로, this "이상 종료"또는 수 없습니다 귀하의 기능 :

return function() { 
    console.log('AP', this); 
    if (!called) memo = this.apply(this, arguments); 
    called = true; 
    return memo; 
}.bind(this); 
+1

'bind'는 올바른 접근 방식입니다. 나는 당신의 대답을 받아 들일 것입니다. 죄송합니다, @Florent,하지만 meagar가 1 초 당신보다 빠릅니다 : –

+0

IMHO,'.bind'는 잔인하며, 당신이 함수의 범위를 제어하지 않는 경우에만 사용해야합니다. 범위가 지정된 변수). 평범한 중첩 된 함수를 작성할 때 앨리어스에 대한 간단한 클로저가 더 효과적입니다. – Alnitak

4

물론 가능하지만 내부 함수가 새로운 문맥을 작성하므로 내부에 this이 외부에있는 this과 같지 않습니다.

Function.prototype.once = function() { 
    var f = this; // use 'f' in the inner function 
    ... 
} 

NB를 :

그냥 원래의 기능에 대한 외부 참조를 만들 의도에 따라 당신은 또한 arguments과 같은 문제가있을 수 있습니다.

+0

당신 말이 맞습니다. 왜 내가 이런 생각을하지 않았습니까? 하지만 나는'bind' 접근법을 더 좋아합니다 : –

+0

@BarthZalewski 그리고 어떻게'.bind'가 작동한다고 생각합니까? ;-) 또한'.bind'는'this'에 대한 여분의 참조를 막는 것보다 하나의 여분의'function'을 만드는 오버 헤드를 가지고 있습니다. – Alnitak

+0

(자세한 내용은 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind에서 polyfill을 확인하십시오. 얼마나 많은 오버 헤드'.bind'가 있는지보십시오) – Alnitak

1

익명 함수의 컨텍스트에 바인딩해야합니다.

Function.prototype.once = function() { 
    var called = false, memo; 
    return (function() { 
    console.log('AP', this); 
    if (!called) memo = this.apply(this, arguments); 
    called = true; 
    return memo; 
    }).bind(this); 
} 
관련 문제