getter ๋ฐ setter์ ๋ํด ๋ค๋ฅธ ์ก์ธ์ค ์์ ์๋ฅผ ๊ตฌํํ ์ ์์ต๋๊น? ์ด๋ฐ ์์ผ๋ก setter๋ ์๋ฅผ ๋ค์ด private/protected์ด๊ณ getter๋ public์ด ๋ ์ ์์ต๋๋ค. ์ด๋ค ๊ฒฝ์ฐ์๋ ๊ฐ์ด ์ฝ๊ธฐ ์ ์ฉ์ผ ๋ ์ ๋ง ์ ์ฉํฉ๋๋ค.
์์:
class MyClass {
private _myProp: any;
private set myProp(value: any) {
this._myProp = value;
}
public get myProp(): any {
return this._myProp;
}
}
#12๊ฐ #6532๋ก ์ข
๋ฃ๋์์ผ๋ฏ๋ก ์ด์ ์ด ๋ฌธ์ ๋ ๋ฒ์๋ฅผ ๋ฒ์ด๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ด์ ๋ค๋ฅธ ์ก์ธ์ค ์์ ์๋ฅผ ๊ตฌํํ ๊ณํ์ด ์์ต๋๊น?
readonly
๋ ์์ฑ์ด ์ค์ ๋ก ํด๋์ค ๋ด์์ ์ฐ๊ธฐ ๊ฐ๋ฅํ๋ค๊ณ ์ฌ๊ธฐ์์ ์ค๋ช
ํ๋ ๊ฒ์ ํด๊ฒฐํ๊ธฐ์ ์ถฉ๋ถํ์ง ์๊ธฐ ๋๋ฌธ์
๋๋ค.
๊ด๋ จ ๋ฌธ์ ์์ ๋ด ์๋ฅผ ์ฌ๊ธฐ๋ก ์ฎ๊ฒจ์ผํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
declare abstract class Emitter {
new (): Emitter;
on: (name:string, handler: (arg:any) => void) => void;
off: (name:string, handler: (arg:any) => void) => void;
protected emit: (name:string, arg:any) => void;
}
class Person extends Emitter {
constructor(name:string) {
super();
this.name = name;
}
private _name:string;
get name() {
return this._name;
}
set name(value) {
if (this._name !== value) {
this._name = value;
this.emit('change:name', value);
//this way is better
this.updatedAt = new Date();
//than this way
this.setUpdatedAt(new Date());
}
}
////
private _updatedAt:Date;
get updatedAt() {
return this._updatedAt;
}
private set updatedAt(value) { //Getter and setter do not agree in visibility
//some logic and a simple readonly (our absence of a setter) is not enough
if (this._updatedAt !== value) {
this._updatedAt = value;
this.emit('change:updatedAt', value);
}
}
//// method implementation - but what's the point in it?
private setUpdatedAt(value) {
if (this._updatedAt !== value) {
this._updatedAt = value;
this.emit('change:updatedAt', value);
}
}
}
const entity = new Person('Mike');
entity.on('change:updatedAt', console.log.bind(console));
entity.name = 'Thomas';
//but manually setting updatedAt should be forbidden
entity.updatedAt = new Date(); //restricted
์ฌ๊ธฐ์ updatedAt
์์ฑ์ ์ค์ ๋ก setter ๋ฅผ ๊ฐ์ง ์ ์์ง๋ง Person
์ธ๋ถ์์ ์ก์ธ์คํ ์ ์์ด์ผ ํฉ๋๋ค . ๊ฒ๋ค๊ฐ ์ด setter๋ ๋ณต์กํ ๋ก์ง์ ํฌํจํ๊ณ ์์ผ๋ฉฐ ๋จ์ํ readonly ๋๋ setter์ ๋ถ์ฌ๋ก๋ ์ถฉ๋ถํ์ง ์์ต๋๋ค.
private setter๋ ์ถ๊ฐ ๋ ผ๋ฆฌ(์: ๋ฐฉ์ถ)๊ฐ ์๋ private ๋ฉ์๋์ ๋ํ ๊ตฌ๋ฌธ ์คํ์ด๋ผ๋ ๋ฐ ๋์ํ์ง๋ง ํ๋์ ๊ด๋ จ๋ ๋ ผ๋ฆฌ์ ์ผ๋ถ๊ฐ ์์ฑ(getter)์ ์๊ณ ๋ค๋ฅธ ๋ ผ๋ฆฌ๊ฐ ๋ฉ์๋(private setter)์ ์๋ ๊ฒฝ์ฐ์๋ ์ผ๊ด์ฑ์ด ์๋ค๊ณ ์๊ฐํฉ๋๋ค. .
์ด ๋ฐฉ๋ฒ์ผ๋ก getters/setters๋ C#
์์ ๊ตฌํ๋ฉ๋๋ค. ์ด ๊ณ์ฝ์ ๋ฐํ์์ ์์ค๋์ง๋ง ์ปดํ์ผ ์๊ฐ์ ๋ค๋ฅธ ๊ฐ์์ฑ์ ํ์ฉํ๋ ๊ฒ์ด ์ ์ฉํ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์ฌ๊ธฐ์์ ๊ถ์ฅํ๋ ๊ฒ์ ๊ณต๊ฐ ์ฝ๊ธฐ ์ ์ฉ getter์ ๊ฐ์ธ/๋ณดํธ๋ ์ง์ ํ๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค.
์ ๊ทผ์๋ ์ ํ ์์คํ ์ ์์ฑ๊ณผ ๋์นญ์ ๋๋ค. ์ฐ๋ฆฌ๊ฐ ํ๋ ๋ชจ๋ ์ผ์ ์ ํ์ ๋ช ์๋์ด์ผ ํ๊ณ ์์ฑ์ ํํ ๊ฐ๋ฅํด์ผ ํฉ๋๋ค. private_set/public_get์ ํ์ฑํํ๊ธฐ ์ํด ์๋ก์ด ์ ๊ทผ ์์ ์๋ฅผ ์ถ๊ฐํ๋ฉด ์ธ์ด์ ๋ณต์ก์ฑ๊ณผ ํ์ต ๊ณก์ ์ด ์ฆ๊ฐํ๊ณ ์ฌ๊ธฐ์ ์ป์ ๊ฐ์ ์ถ๊ฐ๋ ๋ณต์ก์ฑ๊ณผ ์ผ์นํ์ง ์์ต๋๋ค.
์ด์จ๋ ์ด๊ฒ์ ์ํด ๋ด +1์ ์ถ๊ฐํ์ญ์์ค. ๋์ค์ ๋ค์ ๊ณ ๋ ค๋๋ ๊ฒฝ์ฐ๋ฅผ ๋๋นํ์ฌ ...
๋๋ ์์ง๋ ์ด๊ฒ์ ๋ณด๊ณ ์ถ๋ค. C#์๋ ์ด ๊ธฐ๋ฅ์ด ์์ผ๋ฉฐ ํนํ ํด๋์ค ์ธ๋ถ์์ ์ฝ๊ณ ์ถ์ง๋ง ๋ด๋ถ์ ์ผ๋ก๋ง private/protected๋ก ์ค์ ๋๋ ํ๋๊ทธ๊ฐ ์๋ ๊ฒฝ์ฐ ๋ง์ ์ํฉ์์ ๋งค์ฐ ์ ์ฉํฉ๋๋ค.
์์ฃผ ์ฌ์ฉํ์ง ์๋๋ค๋ ์ ์์ ํจํด์ ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ ์ฌ์ฉํ์ง ์๋๋ค๋ ์ ์์ ํฌ๊ทน์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์ด๊ฒ์ ์ธ์ด์ ์ข์ ์ถ๊ฐ ์ฌํญ์ ๋๋ค. (ํ์ ์คํฌ๋ฆฝํธ ํ๋ก๊ทธ๋๋จธ์ ๊ด์ ์์) ์ถ๊ฐ๋๋ ๋ณต์ก์ฑ์ ์์ ์ ์ต๋๋ค. ๊ฐ๋ ์ ์ดํดํ๊ธฐ ์ฝ๊ณ ์ปดํ์ผ๋ฌ๋ ๋ฒ์ ์ง์ ์ผ๋ก ์ธํด getter ๋๋ setter์ ์ก์ธ์คํ ์ ์๋ ์ด์ ๋ฅผ ์์ํ๋ ์ข์ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ ๊ณตํ ์ ์์ด์ผ ํฉ๋๋ค.
๋๋ ์์ ์ฌ์ฉ์์ ๋์ํฉ๋๋ค. ์ด๊ฒ์ ๋๋ถ๋ถ์ ๋ค๋ฅธ ์ธ์ด์ ํ์ค์ ๋๋ค. ์ด์ ๋ํ ์ฃผ์ฅ์ ์ค์ํ์ง ์์ผ๋ฉฐ ๊ตฌํ์ ์ฌ๊ณ ํด์ผ ํฉ๋๋ค.
๋๋ ์ค์ ๋ก ๋น์ ์ด TS์์ ์ด๊ฒ์ ํ ์ ์๋ค๋ ๊ฒ์ ๋๋์ต๋๋ค ... ๋ฌธ์ ์ +1.
์ด๊ฒ์ผ๋ก ํ์ต ๊ณก์ ์ด ์ฆ๊ฐํด์๋ ์๋ฉ๋๋ค.
private get x() { ... }
public set x(value) { ... }
์์ด๋ฅผ ์ฝ์ ์ ์๋ค๋ฉด ์ฌ๊ธฐ์์ private(protected)/public์ด ๋ฌด์์ ์๋ฏธํ๋์ง ์๋ช ํฉ๋๋ค. ๋ํ ์ฒ์์ ์ ๊ทผ์๋ฅผ ์ ์ํ๋ ๊ฒฝ์ฐ - ์ด๋ฏธ ์ ๊ทผ์๊ฐ ๋ฌด์์ธ์ง ์๊ณ ์์ ๊ฒ์ ๋๋ค.
์ถ์ ์ค๋ฅ ์ ๋ณด: "Getter ๋ฐ setter ์ ๊ทผ์๊ฐ ๊ฐ์์ฑ์ ๋์ํ์ง ์์ต๋๋ค." - ๊ธ์: ์ด๊ฒ์ด ๋ฐ๋ก ๋ด๊ฐ ์ํ๋ ์์ ์ ๋๋ค.
๋ค์์ ์ด๊ฒ์ด ํธ๋ฆฌํ ๋ ๊ฐ์ง ์ฌ์ฉ ์ฌ๋ก์ ๋๋ค.
.get()
๋ฐ .set()
ํธ์ถ์ ํผํ๊ธฐ ์ํด Backbone.js:
class Whatever {
public get rotation(): number {
return this.get('rotation');
}
private set rotation(rotation: number) {
this.set('rotation', rotation);
}
}
์๋ธํด๋์ค๊ฐ ์์ ํ ์ ์๋ ์์ฑ:
class ExtendMe {
public get someProperty(): string {
// some stuff
}
protected set someProperty(prop: string) {
// some stuff
}
}
TypeScript๋ฅผ ์ฌ์ฉํ๊ธฐ ์์ํ ์ดํ๋ก ์ ๋ฅผ ๊ดด๋กญํ๊ณ ์๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ๋ณด๊ณ ์ถ์ต๋๋ค.
์ด ๊ธฐ๋ฅ์ ์์ฒญํ๋ ์ฌ๋๋ค์ ์๊ฒฌ์ ๋์ํฉ๋๋ค. ๋ฐฉ๊ธ ๊ณต๊ฐ get() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ค๊ณ ํ๊ณ ๋ด ์งํฉ๊ณผ get์ด ๊ฐ์์ฑ์ ๋ํด ๋์ํด์ผ ํ๋ค๋ ์ฌ์ค์ ๋๋์ต๋๋ค.
๋๋ ๊ทธ๊ฒ์ด ๋๋ฌด ๋ณต์กํ๋ค๊ณ ์ฃผ์ฅํ๋ ๋น์ ๋ค์ ์ฝ์์ต๋๋ค. "C++ ๋ฐฉ์"์ด ๋ค์๊ณผ ๋ค๋ฅธ ์ด์ ๋ฅผ ๊ธฐ์ตํ์ญ์์ค.
private _myAttribute: string;
get myAttribute(): string {...}
setMyAttribute(value: string) {...}
๋๋ ์ด๊ฒ์ ๋ํ ๋ง์ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ๋ณผ ์ ์์ต๋๋ค. ๊ทธ๋์ ์ ๊ฐ ์ง๊ธ ์ฌ๊ธฐ ์์ต๋๋ค.
myAttribute๋ฅผ ๊ณต๊ฐ์ ์ผ๋ก ์ก์ธ์คํ ์ ์์ง๋ง ํด๋น ํด๋์ค ๋ด์์๋ง ์์ ํ ์ ์๋๋ก ํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํฉ๋๊น?
์์ฑ์ด ์์ ๋ ๋๋ง๋ค ์ผ๋ถ ์ฌ์ฉ์ ์ ์ ๋
ผ๋ฆฌ๋ฅผ ์ถ๊ฐํ๋ ค๋ฉด ์ด๋ป๊ฒ ํฉ๋๊น?
๋น์ฆ๋์ค ๊ท์น์ด ๋ ์๋ ์๊ณ ๋๋ฒ๊น
๋ชฉ์ ์ ์ํ ์ค๋จ์ ์กฐ๊ฑด๊ณผ ํจ๊ป ํน์ ๊ฐ์ด ํ ๋น๋ ์ด์ ๋ฅผ ์ดํดํ๊ธฐ ์ํ ๋ก๊น
์ผ ์๋ ์์ต๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์ฐ๋ฆฌ๋ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๋์ ๊ฐ์ ํ ๋นํ๋ ๊ฒ์ฒ๋ผ ๋ณด์ด๊ฒ ํ๋ ๊ตฌ๋ฌธ ์คํ๊ณผ ํจ๊ป ์์ฑ์ ์์ ํ ๋๋ง๋ค ๋ฉ์๋๊ฐ ์ฌ์ฉ๋๊ธฐ๋ฅผ ์ํฉ๋๋ค.
C#์ ์ด์ ๋ํ ์์ฑ์ ๊ฐ๋
์ ๊ฐ์ง๊ณ ์๊ณ TS๊ฐ ๊ทธ ๊ฐ๋
์ ๊ณ์นํ๋ค๊ณ ์๊ฐํ์ง๋ง, ๋ค๋ฅธ ์ ๊ทผ์ฑ์ ํ์ฉํ์ง ์๋ ๊ฒ์ ๋์ ๊ฐ์ ์๊ฐ์ ํ๊ณ ์ฐ๋ฆฌ๋ฅผ "C++ ์คํ์ผ"๋ก ๋๋์๊ฐ๊ฒ ๋ง๋๋ ์ฌ๋๋ค์๊ฒ ํฐ ํ๊ณ์
๋๋ค.
"๋๋ฌด ์ด๋ ค์"๋ผ๊ณ ํด์ ์์ฒญ๋๊ฒ ์ ์ฉํ ๊ธฐ๋ฅ์ ๊ตฌํํ์ง ์์ ์ด์ ๊ฐ ๋์ด์๋ ์ ๋ฉ๋๋ค.
๋ด +1์ ์ถ๊ฐํฉ๋๋ค. ๋ง์ ๋ฉด์์ ๋๋ฌด๋ ์์ ํ ์ธ์ด๋ก ๋น์ ์ด ์ด๊ฒ์ ํ ์ ์๋ค๋ ๊ฒ์ด ์ ๊ฒ๋ ๋งค์ฐ ์ด์ํ๊ฒ ๋ณด์ ๋๋ค.
์ด ๋ฌธ์ ๊ฐ ์ข
๋ฃ๋ ๊ฒ์ผ๋ก ํ์๋์ด ๋๋์ต๋๋ค. ์ด ๊ธฐ๋ฅ์ ์ปค๋ฎค๋ํฐ์์ ์ํ๋ ๊ธฐ๋ฅ์
๋๋ค. ๋ค์ ์ด์ด์ฃผ์ธ์.
+1
IMHO ์ด๊ฒ์ ์ข์ ๊ธฐ๋ฅ์ด์ง๋ง ๋ด๊ฐ ์ดํดํ๋ ํ ๊ณต์ ํฉ๋๋ค. "๊ธ์, ๋๋ ๋งค๋ฒ _property๋ฅผ ์ฐ๊ณ ์ถ์ง ์์ต๋๋ค. ๋์ ์ private set ์์ฑ์ ์ฌ์ฉํ๊ณ ์ถ์ต๋๋ค"๋ผ๋ ์ํฉ์ ๋๋ค.
TypeScript ํต์ฌ ์ฝ๋ ์์ฒด์ ์์ฒญ๋ ๋ณต์ก์ฑ์ ์ถ๊ฐํ๋ ์ ํ์ด ์๋ ๊ฒฝ์ฐ(๊ธฐ์ตํ์ญ์์ค, ๋ ๋ถํ์ํ ๋ณต์ก์ฑ - ๊ฐ๋ฐ ์๋ ๊ฐ์, ๋๋ฒ๊ทธ์ ๋ ๋ง์ ์๊ฐ, ๊ฒฐ๊ตญ ํ ์คํธ ์์ฑ - ๋ ๋น๋ฒํ ๋ฆด๋ฆฌ์ค) ๊ธฐํธ 1๊ฐ ์ฐ๊ธฐ ๋๋ ์ฐ๊ธฐ ๊ทธ 1 ์ฌ๋ณผ์ ์ ์ฒ๋ฆฌํ๊ณ ... ์ฐจ๋ผ๋ฆฌ 1 ์ฌ๋ณผ์ ๋งค๋ฒ ํ ๋ฒ ๋ ์ฐ๊ฒ ์ต๋๋ค. ๊ฒฐ๊ตญ ์ ๋ TS ์ฝ์ด์ ๊ธฐ์ฌํ ์ฌ๋์ด ์๋๋ฉฐ ์ด ์คํ์ ๊ฐ๋ฅํ ๋ณต์ก์ฑ์ ์ฒ๋ฆฌํ๊ณ ์ถ์ง ์์ต๋๋ค.
๋๋ธ๋ ์ด์ปค๊ฐ ์๋๋๋ค. ๋ํ ๊ตฌํํ๊ธฐ์ ๋๋ฌด ๋ณต์กํ ์์ฒญ์ ๋ฐ๊ฒฌํ๋ ๋ฐ๋ ์ฉ๊ธฐ์ ์งํ๊ฐ ํ์ํฉ๋๋ค(๊ฒฐ๊ณผ์ ์ผ๋ก ์ ์ฒด ์ฝ๋ ๋ณต์ก์ฑ์ด ์ฆ๊ฐํจ). ๋ฐ๋ผ์ TypeScript๋ฅผ ๊ฐ๋ฐํ๋ ์ฌ๋ฌ๋ถ๊ป ๊ฒฝ์๋ฅผ ํํ๊ณ ์์ ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค!
(ps๋ ์ ์๋๋์ง ๋ฐฐ์ฐ๊ธฐ ์ํด ์ฌ๊ธฐ์ ์์ต๋๋ค - ๊ฒฐ๊ตญ ๋ด ๋ง์์ด ๋ฐ๋์๊ณ ์ด๊ฒ์ ๋ค๋ฃฐ ๊ฒ์
๋๋ค._property = ...
๊ทธ๋ฆฌ๊ณ ์ฌ์ ํ ํ๋ณตํ ๊ฒ์
๋๋ค)
@idchlife set
์์ฑ ๋ชฉํ๋ ๊ฐ์ ํ ๋นํ ๋ ๊ฐ๋ฐ์์๊ฒ ๋ฐ์ค ํ๋๋ฅผ ์ ์ฅํ๋ ๊ฒ์ด ์๋๋๋ค. set
ํ๋ก์ธ์ค์ ์ผ๋ถ ๋
ผ๋ฆฌ๋ฅผ ์ถ๊ฐํ ์๋ ์์ต๋๋ค.
์ด ๋ฌธ์ ๋ฅผ ๋ค์ ์ฌ์ญ์์ค. ์ด๊ฒ์ ๋ถ๋ช ํ ๋งค์ฐ ์ํ๋ ๊ธฐ๋ฅ์ ๋๋ค.
+1 ๋๋ ์ด๊ฒ์ ์ฌ๊ฒํ ํ๋ ๊ฒ์ ๋ณด๊ณ ์ถ๋ค.
๋ค๋ฅธ ๋ง์ ์ธ์ด๊ฐ ์ด๋ฏธ ์ด ์์ ์ ์ํํ ๋ "์ด๊ฒ์ ํผ๋์ ์ผ์ผํฌ ๊ฒ"์ด๋ผ๋ ๋ ผ๋ฆฌ๊ฐ ๋งค์ฐ ์ด์ํฉ๋๋ค.
๋ชจ๋ ๐๊ฐ ๋ณ ์ผ์ ํ๊ณ ์์ง ์๊ธฐ ๋๋ฌธ์ ๐ ๋๊ธ ํ๋๋ง ๋ ๋ฌ๊ฒ ์ต๋๋ค.
์ด๊ฒ์ ๋ ์ฝ๊ธฐ ์ฝ๊ณ ๋น ๋ฅด๊ฒ ๊ตฌํํ๋ ๋ฐ ๋์์ด๋๋ ๊ตฌ๋ฌธ ์คํ์ด ๋ ๊ฒ์ ๋๋ค. Typescript๋ฅผ ํฌํจํ์ฌ ๋ง์ ์ธ์ด์ ๊ตฌ๋ฌธ ์คํ์ด ์์ต๋๋ค. ํ์ง ๋ง์์ผ ํ ์ข์ ์ด์ ๊ฐ ์๋ ๊ฒ ๊ฐ๊ณ ๋๋ฌด ๋ณต์กํ๋ค๊ณ ํด์ ํ์ง ๋ง์์ผ ํ ์ข์ ์ด์ ๊ฐ ๋ ์ ์์ต๋๋ค. ๋๋ฌด ๋ณต์กํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๊ฒ์ ๋๋ถ๋ถ์ ์ฌ๋๋ค์ด ์ํํธ์จ์ด ์์ง๋์ด๋ง์ ๋๋ฆฌ๋ ์ด์ ์ค ํ๋์ ๋๋ค. ๋ฐ๋ผ์ ์ด ๋ณต์กํ ๋ฌธ์ ๋ฅผ ๊ทธ๋ ๊ฒ ๋ณต์กํ์ง ์์ ๋ฐฉ์์ผ๋ก ํด๊ฒฐํ์ญ์์ค. ๋ฆฌํฉํ ๋ง๊ณผ ์ํํ ๋ณ๊ฒฝ์ด ํ์ํฉ๋๊น? ์ด์ฉ๋ฉด ๊ทธ๋ ๊ฒ ํ ์ ์์ต๋๋ค.
์ฌ์ ํ ๋ฐ๋์งํฉ๋๋ค. ๋ค๋ฅธ ์ธ์ด๋ get ๋ฐ set ๊ธฐ๋ฅ์ ๋ํด ๋ค๋ฅธ ๊ฐ์์ฑ์ ์ง์ํ๋ ๋ฐ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ๋ชจ์์ ์์ฒ๋ฅผ ์ฃผ๊ธฐ ์ํด Typescript๋ C#๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก Microsoft์์ ๋ง๋ค์ง๋ง ํ์๋ ์์ ํ ์ง์ํฉ๋๋ค.
public string myPropertyWithLimitedAccess { get; private set; }
์ ๊ฒ ๋ด. ์๋ฆ๋ต๊ฒ ์ฝ์ ์ ์๊ณ ์ ํ ๋ณต์กํ์ง ์์ต๋๋ค.
์ง์ํ์ง ์์ ์ด์ ๊ฐ ๊ฑฐ์ ์์ต๋๋ค.
private _myProperty: string;
public get myProperty(): string { return this._myProperty; }
private set myProperty(value: string) { this._myProperty = value; }
Typescript๋ ์ฃผ๋ก .NET ๊ฐ๋ฐ์๊ฐ ๋ธ๋ผ์ฐ์ ํ๋ฐํธ ์๋ ์์ ์ ๋ ์ต์ํด์ง๋๋ก ๋ง๋ค์ด์ก๊ธฐ ๋๋ฌธ์ ์ด์ํ ๋์์ธ ๊ฒฐ์ ์ ๋ํ ๋ณด๋์ค ํฌ์ธํธ์ ๋๋ค.
+1
Typescript๋ ํ์คํ ์ด ๊ธฐ๋ฅ์ ์ด์ ์ ๋๋ฆด ๊ฒ์
๋๋ค!
TypeScript๋ C# ์ดํ์๋ ํ๋ฅญํ์ง๋ง ์ด ๋ฌด์๋ฏธํ ์ ํ์ด ๋๋ฅผ ์์ฃผ ์ง์ฆ๋๊ฒ ํฉ๋๋ค. ๋ค์ ์ด์ด์ฃผ์ธ์.
์ธ์ด์ ๋ณต์ก์ฑ์ ์ฆ๊ฐ์ํฌ ๊ฒ์ ๋๋ค
readonly [P in keyof T]: T[P]
์ ๋น๊ตํ ๋ ์ด๊ฒ์ด ์ ๋ง ๋ณต์กํฉ๋๊น?
์ถฉ๋. ๋ชจ๋๊ฐ ์ด ๊ธฐ๋ฅ์ ์ํฉ๋๋ค. TypeScript ์ปค๋ฎค๋ํฐ๊ฐ ๊ฒฐ์ ํด์ผ ํ์ง ์์ต๋๊น?
์ธ์ด์ ๋ณต์ก์ฑ์ ์ฆ๊ฐ์ํฌ ๊ฒ์ ๋๋ค
readonly [P in keyof T]: T[P]
์ ๋น๊ตํ ๋ ์ด๊ฒ์ด ์ ๋ง ๋ณต์กํฉ๋๊น?
๋ณต์ก์ฑ์ ๋ค๋ฅธ ์ธ์ด ๊ธฐ๋ฅ์ ์ํธ ์์ฉ๊ณผ ๊ด๋ จ์ด ์์ต๋๋ค. ๋ถํํ๋ ์ฐพ์ ์ ์์ง๋ง IIRC RyanCavanaugh๋ ์ด ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ ํด๋์ค ํํ์์ ์ฌ์ฉํ์ฌ ์์์ ํตํด ๋ถ๋ณ์ฑ์ ์ค์ ํ๊ณ ์๋ฐํ ์ ์๋ ์๋ฅผ ์ ๊ณตํ์ต๋๋ค. ํน์ ์ ์ธ์ ์์ฑํ๋ ๊ฒ์ด ์ฝ๋ค๊ณ ํด์ ๊ทธ๊ฒ์ด ์ฌ๋ฌผ์ ์ด๋ค ์ํฅ์ ๋ฏธ์น๋์ง ์ถ๋ก ํ๋ ๊ฒ์ด ํญ์ ์ฌ์ด ๊ฒ์ ์๋๋๋ค.
๋ฌธ์ ๋ ์ฃผ์ด์ง ๊ธฐ๋ฅ์ด ์ด๋ค ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ณ ์ด๋ค ๋ฌธ์ ๋ฅผ ๋ง๋ค ๊ฒ์ธ๊ฐ ํ๋ ๊ฒ์ ๋๋ค. ์ ์๋ ๋๋ตํ๊ธฐ ์ฝ๊ณ ํ์๋ ์์ธ๋ก ๋๋ตํ๊ธฐ ์ด๋ ต๋ค. ๋ถํํ๋ TS ํ์ ๋๋๋ก ๋ฌธ์ ๋ฅผ ์ค๋ช ํ๋ ๋์ "OMG ๋ณต์ก์ฑ"์ผ๋ก ์๋ตํ๋ ๊ฒ ๊ฐ์ต๋๋ค. (๊ณต์ ํ๊ฒ ๋งํ๋ฉด, n๋ฒ์งธ๋ก ์ฟผ๋ฆฌ x์ ์๋ตํ๋ ๋ฐ ๋ ๋ง์ ์๊ฐ์ ํ ์ ํ ์๋ก ๊ฐ๋ฐํด์ผ ํ๋ ์๊ฐ์ด ์ค์ด๋ญ๋๋ค.)
๋๋ "์ปค๋ฎค๋ํฐ๊ฐ ๊ฒฐ์ ํด์ผ ํ๋ ๊ฒ"์ด๋ผ๋ ๊ฐ๋ ์ 100% ๋์ํ์ง ์์ต๋๋ค. ์๋ํ๋ฉด ์ค์ ๋ก ์ธ์ด๋ฅผ ๊ฐ๋ฐํ๋ ์ ๋ฌธ๊ฐ๋ค ์ฌ์ด์ ํฉ์๊ฐ ์๋ค๋ฉด ๊ทธ๊ฒ์ด ๋น์ ์๊ฒ ๋ฌด์ธ๊ฐ๋ฅผ ๋งํด์ค ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ด์ ๊ฐ์ด ์์ฒญํ ์ฌํญ์ ๋ํด ํ์์ ์ ์ถฉ์์ด ๋ฌด์์ธ์ง, ์ ๋ฐ๋ํ๋์ง์ ๋ํ ์ฌ๋ ค ๊น์ ์ค๋ช ์ ๋๋ฌด ๋ง์ ๊ฒ์ ์๊ตฌํ์ง ์๋๋ค๊ณ ์๊ฐํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๊ฐ์ธ์ ์ผ๋ก ์ด ๊ฒฝ์ฐ์๋ ์ ์ถฉ์์ด 1000% ๊ฐ์น๊ฐ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ด๊ฐ ๊ทธ๊ฒ์ ์ฌ์ํ๊ณ ์๋ํ๊ฒ ๋ง๋ค ์ ์๋ค๋ฉด ๋๋ ๋ถํํ ๊ถ๋ฆฌ๊ฐ ๋ณ๋ก ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ด ๋ฌธ์ ๋ฅผ ๋ค์ ์ดํด๋ณด๋ ๊ฒ์ด ์ข์๊น์?
readonly
์์ ์๋ ํ๋ฅญํ์ง๋ง ํด๋์ค ๋ด๋ถ์์ ๊ฐ์ ๋ณ๊ฒฝํ๊ณ ์ธ๋ถ์์๋ ๋ชจ๋ ๊ฒ์ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ ์งํ๋ ค๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค.
๊ฐ์ธ ์ง์ ํ๋ + ์์ฑ์ด ์ถ๊ฐํ๋ ๋
ธ์ด์ฆ๊ฐ ๋ง์์ ๋ค์ง ์๊ธฐ ๋๋ฌธ์ ์์ฑ์ readonly
๋ก ์ง์ ํ์ง ์๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค.
์ด ์์ ์ ์ํํ ์ ์๋ ๊ตฌ๋ฌธ ์คํ์ด ์์ผ๋ฉด ์ข์ ๊ฒ์ ๋๋ค. ๋ค์๊ณผ ๊ฐ์ ๊ฒ:
// Option 1: C# style
public name: string { get; private set; }
// Option 2: Swift style
private(set) name: string
// Option 3: Swift struct-style
public readonly name: string
mutating changeName(name: string) {
this.name = name
}
// Option 4: New keyword
public frozen name1: string
public readonly name2: string
์ต์ 2๊ฐ ๋ง์์ ๋ญ๋๋ค. TypeScript ์ธ์ด์ ์ ๋ง์ ๊ฒ์ ๋๋ค.
์ต์
3์ ์ฌ์ฉํ๋ฉด mutating
๋ก ํ์๋ ํจ์์ ์ฝ๊ธฐ ์ ์ฉ ํ๋๋ง ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
์ต์
4๋ฅผ ์ฌ์ฉํ๋ฉด frozen
๋ ์์ฑ์์์๋ง ์ค์ ํ ์ ์๊ณ readonly
๋ ์ธ๋ถ ํด๋์ค๋ ์ด ํด๋์ค์์ ์์ํ๋ ํด๋์ค๊ฐ ์๋๋ผ ์ด ํด๋์ค ๋ด๋ถ์์ ์ค์ ํ ์ ์์ต๋๋ค.
์ฐธ๊ณ ๋ก @yvbeek ์ ๋ณด๋ค ์ ์ฐํ ์์ ์ ์์ด๋์ด๋ https://github.com/microsoft/TypeScript/issues/37487์ ๋ํ ๋ ผ์์ ๋ ์ ํฉํฉ๋๋ค.
์ด ๋ฌธ์ ๋ ํนํ getter ๋ฐ setter๋ฅผ ์ํ ๊ฒ์ด๋ฉฐ ๋งค์ฐ ๋์ ์์ ์ฐฌ์ฑํ๋ฅผ ๋ฐ์์ต๋๋ค! getter์ setter์ ์๋ก ๋ค๋ฅธ ์ก์ธ์ค ์์ ์๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ด ์ ์ฉํ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค(TypeScript ํ์ด ์์ผ๋ก ๋์๊ฐ ์ ์๋ ๊ฒ์ผ๋ก ๊ฒฐ์ ํ ๊ฒฝ์ฐ #37487์์ ๊ธฐ์กด ์์ ์ ์ธํธ๋ฅผ ์ ๋ฐ์ดํธํ ์ ์์ต๋๋ค)
๋๋ "์ปค๋ฎค๋ํฐ๊ฐ ๊ฒฐ์ ํด์ผ ํ๋ ๊ฒ"์ด๋ผ๋ ๊ฐ๋ ์ 100% ๋์ํ์ง ์์ต๋๋ค. ์๋ํ๋ฉด ์ค์ ๋ก ์ธ์ด๋ฅผ ๊ฐ๋ฐํ๋ ์ ๋ฌธ๊ฐ๋ค ์ฌ์ด์ ํฉ์๊ฐ ์๋ค๋ฉด ๊ทธ๊ฒ์ด ๋น์ ์๊ฒ ๋ฌด์ธ๊ฐ๋ฅผ ๋งํด์ค ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ด์ ๊ฐ์ด ์์ฒญํ ์ฌํญ์ ๋ํด ํ์์ ์ ์ถฉ์์ด ๋ฌด์์ธ์ง, ์ ๋ฐ๋ํ๋์ง์ ๋ํ ์ฌ๋ ค ๊น์ ์ค๋ช ์ ๋๋ฌด ๋ง์ ๊ฒ์ ์๊ตฌํ์ง ์๋๋ค๊ณ ์๊ฐํฉ๋๋ค.
@snarfblam ์ด ์ค๋ ๋๋ฅผ ๊ด๋ จ ์๋ ๋๊ธ๋ก
์ด ๊ธฐ๋ฅ์ด ์๋ค๋ ๊ฒ์ ์ ์๊ฒ ์ ๋ง ๊ณ ํต์ค๋ฌ์ด ์ผ์ด๋ฉฐ (๋ฌด์๋ณด๋ค๋) ์ ๊ฐ TS/NodeJS์์ ๋... ์ ํ์ด ์์ ํ ๊ฒ์ผ๋ก ์ ํํ๊ฒ ๋ง๋ค์์ต๋๋ค. ๋ชจ๋ ํ๋ฅญํ๊ณ ๋ฉ์ง๋๋ค. ํ์ง๋ง ๋ง์ ๋ฐ์ดํฐ ๊ตฌ์กฐ(๊น๊ฒ ์ฌ๋ฌ ๋ฒ ์ค์ฒฉ๋จ)๊ฐ ์๋ ๋ณต์กํ ํ๋ก์ ํธ์์ ์์ ํ ๋ ๋ฐ์ดํฐ๋ฅผ ์ ๋๋ก ๋ชจ๋ธ๋งํ ์ ์์ผ๋ฉด ์ด๊ฒ์ด "ํฐ ์ธ์ด"๊ฐ ์๋๋ผ๋ ๋๋์ ๋ฐ์ต๋๋ค. ์๋ ๋ค".
๋ด ํน๋ณํ ๊ฒฝ์ฐ์๋ ์์ฑ์ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ํ์ง๋ง ๋ด๋ถ์์ ์์ ํ ์ ์๊ณ ... ๋ํ JSON์ผ๋ก ์ง๋ ฌํ๋ฉ๋๋ค. ๋์ด์ผ ํ ๊ณจ์ด ๋๋ฌด ๋ง์ต๋๋ค.
์ด ๊ธฐ๋ฅ์ _์ ํ์ ์ฐ๊ฒฐ_๊ณผ ๋์ผํ ๊ฒฝ๋ก๋ฅผ ๋ฐ๋ฅผ ์ ์์ต๋๋ค. ์ฌ๋๋ค์ ๋ช ๋ ๋์ ์ด ๊ธฐ๋ฅ์ ์๊ตฌํ๊ณ ๋ง์นจ๋ด ์ธ์ด์ ์ถ๊ฐ๋ ๊ฒ์ ๋๋ค. ์ค์ฉ์ ์ด๊ณ ๋ค๋ฅธ ์ธ์ด์์๋ ๋์ผํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
๊ทธ๋ ์ง ์์ผ๋ฉด ์ผ๋ถ ๊ตฌํ์ด EcmaScript์ ์ผ๋ถ๊ฐ ๋ ๋ค์ TypeScript์ ์ ์ฉ๋๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
๋๋ ์ต๊ทผ์ typescript๋ก ์ ํํ๊ณ ์ธ์ด๋ฅผ ์ฌ๋ํด ์์ต๋๋ค. ๋ค๋ฅธ ์ธ์ด์ ์กด์ฌํ๋ ์ด ์ค์ฉ์ ์ธ ๊ธฐ๋ฅ์ด ์ฌ๊ธฐ์์ ๊ตฌํ๋์ง ์์๋ค๋ ์ฌ์ค์ด ์ ๋ง ์ํ๊น์ ์ต๋๋ค. ์ธ์ด์ ์ถ๊ฐ๋๋ ๋ณต์ก์ฑ์ ๊ด๊ณ์์ด ํฅํ ๋ฆด๋ฆฌ์ค์ ์ถ๊ฐํ๋ ๊ฒ์ ์ฌ๊ณ ํ์ญ์์ค.
๊ทธ๋ฐ ์์ผ๋ก getter๋ฅผ ์ฌ์ฉํ์ฌ C#๊ณผ ๋น์ทํ ๊ฒ์ ๋ฌ์ฑํ์ต๋๋ค.
export class I18nService {
private static ref: I18nService;
public static get instance(): I18nService {
if (!I18nService.ref) {
I18nService.ref = new I18nService();
}
return I18nService.ref;
}
}
๋ค์๊ณผ ๊ฐ์ ์ ํ ์ค๋ฅ๋ ์ดํดํ๊ธฐ ์ฝ๊ณ ๋ณต์กํ์ง ์์ต๋๋ค.
Property 'foo' is writable only in protected scope within class 'Blah' and its subclasses.
๋๋
Property 'foo' is readable only in protected scope within class 'Blah' and its subclasses.
๋ฑ๋ฑ, ๊ทธ๋ฆฌ๊ณ private
์ ์ ์ฌํฉ๋๋ค.
์์งํ ๋ณต์กํ์ง ์์ต๋๋ค.
BTW, ๋๋์ด ๋ฌธ์ ๋ฅผ ์ฐ์ฐํ ๋ฐ๊ฒฌํ์ผ๋ฉฐ ๊ทธ ๋์ ์ด๋ฐ ์ข ๋ฅ์ "ํดํน"์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
// somewhere.ts
declare global {
type Writable<T> = { -readonly [P in keyof T]: T[P]; }
}
// example.ts
class Example {
public readonly prop: number;
public doSomething(n: number): void {
(this as Writable<this>).prop = n;
}
}
๊ธฐ์ ์ ์ผ๋ก ์ด๊ฒ์ ๋ชจ๋ ๊ณณ์์ ์ฌ์ฉํ ์ ์์ง๋ง ์ด ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ ๊ฒ์ ํด๋์ค ๋ฉ์๋ ๋ด๋ถ์ ์ฝ๋๋ก ์ ํ๋์ด์ผ ํฉ๋๋ค.
BTW, ๋๋์ด ๋ฌธ์ ๋ฅผ ์ฐ์ฐํ ๋ฐ๊ฒฌํ์ผ๋ฉฐ ๊ทธ ๋์ ์ด๋ฐ ์ข ๋ฅ์ "ํดํน"์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
๋๋ ์ด ์์ด๋์ด๋ฅผ ๊ฐ์ง๊ณ ๋์์ง๋ง ๋ฌธ์ ๋ "๊ณต๊ฐ ์ฝ๊ธฐ ์ ์ฉ" ์์ฑ๊ณผ ์ง์ ํ ์ฝ๊ธฐ ์ ์ฉ ์์ฑ์ ๊ตฌ๋ณํ ๋ฐฉ๋ฒ์ด ์๋ค๋ ๊ฒ์ ๋๋ค. ๋ฐ๋ผ์ ๋ฒ์ฉ ์๋ฃจ์ ์ผ๋ก๋ ์ ํฉํ์ง ์์ต๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ด์จ๋ ์ด๊ฒ์ ์ํด ๋ด +1์ ์ถ๊ฐํ์ญ์์ค. ๋์ค์ ๋ค์ ๊ณ ๋ ค๋๋ ๊ฒฝ์ฐ๋ฅผ ๋๋นํ์ฌ ...