목적을 수행하기에 필요한 데이터와 함수를 동시에 갖고 있다면 편리.
const user = { };
user.name = "Julia";
user.score = 5;
user.increment = function() {
user.score ++;
}
function userCreator(name, age) {
const newUser = {};
newUser.age = age;
newUser.name = name;
newUser.increment = function () {
newUser.age ++;
};
return newUser;
};
이런 식으로 오브젝트를 생성한다면 모든 오브젝트가 펑션을 갖게 되며 많은 메모리를 낭비하게 된다.
또 문제는 이를 수정해야할때 모든 펑션을 다 고쳐야한다.
function userCreator(name, age) {
const newUser = Object.create(userFunctionStore);
newUser.name = name;
newUser.age = age;
return newUser;
};
const userFunctionStore = {
incrememnt: function() { this.score++};
login: function() { console.log("You're Logged In!"};
}:
펑션을 공유할수 있는 저장소를 만들어 이를 해결한다.
Object.create(null)
proto라는 특수한 프로퍼티를 갖는 오브젝트를 생성한다.
프로토는 Object.create( _ )에 들어오는 아규먼트를 참조할 수 있게 링크해준다.
따라서 newUser가 반환되고 난 후 increment를 찾을때 자동으로 userFunctionStore를 참조하여 increment를 실행한다.
그러나 이 방식은 새로운 반복 문제를 만든다.
저장소를 만들어야하고 그것을 연결해줘야하고 유저값을 계속 반환해줘야한다.
function UserCreator(name, age) {
const newUser = Object.create(userFunctionStore);
this.name = name;
this.age = age;
return newUser;
}
const userFunctionStore = {
increment : function() { this.age++;}
};
const user = UserCreator("doil", 3);
function UserCreator(name, age) {
this.name = name;
this.age = age;
}
UserCreator.prototype.increment = function() { this.age++; };
UserCreator.prototype.login = function() {
console.log("logged In");
};
const user = new userCreator("Doil", 6);
new 키워드를 사용해서 오브젝트를 생성하면 몇가지 수고를 덜할 수 있다.
prototype
프로토타입이라는 오브젝트가 생성되며 이곳에 공동으로 쓸 함수를 저장할 수 있다.
user라는 오브젝트가 생성 될때
this라는 오브젝트를 user 내부에 생성해주고
this 오브젝트 내부에 __proto__ 프로퍼티가 생성되는데
이곳에서 프로토타입 함수들을 연결해준다.
마지막으로 자동적으로 user에서 선언된 값들과 링크된 함수 정보가 저장된 this 오브젝트를 글로벌로 리턴해준다.
정리하자면 펑션은 오브젝트이다.
오브젝트는 prototype이라고 하는 오브젝트가 펑션 안에 생성되고 이 안에 공동으로 사용할 수 있는 펑션을 저장할 수 있게 된다.
new 키워드를 사용해서 오브젝트를 생성하면
this 키워드가 this 오브젝트를 생성해주며
this 오브젝트 안에 있는 __proto__프로퍼티가 prototype 저장소를 연결해준다.
function UserCreator(name, age) {
this.name = name;
this.age = age;
}
UserCreator.prototype.increment = function() {
function add() {
this.age++;
}
};
UserCreator.prototype.login = function() {
console.log("logged In");
};
프로토타입 펑션 내부에 서브펑션을 선언할때
this는 UserCreator의 아규먼트를 찾지 못하는 문제가 발생한다.
이 문제는 애로우 펑션으로 해결할 수 있다.
function UserCreator(name, age) {
this.name = name;
this.age = age;
}
UserCreator.prototype.increment = function() {
const add = () => {
this.age++;
}
};
UserCreator.prototype.login = function() {
console.log("logged In");
};
class UserCreator = {
constructor (name, age) {
this.name = name;
this.age = age;
}
increment() {
this.age ++;
}
}
const user = new UserCreator("jinhyung", 3);
결론 : 클래스를 쓰면 된다.
const obj = {
num: 3
}
obj.num
obj.hasOwnProperty
모든 오브젝트+펑션은 Object와 Function이라고 하는 펑션을 갖고 있다.
이 펑션은 오브젝트이며 Prototype이라고 하는 오브젝트를 갖고 있고
이 오브젝트에는 hasOwnProperty라는 펑션을 갖고 있다.
__proto__는 obj 오브젝트의 히든 프로퍼티로
Prototype 오브젝트에 접근하는 링크를 제공한다.
Function안에도 Prototype이 존재하며 이 펑션 오브젝트 안에는 toString, call, bind, apply와 같은 펑션들이 빌트인으로 제공된다.
class UserCreator {
constructor(name, score) {
this.name = name;
this.score = score;
}
increment() {
this.score++;
}
}
// class, super, this, extends
class paidUserCreator extends UserCreator {
constructor(paidName, paidScore, balance) {
super(paidName, paidScore);
this.balance = balance;
}
incrementBalance() {
this.balance++;
}
}
const paidUser = new paidUserCreator('tim', 30, 100);
console.log(paidUser.balance);
paidUser.increment();
console.log(paidUser.score);
console.log(paidUser.paidScore);
paidUser.incrementBalance(100);
console.log(paidUser.name);
console.log(paidUser.piadName);
console.log(paidUser.balance);
super를 사용하면 마치 this 처럼 UserCreator클래스를 참조하는 _\Proto_를 생성해서 링크해준다.