function blah(){ var that = this; somethingThatRebindsThings( function(){ that.whatever(); }); }자바스크립트로 꽤 개발을 해본 사람이라면 누구나 이 this의 동작 방식에 대해 고민을 하게 된다. 이 고민을 하지 않아도 되는 개발을 생각해 보자. 어떻게 해야할까? 사실, 가장 쉬운 방법은 this를 사용하지 않는 방법이다. 미친소리 같은가? 그렇다면 다음을 읽어보라.
function Car(numberOfDoors){ this.numberOfDoors = numberOfDoors; this.numberOfWheels = 4; this.describe = function(){ return "I have " + this.numberOfWheels + " wheels and " + this.numberOfDoors + " doors."; } } var sportsCar = new Car(2); console.log( sportsCar.describe() );다음은 클로져를 통해서 똑같은 동작을 하는 코드이다.
function createCar(numberOfDoors){ var numberOfWheels = 4; function describe(){ return "I have " + numberOfWheels + " wheels and " + numberOfDoors + " doors."; } return { describe: describe }; } var suv = createCar(4); console.log( suv.describe() );내가 실행한 createCar 생성자는 Car 타입에 대한 모든 상태(state)와 행동(behavior)을 정의하고 오브젝트 외부에서 접근해야할 public 메서드에 대한 정보만 반환한다. 생성자 내에 다른 것들은 밖에서는 필요하지 않다, 그렇지만 클로져 덕분에 생성자와 함꼐 생성된 모든 것들이 서로에게 접근 할 수 있게 되었다. 생성자를 새로 호출한다면 생성자는 매번 상태와 행동이 모두 들어 있는 새로운 클로져를 만든다.
function createMiniVan(capacity){ var car = createCar(4); car.capacity = function(){ return "I have room for " + capacity + " passengers."; }; return car; } var miniVan = createMiniVan(7); console.log( miniVan.describe() ); console.log( miniVan.capacity() );이 예제에서 나는 Car로부터 모든 public 함수들을 상속받고 새 함수들을 가진 새로운 MiniVan 타입을 만들었다. 이 방법은 마치 Ruby나 CLOS에서의 믹스인(Mixins)과 비슷하다. 이 접근 방법의 잠재적인 단점은 sub-나 super-와 같이 내부의 상태나 행동에 접근하는 것을 허락하지 않는 다는 것이다. 그러니까 다시 말하자면 이것은, 암묵적으로 protected되어 있다는 것이다. 하지만 나는 이 protected된 접근이 오히려 더 유용하다는 아주 약간의 예시만을 보여주었다. 이제부터 더 많은 예제들을 보여주겠다.
function createOdometer(){ var mileage = 0; function increment(numberOfMiles){ mileage += numberOfMiles; } function report(){ return mileage; } return { increment: increment, report: report } } function createCarWithOdometer(numberOfDoors){ var odometer = createOdometer(); var car = createCar(numberOfDoors); car.drive = function(numberOfMiles){ odometer.increment(numberOfMiles); } car.mileage = function(){ return "car has driven " + odometer.report() + " miles"; } return car; }나의 createCarWithOdometer 생성자에 몇몇 추가적인 메서드를 구현하기 위해서 나는 odometer를 만들고 사용했다. 그리고 나는 기반이 되는 Car 인스턴스를 만들고 새로운 behavior를 인스턴스에 더했다. 결과적으로 내가 가진것은 odometer에 의해 제공되는 함수를 사용해서 Car 타입을 확장하는 새로운 타입이다. 이 모두 prototype을 사용하거나 this를 사용하지 않고 만들어진 결과이다.
최신 콘텐츠