2013-05-25 2 views
-1
var i=0; 
var t={ 
    a:function(){ 
    this.timer=setInterval(this.b,30); 
    }, 
    b:function(){ 
    if(i++<1){ 
     console.log(this); 
    } 
    } 
}; 
t.a(); 

왜 [원형 개체가 전역으로] 나왔습니까? 나는 이것을 '원한다'라는 말은 객체를 의미합니다. t;자바 스크립트에서 범위가있는 SetInterval

어떻게받을 수 있습니까?

var i=0; 
var t={ 
    a:function(){ 
    var that=this; 
    this.timer=setInterval(function(){ 
     that.b(); 
    },30); 
    }, 
    b:function(){ 
    if(i++<1){ 
     console.log(this); 
    } 
    } 
}; 
t.a(); 
+3

그래서 문제를 해결하는 방법을 알고 있다면 ... 왜 묻는거야? – migg

+1

@migg 이유를 알고 싶습니다. – Fakefish

+0

* 문맥 * (thisArg)와 [변수] * 범위 * – Bergi

답변

2
당신은 Function.prototype.bind을 사용하거나 필요

또는 Function.prototype.call 이런 방식이라고하는 기능이 그것의 상실과 같은 상황을 다시 할당하기 :

내가이 문제를 해결하는 방법을 알고는, 아래의 코드는 바로 결과입니다 글로벌 범위에 대한 컨텍스트 이 가장 쉽게 귀하의 경우 솔루션의 몇 가지 예는 다음 예에서

// bind 
function scopedInterval(func, delay, context) { 
    return window.setInterval(func.bind(context), delay); 
} 
// or call 
function scopedInterval(func, delay, context) { 
    return window.setInterval(function() {func.call(context);}, delay); 
} 

, 당신은 즉, 3 매개 변수로

this을 통과하려는 다음의 예 여기

o = { // an object 
    foo: 1, 
    bar: function() { // function assuming `this` is `o` 
     return this.foo; 
    } 
}; 
f = o.bar; // function `f` loses scope of `o` 
o.bar(); // 1,   o.foo is defined 
f();  // undefined, window.foo is undefined 

에 관찰된다

this.timer = scopedInterval(this.b, 30, this); 

이렇게하지 않으면, setInterval의 맥락은 0입니다 크록 포드는 그의 놀라운 책에서 말했듯이

+0

을 혼동하지 마십시오. 이유는 무엇인지 설명하지 않고 – Fakefish

+0

을 이해합니다. 그리고 그것이 언어의 버그이기 때문에 그 이유가 있습니다. –

+1

@ 지오. 내가 당신의 대답을 +1 할 수없는 유일한 이유는 (당신이 당신의 코멘트에서 반복 할 때) 당신은 "그것은 언어의 버그"라고 말합니다. 그건 의견이고, _JavaScript_는 '이'가 이러한 경우에 어떻게 작동해야하는지에 대한 어리석은 정의를 가지고 있으며, "버그 사람들"일지도 모릅니다. 나는 그것을 "버그"라고 생각하지 않습니다. –

0

을(window.setInterval 그래서 내가 이것을 잊지 마세요 나는 항상 호출) : "Javascript를 : 좋은 부품"

함수의 자산이 아닌 경우 객체 인 경우 함수로 호출됩니다 ([setInterval의 경우]). 이 패턴을 사용하여 함수를 호출하면 'this'가 전역 객체에 바인딩됩니다. 이것은 언어의 디자인에서 실수였습니다. 언어가 올바르게 설계 되었다면 내부 함수가 호출 될 때 'this'는 여전히 외부 함수의 'this'변수에 바인딩됩니다. 이 오류의 결과는 'this'가 잘못된 값에 바인딩되어 있으므로 내부 함수가 메서드에 대한 메서드 액세스를 공유하지 않기 때문에 메서드가 내부 함수를 사용하여 작업을 수행 할 수 없다는 것입니다. [그럼 당신이 발견 한 해결 방법에 대해 이야기합니다.],

이것이 작동하지 않는 이유가 궁금합니다. 다른 모든 대답은이 문제를 제대로 해결하지 못합니다. 사실 그것은 비합리적이며 크로포드 (Crockford)는 언어 디자인에서 실수라고 말하면서 매우 혼란 스러울 수 있습니다.

+0

감사합니다. 나는 그 책을 이미 읽지 않았으며 언젠가는 놀라운 책을 읽는 것을 끝 마칠 것입니다! – Fakefish

+0

Crockford는'this'가 전역 객체를 참조해서는 안되는 것을 고쳤지만'this'가 함수가 인스턴스화 될 때 어휘 적으로 둘러싸 이는 범위를 가리키는 것이라면 모든 종류의 이상하게 보일 것이라고 생각합니다. – Pointy

+0

@Pointy 왜 그런 생각을 할 수 있습니까? –

관련 문제