2009-10-16 2 views
4

OOP Javascript를 처음 사용하여 this 키워드 및 이벤트에 문제가 있습니다.자바 스크립트 : 이벤트에 OOP 메소드 첨부 및 'this'키워드

내가 얻으려고하는 것은 다음과 같습니다. 여러 DOM 객체가 있고 공통 이벤트를 바인드 할뿐만 아니라 전역 컨테이너에 앞서 언급 한 객체에 대한 데이터를 보관 (런타임 성능 향상)하고 싶습니다.

function ClassThatDoesSomething() { 
    /* keeps node ids for processing in this.init */ 
    this.nodes = new Array(); 

    /* keeps processed node data for fast access */ 
    this.nodeData = new Array(); 

    this.sthAddNodes = function(/* ids */) { 
     /* appends node ids to local variable (this.nodeData) */ 
    } 

    function init() { 
     /* gathers data from all nodes that were 
      added before and stores it in this.nodeData */ 

     /* here, unsurprisingly, 'this' references the window element*/ 

     addEvent(window,'scroll',this.scroll); 
    } 

    function scroll() { 
     /* do stuff when user scrolls the page */ 

     /* 'this' references the window element here too */ 
    } 
    addEvent(window,'load',this.init); 
} 

나중에 문서 본문에

, 난 그냥이를 추가 할 수 있습니다 : 더에

var Ctds = new ClassThatDoesSomething(); 

그리고를하여 DOM 요소를 추가 :

그래서 내가하는 일은 기본적으로 이것이다

Ctds.addNodes(ids); 

구현 코드는 더 이상 필요하지 않습니다.

질문 : initscroll 방법에 JS 클래스 인스턴스에 액세스하는 방법하지창 요소.

this 키워드를 사용할 필요는 없지만 여전히 나는 아무 것도 생각 나지 않았습니다.

P.

  • addEvent은 이벤트를 첨부하는 매우 기본적인 기능으로, IE/Fx와 친숙하며 다른 기능은 없습니다.
  • 필자가 작성한 코드는 이미 기능적이지만 절차상의 형태로는 그냥 OOP했습니다.
  • 사소한 하위 질문으로서 어떻게 든 인상을 받았다. getter/setter 메서드는 자바 스크립트에서 사용하지 않는 것이 좋지만 사용하면 괜찮습니까?

답변

10

한 가지 initscroll도 인스턴스의 방법이라는 것이다.

그래서 당신은 단지로드 이벤트에 init하지 this.init을 추가해야합니다 유사

addEvent(window,'load',init); // No "this." needed 

그리고 :

addEvent(window,'scroll',scroll); 

당신이 클래스로 이동하기로 결정 (예 : this.scroll 및 않는 경우 this.init 등)에 대한 참조를 저장하면 this에 대한 참조를 저장하고 addEvent에 전달되는 익명 함수로 참조 할 수 있습니다.

var self = this; 

this.init = function() { 
    addEvent(window, 'scroll', function() { 
     self.scroll() 
    }) 
}; 

this.scroll = function() { /* ... */ }; 

addEvent(window,'load',function() { 
    self.init() 
}); 

closure이라고합니다.

+0

와우, 너무 많은 답변, 나는 압도되어, 모두에게 감사합니다. 어쨌든 방법은 정확히 어떻게 정의 될까요? (바보 같은 질문, 미안) – raveren

+0

@Raveren : 음, 큰 질문입니다. 이 코드 샘플은 crockford가 "권한있는"멤버 선언을 호출하는 예제입니다. http://www.crockford.com/javascript/private.html을 참조하십시오. 실제로 JavaScript의 OOP에 대한 고급 접근 방식입니다. 자바 스크립트에서 기본 클래스 정의를 시작하려면 여기에서 시작하십시오. http://mckoss.com/jscript/object.htm –

0

당신은 그것을 위해 클로저를 사용할 수 있습니다 : 나는 알

function ClassThatDoesSomething() { 
    var self=this; 
    // ... 

    function init() { 
     addEvent(window,'scroll',self.scroll); 
    } 
} 
+2

a) 이는 폐쇄가 아닙니다. b) 여전히 작동하지 않습니다. –

+0

그냥 'function init()'을 복사하고 this.init = function()을 만들지 않아 작동하지 않습니다. 그리고 왜 그것이 폐쇄가 아니라고 생각합니까? –

+0

또한이 클래스가 어떻게 사용되는지도 중요합니다. 적절한 코드는 'var myClassInstance = new ClassThatDoesSomething(); myClassInstance.init(); ' –

2
function MyConstructor() { 
    this.foo = "bar"; 
    var me = this; 
    function myClosure() { 
     doSomethingWith(me.foo); 
    } 
} 
-1

이 트릭은 작동합니다 :

function ClassThatDoesSomething() { 
... 
    this.This = this; 
... 
}

그런 다음 그 문제 방법 안에 당신이 'This'를 사용할 수 있습니다.

희망이 도움이됩니다.

+0

아니요, 작동하지 않습니다. – slikts

+0

'this.This = this'. 나는 이것에 대해 내 머리를 감쌀 수도 없다. –

1

this은 기능을 실행할 때까지 결정되지 않습니다. 이벤트 리스너를 연결할 때 범위가없는 함수을 전달합니다. 따라서 지정된 이벤트에서 함수는 window의 범위에서 실행됩니다. 즉 thiswindow과 같습니다. 이 마십시오

var that = this; 
... 
addEvent(window,'scroll', function() { 
    that.scroll() 
}); 
0

:

var ClassThatDoesSomething = function() { 
    /* keeps node ids for processing in this.init */ 
    this.nodes = new Array(); 

    /* keeps processed node data for fast access */ 
    this.nodeData = new Array(); 
} 

ClassThatDoesSomething.prototype.sthAddNodes = function(/* ids */) { 
     /* appends node ids to local variable (this.nodeData) */ 
    } 
} 

ClassThatDoesSomething.prototype.init = function() { 
     /* gathers data from all nodes that were 
      added before and stores it in this.nodeData */ 

     /* here, unsurprisingly, 'this' references the window element*/ 

     addEvent(window,'scroll',this.scroll); 
    } 
} 
ClassThatDoesSomething.prototype.scroll = function() { 
     /* do stuff when user scrolls the page */ 

     /* 'this' references the window element here too */ 
    } 
    addEvent(window,'load',this.init); 
} 
1

허용하는 기능 프로토 타입에 메서드를 추가 특정 범위에서 실행을 강제하려면 같은 this 동일하게 새로운 변수를 만들어 같은 트릭을 사용할 수 있습니다 당신은 어떤 개체에 어떤 기능을 바인딩 :

Function.prototype.bind = function(object) { 
    var __method = this; 
    return function() { 
     return __method.apply(object, arguments); 
    }; 
}; 

인스턴스에 이벤트 핸들러를 선언 (깔끔한 일 유지) :

function ClassThatDoesSomething() { 

    this.events = { 
    init: ClassThatDoesSomething.init.bind(this), 
    scroll: ClassThatDoesSomething.scroll.bind(this), 
    etc: ClassThatDoesSomething.etc.bind(this) 
    }; 
    ... 
} 

이제 이벤트를 참조 할 때마다 자동으로 클래스 인스턴스에 바인딩됩니다. 예 :

function init() { 
    addEvent(window,'scroll',ClassThatDoesSomething.events.scroll); 
}