이번 주차는 솔로위크이다. 스스로 복습&예습하는...!
JS에서 꽤나 중요한 prototype과 헷갈리는 this에 대해 정리한다. 정리하다가 더 도움될만한 내용은 그때 추가해야겠다!
Javascript의 모든 객체는 부모 역할을 하는 객체와 연결되어 있다. 객체 지향에서의 상속처럼 부모 객체의 프로퍼티나 메소드를 상속받아 사용한다. 이때 이 부모 객체를 prototype
이라 한다.
Prototype은 생성자 함수에 의해 생성된 각각의 객체에 공유 프로퍼티를 제공하기 위해 사용한다.
// 1. 생성자 함수
function Vehicle(type, wheel) {
this.type = type;
this.wheel = wheel;
}
// 2. 프로토타입에 공유 프로퍼티로 메소드 추가
Vehicle.prototype.hasWheel = function() {
console.log(`${this.type}은(는) 바퀴가 ${this.wheel} 개입니다...!`);
}
// 3. 인스턴스 생성
let BMW = new Vehicle('자동차', 4);
let MegaTruck = new Vehicle('트럭', 6);
BMW.hasWheel(); // 자동차은(는) 바퀴가 4 개입니다...!
MegaTruck.hasWheel(); // 트럭은(는) 바퀴가 6 개입니다...!
이 외에 다양한 적용방식이 있지만, 깊게 파봐야 헷갈린다. 그때그때 알아보자.
prototype에서도 사용했지만, this는 함수를 호출할 때 함수가 어떻게 호출되었는지에 따라 this에 바인딩할 객체가 동적으로 결정되므로, 다양하게 적용된다.
// 1. 콘솔에서의 전역 this
this === window // true
var ap = 'apple'
console.log(ap); // apple
console.log(window.ap); // apple
console.log(this.ap); // apple
// 2. 중첩 함수에서의 this
function aaa() {
console.log('aaa this: ' + this);
function bbb() {
console.log('bbb this: ' + this)
}
bbb();
}
aaa()
// aaa this: [object Window]
// bbb this: [object Window]
내부함수는 일반 함수, 메소드, 콜백함수 어디에서 선언되었든 관게없이 this는 전역객체를 바인딩한다.
메소드 내부의 this
는 해당 메소드를 호출한 객체에 바인딩된다.
// 1. 객체
var obj = {
name: 'sohee',
sayHello: function() {
console.log('Hi, ' + this.name);
}
}
obj.sayHello() // Hi, sohee
// 2. 생성자
function Person(name) {
this.name = name;
}
var person1 = new Person('sohee');
var person2 = new Person('dahyun');
person1.name // sohee
person2.name // dahyun
// 3. prototype
Person.prototype.sayHello = function() {
console.log(`Hi, ${this.name}`);
}
person1.sayHello(); // Hi, sohee
person2.sayHello(); // Hi, dahyun
// 4. new를 붙이지 않을 경우
var person3 = Person('sunee');
person3 // undefined
window.name // sunee -> this가 전역객체에 바인딩
apply는 배열, call은 풀어서, bind는 함수를 리턴!
// EX1
var Person = function(name) {
this.name = name;
}
var person1 = {};
var person2 = {};
Person.apply(person1, ['sohee']);
Person.call(person2, 'dahyun');
console.log(person1); // {name: "sohee"}
console.log(person2); // {name: "dahyun"}
// EX2
function Person(name, age, gender){
this.name = name;
this.age = age;
this.gender = gender;
}
const person3 = {}
Person.apply(person3, ['daye', 20, 'man']); // call을 사용하면 -> Person.call(person3, 'daye', 20, 'man')
console.log(person3) // {name: "daye", age: 20, gender: "man"}
// EX3. bind
function sayHello() {
console.log('Hi, ' + this.name);
}
const hiSohee = sayHello.bind(person1)
const hiDahyun = sayHello.bind(person2)
hiSohee() // Hi, sohee
hiDahyun() // Hi, dahyun