2011-01-14 3 views
46

기본적으로 세 개의 숫자 값을 포함 할 수있는 Vector 클래스를 만들고 있습니다. 그러나 이러한 벡터에서 많은 작업을 수행 할 수 있습니다. 크기를 늘리거나 다른 벡터를 더하거나 뺍니다.프로토 타입을 사용해야합니까?

이 함수를 Vector 클래스의 프로토 타입 함수로 코딩해야하는지 아니면 생성자에서 정의해야하는지 궁금합니다.

이러한 두 가지 방법 중 어느 것이 더 낫습니까? 당신이 프로토 타입이 작동하지 않을 것 "개인"변수로 X, Y, Z를 추적 할 경우

function Vector3D(x, y, z) { 
    this.x = x; 
    this.y = y 
    this.z = z; 
} 

Vector3D.prototype.magnitude = function() { 
    return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); 
}; 

또는

function Vector3D(x, y, z) { 
    this.x = x; 
    this.y = y; 
    this.z = z; 

    this.magnitude = function() { 
     return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); 
    }; 
} 

답변

49

이것은 정확히 프로토 타입을 사용하는 상황입니다.

  1. 기능이 생성되지 않습니다 여러 번 : 나는 이렇게 두 가지 주요 이점을 참조하십시오. 생성자 내부에서 함수를 정의하면 정의 된 각 함수에 대해이 호출 될 때마다 이라는 새로운 익명 함수가 만들어집니다. 프로토 타입은 정적 객체이며 Vector3D의 각 인스턴스는 간단히 참조 프로토 타입 함수입니다.
  2. 프로토 타입은 쉽게 조작 할 수있는 단일 개체입니다. 이것은 큰 유연성을 제공합니다. 불행히도이 기능을 제공 할 수있는 몇 가지 예를 제공 할 수 있습니다.
    1. 예를 들어 Vector3DSpecial과 같은 하위 클래스를 만들려면 Vector3D.prototype을 복제하고이를 Vector3DSpecial.prototype에 할당하면됩니다. Vector3DSpecial.prototype = new Vector3D();으로 생성자를 사용하여이 작업을 수행 할 수 있지만 생성자는 간단한 프로토 타입 할당에서 실행되는 부작용을 포함 할 수 있으므로 피해야합니다. 프로토 타입을 사용하면 프로토 타입의 특정 함수 만 선택하여 새 클래스에 복사 할 수도 있습니다.
    2. Vector3D에 메서드를 추가하는 것은 프로토 타입에 속성을 추가하는 것일뿐 아니라 코드를 여러 파일로 더 쉽게 분할/구성하거나 코드의 다른 부분에 메서드를 동적으로 추가 할 수 있습니다. 물론 생성자와 프로토 타입을 통해 메서드를 추가하는 방법을 조합 할 수는 있지만 일관성이없고 트랙을 더 복잡하게 만들 수 있습니다.

언제 하지 사용 프로토 타입 것? 싱글 톤 객체의 경우 (예 : 페이지와 상호 작용하고 다른 객체에 작업을 위임 할 수있는 컨트롤러). 전역 "알림"객체는 그러한 예입니다. 여기서 확장은 거의 일어나지 않으며 객체는 한 번만 만들어져 프로토 타입을 추가 (개념적) 복잡성으로 만듭니다.

8

프로토 타입 방법은, 공용 속성에 대해 작동합니다.

개인/내부 변수에서만 작동하는 메서드가 필요할 수 있기 때문에 후자를 사용 하겠지만 모두 문맥에 따라 다릅니다.

function Vector3D(x, y, z) { 
    // x, y, z is automatically in this scope now, but as private members. 
    this.magnitude = function() { 
     return Math.sqrt(x * x + y * y + z *z); 
    } 
} 
+1

감사합니다. x, y 및 z도 Vector3D의 인스턴스에서 추출 할 수 있어야하므로 공개되어야합니다. 이 경우 프로토 타입이 최선의 선택일까요? – pimvdb

+3

정답은 +1이지만 js의 private 항목은 pipedream이므로 프로토 타입을 선호합니다. 일반적으로 코드를 테스트 할 때 단위 테스트를 어렵게 만듭니다 .- 누가 자신을 제외하고 물건을 숨기고 있습니까? –

+0

동의합니다. 따라서 여러분은 공용 변수 만 가질 수 있습니다. Google 크롬의 개발자 도구에서 함수는 생성자를 통과해도 멤버로 표시되지만 프로토 타입에 '숨겨져 있고 x, y 및 z 만 표시된다면 더 실용적입니다. – pimvdb

0

ECMA 6 http://es6-features.org/#BaseClassAccess

class Shape { 
    … 
    toString() { 
     return `Shape(${this.id})` 
    } 
} 
class Rectangle extends Shape { 
    constructor (id, x, y, width, height) { 
     super(id, x, y) 
     … 
    } 
    toString() { 
     return "Rectangle > " + super.toString() 
    } 
} 
class Circle extends Shape { 
    constructor (id, x, y, radius) { 
     super(id, x, y) 
     … 
    } 
    toString() { 
     return "Circle > " + super.toString() 
    } 
} 

ECMA (5) 당신의 반응

var Shape = function (id, x, y) { 
    … 
}; 
Shape.prototype.toString = function (x, y) { 
    return "Shape(" + this.id + ")" 
}; 
var Rectangle = function (id, x, y, width, height) { 
    Shape.call(this, id, x, y); 
    … 
}; 
Rectangle.prototype.toString = function() { 
    return "Rectangle > " + Shape.prototype.toString.call(this); 
}; 
var Circle = function (id, x, y, radius) { 
    Shape.call(this, id, x, y); 
    … 
}; 
Circle.prototype.toString = function() { 
    return "Circle > " + Shape.prototype.toString.call(this); 
}; 
관련 문제