í´ëì¤ë ê°ì²´ ì§í¥ íë¡ê·¸ëë°ìì í¹ì ê°ì²´ë¥¼ ìì±í기 ìí´ ë³ìì ë©ìë를 ì ìíë ì¼ì¢ ì íë¡, ê°ì²´ë¥¼ ì ìí기 ìí ìí(ë©¤ë² ë³ì)ì ë©ìë(í¨ì)ë¡ êµ¬ì±ëë¤.
ì¤ë¬´ìì ì¬ì©ìë 물건ê°ì´ ëì¼í ì¢ ë¥ì ê°ì²´ë¥¼ ì¬ë¬ ê° ìì±í´ì¼ íë ê²½ì°ê° ì¦ìµëë¤.
ì´ë´ ë new ì°ì°ìì ìì±ì í¨ììì ë°°ì´ new functionì ì¬ì©í ì ììµëë¤.
ì¬ê¸°ì ëíì¬ ëª¨ë ìë°ì¤í¬ë¦½í¸ì ëì
ë í´ëì¤(class)ë¼ë 문ë²ì ì¬ì©íë©´ ê°ì²´ ì§í¥ íë¡ê·¸ëë°ìì ì¬ì©ëë ë¤ìí 기ë¥ì ìë°ì¤í¬ë¦½í¸ììë ì¬ì©í ì ììµëë¤.
기본 문ë²
í´ëì¤ë ë¤ìê³¼ ê°ì 기본 문ë²ì ì¬ì©í´ ë§ë¤ ì ììµëë¤.
class MyClass {
// ì¬ë¬ ë©ìë를 ì ìí ì ìì
constructor() { ... }
method1() { ... }
method2() { ... }
method3() { ... }
...
}
ì´ë ê² í´ëì¤ë¥¼ ë§ë¤ê³ , new MyClass()를 í¸ì¶íë©´ ë´ë¶ìì ì ìí ë©ìëê° ë¤ì´ ìë ê°ì²´ê° ìì±ë©ëë¤.
ê°ì²´ì 기본 ìí를 ì¤ì í´ì£¼ë ìì±ì ë©ìë constructor()ë newì ìí´ ìëì¼ë¡ í¸ì¶ëë¯ë¡, í¹ë³í ì ì°¨ ìì´ ê°ì²´ë¥¼ ì´ê¸°í í ì ììµëë¤.
ìì:
class User {
constructor(name) {
this.name = name;
}
sayHi() {
alert(this.name);
}
}
// ì¬ì©ë²:
let user = new User("John");
user.sayHi();
new User("John")를 í¸ì¶íë©´ ë¤ìê³¼ ê°ì ì¼ì´ ì¼ì´ë©ëë¤.
- ìë¡ì´ ê°ì²´ê° ìì±ë©ëë¤.
- ë겨ë°ì ì¸ìì í¨ê»
constructorê° ìëì¼ë¡ ì¤íë©ëë¤. ì´ë ì¸ì"John"ì´this.nameì í ë¹ë©ëë¤.
ì´ë° ê³¼ì ì ê±°ì¹ íì user.sayHi() ê°ì ê°ì²´ ë©ìë를 í¸ì¶í ì ììµëë¤.
ì´ë³´ ê°ë°ìë í´ëì¤ ë©ìë ì¬ì´ì ì¼í를 ë£ë ì¤ì를 ì ì§ë¥´ê³¤ í©ëë¤. ì´ë ê² ì¼í를 ë£ì¼ë©´ ë¬¸ë² ìë¬ê° ë°ìí©ëë¤.
í´ëì¤ì ê´ë ¨ë í기ë²ì ê°ì²´ 리í°ë´ í기ë²ê³¼ ì°¨ì´ê° ììµëë¤. í´ëì¤ìì ë©ìë ì¬ì´ì ì¼í를 ë£ì§ ììë ë©ëë¤.
í´ëì¤ë
ì´ ìì ìì "í´ëì¤ê° ì íí ëê°ì?"ë¼ë ìë¬¸ì´ ìê¸°ì¤ ê²ëë¤. í´ëì¤ë ìë°ì¤í¬ë¦½í¸ìì ìë¡ê² ì°½ìí ê°ì²´(entity)ê° ìëëë¤.
í´ëì¤ê° ë³´ì¬ì£¼ë ë¤ìí ë§ë²ì ì리를 íëì© íí¤ì¹ë©´ì í´ëì¤ê° ì íí 무ìì¸ì§ ììë´ ìë¤. ì´ ê³¼ì ì ê±°ì¹ê³ ëë©´ ìë°ì¤í¬ë¦½í¸ì ë³µì¡í 기ë¥ì ì´í´í ì ìì ê²ëë¤.
ìë°ì¤í¬ë¦½í¸ìì í´ëì¤ë í¨ìì í ì¢ ë¥ì ëë¤.
ì½ëë¡ íì¸í´ë´ ìë¤.
class User {
constructor(name) { this.name = name; }
sayHi() { alert(this.name); }
}
// Userê° í¨ìë¼ë ì¦ê±°
alert(typeof User); // function
class User {...} ë¬¸ë² êµ¬ì¡°ê° ì§ì§ íë ì¼ì ë¤ìê³¼ ê°ìµëë¤.
Userë¼ë ì´ë¦ì ê°ì§ í¨ì를 ë§ëëë¤. í¨ì 본문ì ìì±ì ë©ìëconstructorìì ê°ì ¸ìµëë¤. ìì±ì ë©ìëê° ìì¼ë©´ ë³¸ë¬¸ì´ ë¹ìì§ ì±ë¡ í¨ìê° ë§ë¤ì´ì§ëë¤.sayHiê°ì í´ëì¤ ë´ìì ì ìí ë©ìë를User.prototypeì ì ì¥í©ëë¤.
new User를 í¸ì¶í´ ê°ì²´ë¥¼ ë§ë¤ê³ , ê°ì²´ì ë©ìë를 í¸ì¶íë©´ í¨ìì prototype íë¡í¼í°ìì ì¤ëª
í ê²ì²ë¼ ë©ìë를 prototype íë¡í¼í°ë¥¼ íµí´ ê°ì ¸ìµëë¤. ì´ ê³¼ì ì´ ì기 ë문ì ê°ì²´ìì í´ëì¤ ë©ìëì ì ê·¼í ì ììµëë¤.
class User ì ì¸ ê²°ê³¼ë¥¼ 그림ì¼ë¡ ëíë´ë©´ ìëì ê°ìµëë¤.
ì§ê¸ê¹ì§ íë ì¤ëª ì ì½ëë¡ ííí´ ë´ ìë¤.
class User {
constructor(name) { this.name = name; }
sayHi() { alert(this.name); }
}
// í´ëì¤ë í¨ìì
ëë¤.
alert(typeof User); // function
// ì ííë ìì±ì ë©ìëì ëì¼í©ëë¤.
alert(User === User.prototype.constructor); // true
// í´ëì¤ ë´ë¶ìì ì ìí ë©ìëë User.prototypeì ì ì¥ë©ëë¤.
alert(User.prototype.sayHi); // alert(this.name);
// íì¬ íë¡í íì
ìë ë©ìëê° ë ê°ì
ëë¤.
alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi
í´ëì¤ë ë¨ìí í¸ì 문ë²ì´ ìëëë¤
ì´ë¤ ì¬ëë¤ì classë¼ë í¤ìë ìì´ë í´ëì¤ ìí ì íë í¨ì를 ì ì¸í ì ì기 ë문ì í´ëì¤ë 'í¸ì 문ë²âì ë¶ê³¼íë¤ê³ ì´ì¼ê¸°í©ëë¤. ì°¸ê³ ë¡ ê¸°ë¥ì ëì¼íë 기존 문ë²ì ì½ê² ì½ì ì ìê² ë§ë 문ë²ì í¸ì 문ë²(syntactic sugar, ë¬¸ë² ì¤í)ì´ë¼ê³ í©ëë¤.
// class Userì ëì¼í 기ë¥ì íë ìì í¨ì를 ë§ë¤ì´ë³´ê² ìµëë¤.
// 1. ìì±ì í¨ì를 ë§ëëë¤.
function User(name) {
this.name = name;
}
// 모ë í¨ìì íë¡í íì
ì 'constructor' íë¡í¼í°ë¥¼ 기본ì¼ë¡ ê°ê³ ì기 ë문ì
// constructor íë¡í¼í°ë¥¼ ëª
ìì ì¼ë¡ ë§ë¤ íìê° ììµëë¤.
// 2. prototypeì ë©ìë를 ì¶ê°í©ëë¤.
User.prototype.sayHi = function() {
alert(this.name);
};
// ì¬ì©ë²:
let user = new User("John");
user.sayHi();
ì ììì²ë¼ ìì í¨ìë¡ í´ëì¤ ìí ì íë í¨ì를 ì ì¸íë ë°©ë²ê³¼ class í¤ìë를 ì¬ì©íë ë°©ë²ì ê²°ê³¼ë ê±°ì ê°ìµëë¤. classê° ë¨ìí í¸ì 문ë²ì´ë¼ê³ ìê°íë ì´ì ê° ì¬ê¸°ì ììµëë¤.
ê·¸ë°ë° ë ë°©ë²ìë ì¤ìí ì°¨ì´ê° ëª ê°ì§ ììµëë¤.
-
classë¡ ë§ë í¨ìì í¹ì ë´ë¶ íë¡í¼í°ì¸[[IsClassConstructor]]: trueê° ì´ë¦íì²ë¼ ë¶ìµëë¤. ì´ê²ë§ì¼ë¡ë ë ë°©ë²ì ë¶ëª í ì°¨ì´ê° ììì ì ì ììµëë¤.ìë°ì¤í¬ë¦½í¸ë ë¤ìí ê²½ì°ì
[[IsClassConstructor]]: true를 íì©í©ëë¤. í´ëì¤ ìì±ì를newì í¨ê» í¸ì¶íì§ ìì¼ë©´ ìë¬ê° ë°ìíëë° ì´ ë[[IsClassConstructor]]: trueê° ì¬ì©ë©ëë¤.class User { constructor() {} } alert(typeof User); // Userì íì ì í¨ìì´ê¸´ íì§ë§ ê·¸ë¥ í¸ì¶í ì ììµëë¤. User(); // TypeError: Class constructor User cannot be invoked without 'new'í´ëì¤ ìì±ì를 문ìì´ë¡ íë³ííë©´ 'classâ¦'ë¡ ììíë 문ìì´ì´ ëëë° ì´ëë
[[IsClassConstructor]]: trueê° ì¬ì©ë©ëë¤.class User { constructor() {} } alert(User); // class User { ... }ë ë¤ë¥¸ ì°¨ì´ì ë¤ì ëí´ì ê³§ ë ì´í´ë³´ê² ìµëë¤.
-
í´ëì¤ì ì ìë ë©ìëë ì´ê±°í ì ììµëë¤(non-enumerable). í´ëì¤ì
prototypeíë¡í¼í°ì ì¶ê°ë ë©ìëìenumerableíëê·¸ëfalseì ëë¤.for..inì¼ë¡ ê°ì²´ë¥¼ ìíí ë, ë©ìëë ìí ëììì ì ì¸íê³ ì íë ê²½ì°ê° ë§ì¼ë¯ë¡ ì´ í¹ì§ì 꽤 ì ì©í©ëë¤. -
í´ëì¤ë íì
ì격 모ëë¡ ì¤íë©ëë¤(use strict). í´ëì¤ ìì±ì ì ì½ë ì ì²´ì ìëì¼ë¡ ì격 모ëê° ì ì©ë©ëë¤.
ì´ ì¸ìë class를 ì¬ì©íë©´ ë¤ìí 기ë¥ì´ ë°ë¼ì¤ëë°, ìì¸í ë´ì©ì 차차 ë¤ë£¨ê² ìµëë¤.
í´ëì¤ ííì
í¨ìì²ë¼ í´ëì¤ë ë¤ë¥¸ ííì ë´ë¶ìì ì ì, ì ë¬, ë°í, í ë¹í ì ììµëë¤.
먼ì í´ëì¤ ííìì ë§ë¤ì´ë³´ê² ìµëë¤.
let User = class {
sayHi() {
alert("ìë
íì¸ì.");
}
};
ê¸°ëª í¨ì ííì(Named Function Expression)ê³¼ ì ì¬íê² í´ëì¤ ííììë ì´ë¦ì ë¶ì¼ ì ììµëë¤.
í´ëì¤ ííìì ì´ë¦ì ë¶ì´ë©´, ì´ ì´ë¦ì ì¤ì§ í´ëì¤ ë´ë¶ììë§ ì¬ì©í ì ììµëë¤.
// 기ëª
í´ëì¤ ííì(Named Class Expression)
// (ëª
ì¸ìì ìë ì©ì´ì´ì§ë§, 기ëª
í¨ì ííìê³¼ ì ì¬íê² ëìí©ëë¤.)
let User = class MyClass {
sayHi() {
alert(MyClass); // MyClassë¼ë ì´ë¦ì ì¤ì§ í´ëì¤ ìììë§ ì¬ì©í ì ììµëë¤.
}
};
new User().sayHi(); // ìíëëë¡ MyClassì ì ì를 ë³´ì¬ì¤ëë¤.
alert(MyClass); // ReferenceError: MyClass is not defined, MyClassë í´ëì¤ ë°ìì ì¬ì©í ì ììµëë¤.
ìëì ê°ì´ âíìì ë°ë¼â í´ëì¤ë¥¼ ëì ì¼ë¡ ìì±íë ê²ë ê°ë¥í©ëë¤.
function makeClass(phrase) {
// í´ëì¤ë¥¼ ì ì¸íê³ ì´ë¥¼ ë°íí¨
return class {
sayHi() {
alert(phrase);
};
};
}
// ìë¡ì´ í´ëì¤ë¥¼ ë§ë¦
let User = makeClass("ìë
íì¸ì.");
new User().sayHi(); // ìë
íì¸ì.
getterì setter
리í°ë´ì ì¬ì©í´ ë§ë ê°ì²´ì²ë¼ í´ëì¤ë getterë setter, ê³ì°ë íë¡í¼í°(computed property)를 ì§ìí©ëë¤.
getê³¼setì ì´ì©í´ user.nameì ì¡°ìí ì ìê² í´ë´
ìë¤.
class User {
constructor(name) {
// setter를 íì±íí©ëë¤.
this.name = name;
}
get name() {
return this._name;
}
set name(value) {
if (value.length < 4) {
alert("ì´ë¦ì´ ë무 ì§§ìµëë¤.");
return;
}
this._name = value;
}
}
let user = new User("ë³´ë¼");
alert(user.name); // ë³´ë¼
user = new User(""); // ì´ë¦ì´ ë무 ì§§ìµëë¤.
ì°¸ê³ ë¡ getterì setterë User.prototypeì ì ìë©ëë¤.
ê³ì°ë ë©ìë ì´ë¦ [â¦]
ëê´í¸ [...]를 ì´ì©í´ ê³ì°ë ë©ìë ì´ë¦(computed method name)ì ë§ëë ìì를 ì´í´ë´
ìë¤.
class User {
['say' + 'Hi']() {
alert("Hello");
}
}
new User().sayHi();
ê³ì°ë ë©ìë ì´ë¦ì 리í°ë´ ê°ì²´ì ì ì¬í íí를 ë 기 ë문ì ì¬ì©ë²ì ì¸ì°ê¸° ì½ë¤ë ì¥ì ì´ ììµëë¤.
í´ëì¤ íë
í´ëì¤ íëë ìµê·¼ì ëí´ì§ 기ë¥ì ëë¤.
ì§ê¸ê¹ì§ ì´í´ë³¸ ììì ë©ìëê° íëë§ ìììµëë¤.
'í´ëì¤ íë(class field)'ë¼ë 문ë²ì ì¬ì©íë©´ ì´ë¤ ì¢ ë¥ì íë¡í¼í°ë í´ëì¤ì ì¶ê°í ì ììµëë¤.
í´ëì¤ Userì name íë¡í¼í°ë¥¼ ì¶ê°í´ë´
ìë¤.
class User {
name = "ë³´ë¼";
sayHi() {
alert(`${this.name}ë ìë
íì¸ì!`);
}
}
new User().sayHi(); // ë³´ë¼ë ìë
íì¸ì!
í´ëì¤ë¥¼ ì ìí ë '<íë¡í¼í° ì´ë¦> = <ê°>'ì ì¨ì£¼ë©´ ê°ë¨í í´ëì¤ íë를 ë§ë¤ ì ììµëë¤.
í´ëì¤ íëì ì¤ìí í¹ì§ ì¤ íëë User.prototypeì´ ìë ê°ë³ ê°ì²´ìë§ í´ëì¤ íëê° ì¤ì ëë¤ë ì ì
ëë¤.
class User {
name = "ë³´ë¼";
}
let user = new User();
alert(user.name); // ë³´ë¼
alert(User.prototype.name); // undefined
ìì¸ë¬ í´ëì¤ íëì ë³µì¡í ííìì´ë í¨ì í¸ì¶ 결과를 ì¬ì©í ì ììµëë¤.
class User {
name = prompt("ì´ë¦ì ìë ¤ì£¼ì¸ì.", "ë³´ë¼");
}
let user = new User();
alert(user.name); // ë³´ë¼
í´ëì¤ íëë¡ ë°ì¸ë© ë ë©ìë ë§ë¤ê¸°
í¨ì ë°ì¸ë© ì±í°ìì ì´í´ë³¸ ê²ì²ë¼ ìë°ì¤í¬ë¦½í¸ìì thisë ëì ì¼ë¡ ê²°ì ë©ëë¤.
ë°ë¼ì ê°ì²´ ë©ìë를 ì¬ê¸°ì 기 ì ë¬í´ ì í ë¤ë¥¸ 컨í
ì¤í¸ìì í¸ì¶íê² ëë©´ thisë ë©ìëê° ì ìë ê°ì²´ë¥¼ 참조íì§ ììµëë¤.
ê´ë ¨ ìì를 ì´í´ë´
ìë¤. ìì를 ì¤ííë©´ undefinedê° ì¶ë ¥ë©ëë¤.
class Button {
constructor(value) {
this.value = value;
}
click() {
alert(this.value);
}
}
let button = new Button("ìë
íì¸ì.");
setTimeout(button.click, 1000); // undefined
ì´ë ê² thisì 컨í
ì¤í¸ë¥¼ ì ì ìê² ëë 문ì 를 'ìì´ë²ë¦° this(losing this)'ë¼ê³ í©ëë¤.
문ì ë ë ë°©ë²ì ì¬ì©í´ í´ê²°í ì ìëë° í¨ì ë°ì¸ë©ìì ì´ ë°©ë²ì ëí´ ìì본 ë° ììµëë¤.
setTimeout(() => button.click(), 1000)ê°ì´ ëí¼ í¨ì를 ì ë¬í기- ìì±ì ì ë±ìì ë©ìë를 ê°ì²´ì ë°ì¸ë©í기
ì´ ë ë°©ë² ë§ê³ í´ëì¤ íë를 ì¬ì©í´ë ì°ìíê² ë¬¸ì 를 í´ê²°í ì ììµëë¤.
class Button {
constructor(value) {
this.value = value;
}
click = () => {
alert(this.value);
}
}
let button = new Button("ìë
íì¸ì.");
setTimeout(button.click, 1000); // ìë
íì¸ì.
í´ëì¤ íë click = () => {...}ë ê° Button ê°ì²´ë§ë¤ ë
립ì ì¸ í¨ì를 ë§ë¤ì´ì£¼ê³ ì´ í¨ìì this를 í´ë¹ ê°ì²´ì ë°ì¸ë©ìì¼ì¤ëë¤. ë°ë¼ì ê°ë°ìë button.clickì ì무 ê³³ìë ì ë¬í ì ìê³ , thisì íì ìëí ê°ì´ ë¤ì´ê°ê² ë©ëë¤.
í´ëì¤ íëì ì´ë° 기ë¥ì ë¸ë¼ì°ì íê²½ìì ë©ìë를 ì´ë²¤í¸ 리ì¤ëë¡ ì¤ì í´ì¼ í ë í¹í ì ì©í©ëë¤.
ìì½
ìëì ê°ì 기본 문ë²ì ì¬ì©í´ í´ëì¤ë¥¼ ë§ë¤ ì ììµëë¤.
class MyClass {
prop = value; // íë¡í¼í°
constructor(...) { // ìì±ì ë©ìë
// ...
}
method(...) {} // ë©ìë
get something(...) {} // getter ë©ìë
set something(...) {} // setter ë©ìë
[Symbol.iterator]() {} // ê³ì°ë ì´ë¦(computed name)ì ì¬ì©í´ ë§ëë ë©ìë (ì¬ë³¼)
// ...
}
MyClassë constructorì ì½ë를 본문ì¼ë¡ ê°ë í¨ìì
ëë¤. MyClassìì ì ìí ì¼ë° ë©ìëë getter, setterë MyClass.prototypeì ì°ì
ëë¤.
ì´ì´ì§ë ì±í°ìì ììì ë¹ë¡¯í í´ëì¤ì ë¤ìí 기ë¥ì ëí´ ììë³´ê² ìµëë¤.
ëê¸
<code>í그를, ì¬ë¬ ì¤ë¡ 구ì±ë ì½ë를 ì½ì íê³ ì¶ë¤ë©´<pre>í그를 ì´ì©íì¸ì. 10ì¤ ì´ìì ì½ëë plnkr, JSBin, codepen ë±ì ìëë°ì¤ë¥¼ ì¬ì©íì¸ì.