2014-07-05 2 views
1

아래 코드에서 Mass 생성자 및 일부 메서드가 있습니다. 원래 메서드는 Mass 생성자 안에 있었지만 사용중인 메서드가 많이 있습니다. 그래서, 좀 더 체계화 된 것을 유지하기 위해서, 나는 Mass 외부의 몇몇 메소드를 제거하고 프로토 타입을 사용하여 추가했습니다.프로토 타입 메서드에서 액세스 생성자

하지만 문제가 있습니다. 나는 Massthis으로 언급 할 수 없다. 그것은 window을 말합니다.

function Mass(elm) { 
    this.getElement   = function(element) { 
     if (typeof element == "string") { 
      return document.getElementById(element); 
     } 
     return element; 
    }; 
    this.elm    = this.getElement(elm); 
    this.elm.style.position = "absolute"; 
    this.elm.style.left  = 0 + "px"; 
    this.elm.style.top  = 0 + "px"; 
    this.updateVars   = function() { 
      this.width  = parseInt(this.elm.style.width, 10); 
      this.height  = parseInt(this.elm.style.height, 10); 
      this.top  = parseInt(this.elm.style.top, 10); 
      this.left  = parseInt(this.elm.style.left, 10); 
      this.radius  = this.width/2; 
      this.originX = this.left + this.radius; 
      this.originY = this.top + this.radius; 
      this.worldOrgX = this.originX + parseInt(this.elm.parentNode.style.left, 10); 
      this.worldOrgY = this.originY + parseInt(this.elm.parentNode.style.top, 10); 
    }; 
} 

Mass.prototype = { 
    // other methods here 
    rotation : { 
     // this = window 
     mass : this, 
     angle : 0, 
     handler : null, 
     rotate : function (angularVelocity, rotationSpeed) { 
        this.angle = (this.angle + angularVelocity) % 360; 
        // here I need to access Mass.elm and apply rotate 
        this.mass.elm.style.webkitTransform = "rotate(" + this.angle + "deg)"; 
       }, 
     start : function (angularVelocity, rotationSpeed) { 
        var rotation = this; // this = Mass.rotation 
        rotation.handler = setInterval(function() { 
         rotation.rotate(angularVelocity, rotationSpeed); 
        }, rotationSpeed); 
       }, 

    }, 
} 

var earth = new Mass("earth"); 
//earth.rotation.start(4.5, 25); 

Fiddle

Old version of the code.

이 잘 노력하고 있습니다. 새로운 제품을 만들기 위해서는 어떤 변화를 가져야합니까?

+0

[JavaScript 프로토 타입 기능에서 "this"에 대한 참조를 유지함] (http://stackoverflow.com/questions/2025789/preserving-a-reference-to-this-in-javascript) -prototype-functions). –

+1

그 순간에 인스턴스를 만들지 않았다면 '이'가 '미사'의 인스턴스를 나타낼 것이라고 생각하게 만들었습니까? 'this'는별로 복잡하지 않습니다. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this –

+0

@PM 약간 다른 문제입니다. 질량에는 회전과 연산이 있습니다. 회전에서 매스 인스턴스를 알아야합니다. 이 회전의 값은 회전 (호출하는 객체)이 될 것이지만 op는 거기에서 Mass 인스턴스를 얻는 방법을 모릅니다. – HMR

답변

1

프로토 타입은 생성자 내부의 코드를 작게 만드는 것이 아닙니다. 프로토 타입은 공통 기능을 공유하기위한 것입니다. 예를 들어 getElement 방법은 Mass의 모든 인스턴스에 대해 동일합니다. 따라서 프로토 타입에 배치하는 것이 이상적입니다. updateVars와 동일합니다.

반면에 this.rotation은 개체이며 기능이 아닙니다. Mass의 모든 인스턴스에는 다른 this.rotation 속성이 있습니다. 따라서 this.rotation은 공유 할 수 없으므로 프로토 타입에 넣을 수 없습니다.

나는 일반적으로 간단 defclass 기능을 사용하여 자바 스크립트에서 "클래스"를 만들려면 :

function defclass(prototype) { 
    var constructor = prototype.constructor; 
    constructor.prototype = prototype; 
    return constructor; 
} 

defclass 함수는 프로토 타입을 펼쳤다와 생성자를 반환합니다. 그건 그렇고, 생성자는 프로토 타입의 또 다른 메소드 일뿐입니다.

var Rotation = defclass({ 
    constructor: function (mass) { 
     this.mass = mass; 
     this.angle = 0; 
    }, 
    start: function (angularVelocity, delay) { 
     var rotation = this; 

     setInterval(function() { 
      rotation.rotate(angularVelocity); 
     }, delay); 
    }, 
    rotate: function (angularVelocity) { 
     var angle = this.angle = (this.angle + angularVelocity) % 360; 
     var transform = "rotate(" + angle + "deg)"; 
     var style = this.mass.element.style; 

     style.webkitTransform = transform; 
     style.mozTransform = transform; 
     style.msTransform = transform; 
     style.oTransform = transform; 
     style.transform = transform; 
    } 
}); 

마지막으로 우리는 단순히 Mass의 인스턴스를 생성하고 회전합니다 : 우리는 Rotation 클래스를 생성

var Mass = defclass({ 
    constructor: function (id) { 
     var element = this.element = this.getElement(id); 
     var style = element.style; 

     style.position = "absolute"; 
     style.left = 0; 
     style.top = 0; 

     this.rotation = new Rotation(this); 
    }, 
    getElement: function (id) { 
     if (typeof id !== "string") return id; 
     else return document.getElementById(id); 
    } 
}); 

다음 : 그래서 여기

내가 당신 Mass 클래스를 재 작성 할 방법

var earth = new Mass("earth"); 
earth.rotation.start(4.5, 25); 

직접 데모보기 : http://jsfiddle.net/NL3SJ/

+0

내가 제안한 방법을 정확하게 사용하지는 않았지만 문제를 해결하는 데 도움이되었습니다. 그것은 몇 가지를 정리했다.학급 기간은 나를 조금 겁나게한다. 이전에 C#으로 몇 가지 응용 프로그램을 만들었지 만 아직 익숙하지는 않습니다. 어쨌든, 나는 지금 미사에 접근 할 수 있으며, 코드는 좀 더 조직적으로 보인다. 고맙습니다. [** Fiddle **] (http://jsfiddle.net/TLzYe/4/) – akinuri