Array()
클래스를 이용한 코드를 보다가 문득 이상한 점을 발견했다.
클래스(객체 생성자 함수)를 클래스 호출(new
호출)이 아닌 일반 함수 호출(new
없이 호출)하는 것이었다.
JS의 클래스는 사실 함수이기 때문에 일반 함수로 호출은 가능하더라도 정상적으로 동작할 수 없는데 정상적으로 동작했다.
그러면 new
연산자(operator)가 꼭 필요한 건가?
또는 새로운 유형의 클래스인가?
숨겨진 내용이 있는 것 같아 Array()
와 new
연산자(operator)에 대해 찾아보았다.
new
없이 일반 함수 호출하면class
로 선언한 클래스(객체 생성자 함수)ES6
이후 부터 이용하는 class
문법에서는 TypeError
가 나와 진행 불가.class Animal {
constructor(type, name, sound) {
this.type = type;
this.name = name;
this.sound = sound;
this.say = () => console.log(this.sound);
}
}
const pig = Animal('돼지', '꿀꿀이', '꿀꿀'); // TypeError: Class constructor Animal cannot be invoked without 'new'
function
으로 선언한 클래스(객체 생성자 함수)this
가 무시.function Animal(type, name, sound) {
this.type = type;
this.name = name;
this.sound = sound;
this.say = () => console.log(this.sound);
}
const pig = Animal('돼지', '꿀꿀이', '꿀꿀');
console.log(pig.type); // TypeError: Cannot read properties of undefined
console.log(pig.sound); // TypeError: Cannot read properties of undefined
console.log(type); // 돼지
console.log(sound); // 꿀꿀
new.target
프로퍼티new.target
프로퍼티를 사용하면 클래스 호출인지 일반 함수 호출인지 구분.new.target
은 일반 함수 호출 시 undefined
반환.new
호출)은 클래스 자체 반환.new.
는 객체가 아니고 가상 문맥.function Animal(type, name, sound) {
console.log(new.target);
this.type = type;
this.name = name;
this.sound = sound;
this.say = () => console.log(this.sound);
}
const pig = Animal('돼지', '꿀꿀이', '꿀꿀'); // undefined
const dog = new Animal('강아지', '멍멍이', '멍멍'); // [Function: Animal]
class
문법에서도 동작.class Animal {
constructor(type, name, sound) {
console.log(new.target);
this.type = type;
this.name = name;
this.sound = sound;
this.say = () => console.log(this.sound);
}
}
const pig = new Animal('돼지', '꿀꿀이', '꿀꿀'); // [class Animal]
ES6 class
문법에서는 이용 불가능.function Animal(type, name, sound) {
if (!new.target) {
return console.log(`${name}는(은) "${sound}" 소리를 내요.`);
}
this.type = type;
this.name = name;
this.sound = sound;
this.say = () => console.log(this.sound);
}
const pigA = Animal('돼지', '꿀꿀이', '꿀꿀'); // 꿀꿀이는(은) "꿀꿀" 소리를 내요.
const pigB = new Animal('돼지', '꿀꿀이', '꿀꿀');
pigB.say(); // 꿀꿀
ES6 class
문법에서는 이용 불가능.function Animal(type, name, sound) {
if (!new.target) {
return new Animal(type, name, sound); // new가 없으면 return으로 붙여줌.
}
this.type = type;
this.name = name;
this.sound = sound;
this.say = () => console.log(this.sound);
}
const pig = Animal('돼지', '꿀꿀이', '꿀꿀'); // new 없이 호출.
console.log(pig.type); // 돼지
console.log(pig.sound); // 꿀꿀
내장 클래스가 언제부터(ES5 이전과 ES6이후) 내장되었냐에 따라서;
즉, class
문법으로 정의 되었는지 function
문법으로 정의 되었는지에 따라 다른것 같다.
Array()
클래스는 function
으로 정의 되었고, new.target
프로퍼티로 클래스 호출과 일반 함수 호출 관련 없이 같은 동작을 하도록 설계 된 것이다.
const a = Array(5);
console.log(b.length); // 5
console.log(typeof b); // object
이러한 클래스가 몇 개 더 존재 하는데 Error()
, Function()
등이 있다.
다만 new
를 이용하면 누구나 클래스와 인스턴스 생성임을 알 수 있고, 모든 클래스에 일관적으로(모든 클래스가 어떻게 동작하는지 알지 못하기) 쓸수있기 때문에 new
이용을 지향해야 하고, ES6
의 class
문법의 의도(if(!new.target)
제한) 또한 동일하다고 생각한다.