문서의 이전 판입니다!
원칙적으로 말해서 JS에는 class는 존재하지 않는다. 단지, 생성자 함수만 존재할 뿐이다.
아래는 Pet 이라는 클래스를 생성한다.
function Pet(name) { this.name = name; // name 필드 생성 } Pet.prototype.age = 0; // age 필드 생성 // toString 메소드 생성 Pet.prototype.toString = function() { return "Pet name : " + this.name + ", age : " + this.age; } var mong = new Pet("mong"); // 객체 생성 mong.age = 6; alert(mong);
상속할 때 중요한 부분은 Dog.prototype = new Pet()
과 Dog.prototype.constructor = Dog
부분이다.
// 위에서 이어서, Pet을 상속하는 Dog 생성 function Dog(name, age, breed) { Pet.call(this, name); this.age = age; this.breed = breed; } // Dog.prototype이 Pet.prototype으로부터 상속하도록 한다. Dog.prototype = new Pet(); // Pet 함수를 가리키는 생성자를 Dog 함수를 가리키도록 변경한다. Dog.prototype.constructor = Dog; // toString() 메소드 오버라이드 Dog.prototype.toString = function() { // 필요할 경우 부모클래스 메소드도 호출 가능 return "Dog " + Pet.prototype.toString.call(this) + ", breed : " + this.breed; } var miro = new Dog("Miro", 7, "Pomeranian"); alert(miro); alert("Is miro a Dog? " + (miro instanceof Dog)); alert("Is miro a Pet? " + (miro instanceof Pet)); alert("Is miro an Object? " + (miro instanceof Object));
JavaScript does not need classes를 참조하였다.
this.field
로 필드 값을 읽으면 된다.var jane = { name: "Jane", describe: function() { return "Person called " + this.name; } }; console.log(jane.describe()); // Person called Jane
var PersonProto = { describe: function () { return "Person called "+this.name; } }; var jane = { __proto__: PersonProto, name: "Jane" }; var tarzan = { __proto__: PersonProto, name: "Tarzan" }; console.log(jane.describe()); console.log(tarzan.describe());
Class 객체의 method는 원칙적으로 this가 객체를 가리켜야 하지만, 이벤트 핸들러로 등록되면 이벤트를 발생시킨 객체를 this로 가지게 되는 현상이 발생한다. 이 문제를 해결하려면 Class methods as event handlers in javascript? - Stack Overflow에 나온 방법을 사용해야 한다.
ClickCounter = function(buttonId) { this._clickCount = 0; var that = this; document.getElementById(buttonId).onclick = function(){ that.buttonClicked() }; } ClickCounter.prototype = { buttonClicked: function() { this._clickCount++; alert('the button was clicked ' + this._clickCount + ' times'); } }
핵심은 이벤트 핸들러를 등록할 때 this를 that으로 매핑하고, that.buttonClicked()
를 호출하도록 function()으로 감싸는 부분이다. 이렇게 하면 클래스 메소드에서는 this
를 원래 객체를 가리키는 것으로써 온전하게 사용할 수 있다.
setInterval과 setTimeout에서도 DOM 이벤트 바인딩과 동일한 원리가 적용된다.
var A = function(v) { this.value = v; this.intervalId = null; }; A.prototype.load = function() { console.log(new Date() + " : " + this.value); }; A.prototype.start = function() { var that = this; this.intervalId = setInterval(function() { that.load(); }, 2000); }; A.prototype.stop = function() { clearInterval(this.intervalId); }; var a = new A('hello'); a.start(); //... after a minute a.stop();
위에서 A.prototype.start
함수를 보면된다.