private 속성
자바스크립트의 private 속성을 알아볼 것이다.
먼저 정사각형의 넓이와 둘레를 구하는 class를 만들어 볼 것이다.
정사각형의 변을 length라고 하고, 넓이를 구하는 함수는 getArea(), 둘레를 구하는 함수는 getPerimeter()로 메소드를 만들 것이다.
// 정사각형을 나타내는 객체
class Square {
constructor(length) {
this.length = length;
}
getArea() {
return this.length * this.length;
}
getPerimeter() {
return 4 * this.length;
}
}
const square = new Square(10);
console.log(square.getArea()); // 100
console.log(square.getPerimeter()); // 40
console.log를 찍어보면 잘 동작하는 걸 알 수 있다.
하지만 만약 이 코드를 다른 사람에게 줬을 때 그 사람이 코드를 이상하게 사용할 가능성이 있다.
예를 들어서 이 변의 길이라는 단위는 음수가 나올 수 없는데 한 변의 길이가 -10인 사각형은 어떻게 될까 하고 스퀘어라는 매개변수에 -10을 넣게 된다면 코드에는 제약하는 코드가 없으므로 결과값은 넓이는 100이고 둘레는 -40이라는 값이 나올 것이다.
그래서 이런 문제가 생기지 않게 조건문을 활용하여 throw 키워드를 강제로 발생시키는 방법이 있다.
// 정사각형을 나타내는 객체
class Square {
constructor(length) {
if (length < 0) {
throw '길이는 0 이상이어야 합니다.';
}
this.length = length;
}
getArea() {
return this.length * this.length;
}
getPerimeter() {
return 4 * this.length;
}
}
const square = new Square(10);
console.log(square.getArea()); // 100
console.log(square.getPerimeter()); // 40
그런데 만약 클래스 외부에서 square.length = -10 으로 직접적으로 변경한 뒤에 다시 넓이와 둘레를 구하게 된다면 이전과 같이 넓이는 100이고 둘레는 -40이라는 결과값이 나오게 된다.
옛날에는 이런 문제를 막기 위해 클로저라는 특별한 개념을 사용하거나 아니면 모든 개발자들이 관례적으로 약속을 해서 속성 이름 앞에 _length와 같이 언더바를 붙이면 이 값을 건드리지 않는다는 관례를 통해서 length속성에 접근하지 않게 만들었다.
하지만 결과적으로 _length라고 언더바를 붙여도 속성에 접근을 할 수 있기에 최근 Javascript에서는 아예 접근하지 못하게 특별한 문법을 추가했다.
그것은 바로 private 속성이다. private 속성은 클래스 내부에서만 접근 가능한 속성이다.
사용하는 방법은 아래와 같이 클래스 밑에 #length로 #기호를 써서 선언을 해줘야 한다.
// 정사각형을 나타내는 객체
class Square {
// private 속성: 클래스 내부에서만 접근 가능한 속성
#length;
constructor(length) {
if (length < 0) {
throw '길이는 0 이상이어야 합니다.';
}
this.#length = length;
}
getArea() {
return this.#length * this.#length;
}
getPerimeter() {
return 4 * this.#length;
}
}
const square = new Square(10);
console.log(square.getArea()); // 100
console.log(square.getPerimeter()); // 40
console.log(square.#length = 20) // error:Uncaught SyntaxError: Private field '#length' must be declared in an enclosing class
이렇게 작성하게 되면 클래스 내부에서는 아무 문제없이 작동하게 되지만 클래스 외부에서는 length속성 값에 접근을 할 수 없게 된다.
게터(Getter)와 세터(Setter)
private 속성을 사용하면 외부에서는 #length 속성에 아예 접근할 수 없는 문제가 발생한다. 현재 square 객체의 length 속성이 몇인지 확인할 수도 없고, length 속성을 변경하고 싶어도 변경할 수 없다.
그래서 이때는 상황에 따라서 속성을 읽고 쓸 수 있는 getter와 setter 메소드를 만들어서 제공한다.
// 정사각형을 나타내는 객체
class Square {
// private 속성: 클래스 내부에서만 접근 가능한 속성
#length;
constructor(length) {
if (length < 0) {
throw '길이는 0 이상이어야 합니다.';
}
this.#length = length;
}
getArea() {
return this.#length * this.#length;
}
getPerimeter() {
return 4 * this.#length;
}
setLength(length) {
if (length < 0) {
throw '길이는 0 이상이어야 합니다.';
}
this.#length = length;
}
getLength() {
return this.#length;
}
}
const square = new Square(10);
console.log(square.getArea()); // 100
console.log(square.getPerimeter()); // 40
console.log(square.getLength()); // 10
square.setLength(20);
console.log(square.getLength()); // 20
이때 get○○() 메소드처럼 속성 값을 확인할 때 사용하는 메소드를 게터(getter)라고 부르며, set○○()메소드처럼 속성에 값을 지정할 때 사용하는 메소드를 세터(setter)라고 부른다.
위 코드를 더 쉽게 작성하고 사용할 수 있도록 get키워드와 set키워드 문법을 활용할 수 있다.
// 정사각형을 나타내는 객체
class Square {
// private 속성: 클래스 내부에서만 접근 가능한 속성
#length;
constructor(length) {
if (length < 0) {
throw '길이는 0 이상이어야 합니다.';
}
this.#length = length;
}
get area() {
return this.#length * this.#length;
}
get perimeter() {
return 4 * this.#length;
}
set length(length) {
if (length < 0) {
throw '길이는 0 이상이어야 합니다.';
}
this.#length = length;
}
get length() {
return this.#length;
}
}
const square = new Square(10);
console.log(square.area);
console.log(square.perimeter);
console.log(square.length);
square.length = 20;
console.log(square.length);
Square 클래스가 가지고 있던 모든 get○○()과 set○○()형태의 코드에서 get과 set 뒤에 띄어쓰기를 넣었다. 클래스쪽은 큰 변경이 없는 것 같지만, 클래스를 활용하는 쪽에서는 단순하게 속성을 사용하는 형태처럼 게터와 세터를 사용할 수 있게 되었다.
결론 : private 속성은 클래스를 더 안전하게 사용하기 위해 나온 기능이다. 게터와 세터는 private 속성에 접근하기 위해 만들어진 것이다. get/set 키워드는 게터와 세터를 더 유연하게 사용하기 위해서 나온 문법이다.
'Javascript' 카테고리의 다른 글
자바스크립트 - Class 도입 (0) | 2022.12.09 |
---|---|
자바스크립트 - 구문 오류와 예외 (2) | 2022.12.05 |
자바스크립트 - 객체의 기본 속성 지정하기 (0) | 2022.11.29 |
자바스크립트 - 객체의 기본 (1) | 2022.11.12 |
자바스크립트 - 함수 (0) | 2022.11.12 |