javascript 비공개 프로퍼티와 메소드, class prototype private public
javascript 비공개 프로퍼티와 메소드, class prototype private public
javascript 프로퍼티와 메소드를 private하게 활용하는 방법을 알아보겠습니다.
이번 포스팅의 선행학습이 되어야 하는 내용은 아래의 Link를 참고하세요!
Link : https://aljjabaegi.tistory.com/586
Link : https://aljjabaegi.tistory.com/542
Link : https://aljjabaegi.tistory.com/543
예로 Test라는 class를 생성하겠습니다.
class Test{
constructor(){
this.name = "이건";
this.getName = function(){
return this.name;
}
}
}
const test = new Test();
console.log(test);
console.log(test.name);
console.log(test.getName());
Test 생성자에 변수 name과 getName 메서드를 추가하였습니다.
위의 코드의 실행결과를 보겠습니다.
name과 getName 모두 공개변수/메서드로
콘솔의 결과를 보면 test.name과 test.getname() 으로 this.name에 접근 할 수 있다는 것을 알 수 있습니다.
비공개 변수
이제 name이라는 변수를 비공개 변수로 바꾸어보겠습니다.
class Test{
constructor(){
const name = "이건";
this.getName = function(){
return name;
}
}
}
const test = new Test();
console.log(test);
console.log(test.name);
console.log(test.getName());
name변수를 const 로 선언하고 getName 메서드에 리턴을 name으로 변경해주었습니다.
결과를 보면 test.name으로는 접근 못하는 것(undefined)을 확인 할 수 있습니다.
getName과 같이 비공개 변수에 접근 할 수 있게 해주는 메서드를 특권(Privileged)메서드라고 합니다.
비공개 변수 사용 시 주의점
비공개 변수를 사용할 때 주의해야될 점이 있습니다.
위에 예처럼 비공개 변수를 기본타입로 선언했을 경우에는 해당 값을 리턴하지만, 참조타입으로 선언했을 경우는
값이 아닌 참조값을 리턴하기 때문에 비공개 변수의 값을 바꿀 수 있습니다.
class Test{
constructor(){
const array = [1,2,3];
const object = {
name : "이건"
}
this.getArray = function(){
return array;
}
this.getObject = function(){
return object;
}
}
}
const test = new Test();
const arr = test.getArray();
const obj = test.getObject();
arr[0] = 0;
obj.name = "알짜배기"
console.log(test.getArray());
console.log(test.getObject());
비공개 참조변수의 값을 바꾸지 못하게 하기 위해선 새로운 객체를 생성해 리턴하도록 합니다.
class Test{
constructor(){
const array = [1,2,3];
const object = {
name : "이건"
}
this.getArray = function(){
const newArray = JSON.stringify(array);
return JSON.parse(newArray);
}
this.getObject = function(){
const newObject = JSON.stringify(object);
return JSON.parse(newObject);
}
}
}
const test = new Test();
const arr = test.getArray();
const obj = test.getObject();
arr[0] = 0;
obj.name = "알짜배기"
console.log(test.getArray());
console.log(test.getObject());
프로토타입의 특권 메서드
이제 프로토타입에서의 특권메소드 활용에 대해서 알아보겠습니다.
ParentTest object를 리턴하는 즉시 실행 함수를 만들고 Test의 prototype으로 설정합니다.
const ParentTest = (function(){
const age = 36;
return {
getAge: function(){
return age;
}
}
}());
class Test{
constructor(){
const name = "이건";
this.getName = function(){
return name;
}
}
}
Object.setPrototypeOf(Test.prototype, ParentTest);
const test = new Test();
console.log(test);
console.log(test.getName());
console.log(test.getAge());
prototype으로 설정된 ParentTest age가 closure로 동작하며 prototype의 age 변수는 비공개 메소드가 됩니다.
클래스의 공개/비공개 멤버(변수/메소드) 설정
이제 생성한 class의 공개 비공개 멤버를 설정하는 방법을 알아보겠습니다.
내부적으로 사용하는 멤버를 비공개 멤버로,
외부에 노출해야하는 멤버를 공개 멤버로 설정하는 방법을 알아보겠습니다.
클래스의 생성자 내에서 새로운 Object를 만들어 return 해 주시면 됩니다.
class Test{
constructor(){
this.name = "이건";
this.age = 36;
return {
getName : this.getName.bind(this),
age : this.age
}
}
getName(){
return this.name;
}
getAge(){
return this.age;
}
}
const test = new Test();
console.log(test);
console.log(test.getName());
console.log(test.name);
console.log(test.getAge());
Test class의 공개 변수로 name과 age가 있고 class의 prototype으로 getName과 getAge 메소드가 있습니다.
이 중에서 prototype의 getName 메소드와 age 만 Object 리터럴로 리턴해주어 공개 멤버로 설정합니다.
return 되는 Object에서 this.getName에 bind를 해주는 리턴된 결과의 this가 리터럴로 리턴한 Object가 되어 name이 undefined가 되기때에 Test객체의 this로 설정해준 것 입니다.
결과를 보시면 리턴된 test에는 age 변수와 getName 메서드가 있으며
name과 getAge로는 접근이 안되는 것을 확인하실 수 있습니다.