Object()
를 제공한다.//Object()를 이용해서 빈 cat 객체 생성
const cat = new Object();
//cat 객체 프로퍼티 생성
cat.name='방울';
cat.age='4';
cat.gender='female';
console.log(typeof cat); //object
console.log(cat); // {name: '방울', age: '4', gender: 'female'}
‘프로퍼티 이름' : ‘프로퍼티 값’
형태로 표기하여 해당 프로퍼티가 추가된 객체를 생성할 수 있다. 이 때 프로퍼티 값이 함수인 경우, 이를 메소드라고 한다.const cat = {
name : '방울',
age : 4,
gender : 'female',
says : function(){
console.log('야옹')
}
}
new 연산자
를 붙여서 호출하면 해당 함수가 생성자 함수로 동작하게 된다.// Cat() 생성자 함수
const Cat = function (name) {
this.name = name;
}
// bangul 객체 생성
const bangul = new Cat('방울');
console.log(bangul.name);
// 방울
객체 리터럴 방식으로 생성된 객체는 같은 형태의 객체를 재생성할 수 없다.
이에 반해 생성자 함수를 사용하여 객체를 생성하면, 생성자 함수를 호출할 때 다른 인자를 넘김으로써 같은 형태의 서로 다른 객체 bar와 baz를 생성할 수 있다.
// 객체 리터럴 방식으로 foo객체 생성
var foo = {
name: 'foo',
age: 35,
gender: 'man'
}
console.dir(foo);
// 생성자 함수
function Person(name, age, gender, position) {
this.name = name;
this.age = age;
this.gender = gender;
this.position = position;
}
// Person 생성자 함수를 이용해 bar 객체, baz 객체 생성
var bar = new Person('bar', 33, 'woman')
console.dir(bar)
var baz = new Person('baz', 25, 'woman')
console.dir(baz)
function Champion(){
this.q = 'strike';
this.w = 'snowball';
}
const nunu = new Champion();
상속 기능을 구현하는 장치. 자식에게 어떤 형질을 물려줄지 결정하는 유전자와 비슷하다.
nunu는 item 속성을 직접 가지고 있지 않지만 item 속성을 사용할 수 있다.
Array 자료형에 기본적으로 사용할 수 있는 .sort()
등의 메서드가 있다. Array 내의 원소만 추가해 주었고 .sort()를 추가한 적 없는데 .sort()를 사용 가능한 이유가 무엇일까?
Array() 의 prototype(유전자) 에 .sort(), .length 등이 정의되어있기 때문이다.
Array.prototype.함수 = function(){}
prototype을 활용하면 모든 Array type에 사용이 가능한 함수를 만들 수 있다.
ES6의 클래스가 도입되기 이전에는 생성자 함수로 프로토타입 기반의 인스턴스를 생성하였다. 클래스와 생성자 함수는 모두 프로토타입 기반의 인스턴스를 생성하지만 정확히 동일한 동작을 하지는 않는다.
클래스의 몸체에서는 constructor
가 생성자 역할을 한다. 인스턴스를 생성, 초기화 하는 특수한 메서드이므로 이름 변경이 불가능하다. 아래와 같은 코드로 클래스를 만들고 인스턴스를 생성하는 것이 가능하다.
constructor는 클래스 내에 최대 1개만 존재 가능하다.
class Cat {
// 생성자 역할을 합니다.
constructor(name){
// 인스턴스 생성 및 초기화 진행이 가능합니다.
this.name = name;
}
meow(){console.log(this.name + ': 야옹')}
}
// 클래스를 호출하여 인스턴스를 만들었습니다.
const myCat = new Cat('bangul');
Cat() 이라는 이름을 가진 함수를 만든다. 함수 본문은 생성자 메서드 constructor
에서 가져온다. 생성자 메서드가 없으면 본문이 비워진 채로 함수가 만들어진다.
meow()
와 같이 클래스 내에서 정의한 메서드를 Cat.prototype
에 저장한다.
만약 프로토타입으로 메서드를 만들어주지 않는 경우에는 인스턴스가 생성될 때마다 계속해서 메서드를 생성해 주어야 한다. 클래스는 보다 더 간결하게 프로토타입 메서드를 생성하는 것이 가능하다.
class Cat {
// 생성자 역할을 합니다.
constructor(name){
// 인스턴스 생성 및 초기화 진행이 가능합니다.
this.name = name;
}
// 프로토타입 메서드
meow(){console.log(this.name + ': 야옹')}
}
//클래스를 호출해서 인스턴스를 만들었습니다.
const myCat = new Cat('bangul');
//프로토타입 메서드를 호출했습니다.
myCat.meow() // bangul: 야옹
인스턴스는 프로토타입 메서드를 상속받아 사용하는 것이 가능하다. 즉 클래스도 결국은 생성자 함수와 마찬가지로 프로토타입 기반의 객체 생성 메커니즘인 것.
class Cat {
// 생성자 역할을 합니다.
constructor(name){
// 인스턴스 생성 및 초기화 진행이 가능합니다.
this.name = name;
}
// 프로토타입 메서드
meow(){console.log(this.name + ': 야옹')}
// 정적 메서드
static staticMeow(){console.log('미야웅')}
}
Cat.staticMeow(); // 미야웅
정적 메서드는 클래스에 바인딩된 메서드로, 인스턴스와 달리 별도의 생성 과정이 필요없기 때문에 클래스로 호출이 가능하다.
extends
는 상속과 관련된 키워드이고, super
는 수퍼클래스의 constructor 호출과 수퍼클래스의 메서드 호출을 가능하게 하는 키워드이다.// 부모 클래스인 Animal Class
class Animal {
constructor(weight, height){
this.weight = weight;
this.height = height;
}
}
// 상속을 통해 animal 클래스를 확장할 수 있습니다.
class Bird extends Animal{
fly(){
return 'fly';
}
}
수퍼 클래스의 Animal을 상속 받아 사용하므로(정확히는 수퍼 클래스인 Animal의 constructor가 객체를 만들어 서브 클래스에게 전달) 서브 클래스의 constructor 내부에서는 꼭 super()를 불러 주어야 함.
constructor(width,height, color) {
//super 클래스에서 width와 height를 상속받는 경우
super(width,height);
this.color = color;
}
만약 super 클래스에게서 그대로 상속을 받는다면 constructor를 생략할 수도 있지만, 서브 클래스에서도 초기화를 진행하고 싶다면 꼭 super()를 불러주고, 매개 변수에 전달할 인수도 필요함.
constructor(width, height, color){
// super 클래스에게서 width와 height를 상속받는 경우
super(width, height);
// 서브 클래스 자체에서 필요한 프로퍼티를 초기화 시켜줍니다.
this.color = color;
}
//상속 받는 매개 변수에 대한 인수도 같이 전달해 주어야 합니다.
const bird = new Bird(2,4,'red')