클래스에서 arrow function은 오버라이딩 될 수 없다.
기존에 클래스는 method 정의만 가능했다. 즉, 클래스 내부의 constructor와 method 정의로만 해당 클래스의 메서드를 정의할 수 있다.
하지만 class-properties-proposal 을 사용하면 4가지 방식의 클래스 프로퍼티를 생성할 수 있다.
class Book {
instanceProperty = 'bork';
boundFunction = () => {
return this.instanceProperty;
};
static staticProperty = 'babeliscool';
static staticFn = function() {
return Bork.staticProperty;
};
}
이제 내가 헷갈린 오버라이딩 예제를 보자.
class Animal {
constructor(sound = '??') {
this.sound = sound;
}
setNickname(nickname) {
this.nickname = nickname;
}
arrowNotHerited = () => {
console.log('in Animal');
};
}
class Dog extends Animal {
constructor() {
super('wal wal');
this.species = 'mixed';
}
setNickName(nickname) {
this.nickname = 'doggy_' + nickname;
console.log('overriding fn called');
}
arrowNotHerited() {
console.log('in Dog');
}
}
const baduk = new Dog('urururur');
baduk.setNickname('baduk'); // overriding fn called
baduk.arrowNotHerited(); // in dog
arrowNotHerited 메서드는 오버라이딩 되지 않는다.
transpile을 통해 무슨일이 일어났는지 알아보자.
// after transpile
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true,
});
} else {
obj[key] = value;
}
return obj;
}
var Animal =
/*#__PURE__*/
(function() {
function Animal() {
var sound =
arguments.length > 0 && arguments[0] !== undefined
? arguments[0]
: '??';
_defineProperty(this, 'arrowNotHerited', function() {
console.log('can not called in child');
});
this.sound = sound;
}
_createClass(Animal, [
{
key: 'setNickname',
value: function setNickname(nickname) {
this.nickname = nickname;
},
},
]);
return Animal;
})();
Object.defineProperty 객체에 직접 새로운 속성을 정의하거나, 이미 존재하는 속성을 수정한 후 그 객체를 반환.
_defineProperty(this, 'arrowNotHerited', function() {
console.log('can not called in child');
});
Animal 생성자 함수에서 arrowNotHerited를 직접할당
this는 생성자 함수 실행시 생성되는 인스턴스
즉, prototype 객체에 할당되지 않는다.
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
_createClass(Animal, [
{
key: 'setNickname',
value: function setNickname(nickname) {
this.nickname = nickname;
},
},
]);
setNickname은 contructor.prototype에 할당
그러므로, setNickname은 오버라이딩이 잘 동작한다
class 내부의 화살표 함수 선언시 standard 문법이 없다. 그러므로, class-properties 플러그인을 통해 선언할 수 있다. 이를 이용하여 클래스 내부 화살표 함수 선언시, prototype 객체가 아닌 new 생성자로 생성된 인스턴스에 할당된다.
Animal, Dog 클래스의 예제에서, new Dog.arrowNotHerited() 호출시, 프로토타입체이닝을 확인하기 전에 instance내의 메서드(arrowNotHerited)를 호출한다.