Uczymy się co nieco o Object.defineProperty oraz różnicach miedzy nowymi klasami a starym podejściem. Do dzieła.
Ok, tak wygląda klasa:
class PersonCls {
constructor(firstName, lastName){
this.firstName = firstName;
this.lastName = lastName;
}
fullname(){
return this.firstName + " " + this.lastName;
}
}
Jej odpowiednik w starym zapisie powinniśmy już umieć napisać:
function Person(firstName, lastName){
this.firstName = firstName;
this.lastName = lastName;
}
Person.prototype.fullname = function(){
return this.firstName + " " + this.lastName;
}
Jaka jest różnica? Cóż, jeżeli pomyśleliśmy sobie, że konstruktora z klasy nie możemy sobie pożyczyć, zaś funkcję Person już tak (jak każda funkcja, która ma w prototypie call, apply, bind) to już i tak dużo wiemy!
Ale jest jeszcze jedna różnica:
class PersonCls {
constructor(firstName, lastName){
this.firstName = firstName;
this.lastName = lastName;
}
fullname(){
return this.firstName + " " + this.lastName;
}
}
let p2 = new PersonCls("Jane", "Doe");
for(let key in p2){
console.log(key);
}
// firstName
// lastName
Pętla for in jest tą różnicą. Zobaczmy, jak to działa w funkcjach-konstruktorach:
function Person(firstName, lastName){
this.firstName = firstName;
this.lastName = lastName;
}
Person.prototype.fullname = function(){
return this.firstName + " " + this.lastName;
}
let p1 = new Person("John", "Doe");
for(let key in p1){
console.log(key);
}
// firstName
// lastName
// fullname
Funkcje dodawane przez prototyp są enumerable. Oczywiście, można to zmienić w dość kreatywny sposób:
function Person(firstName, lastName){
this.firstName = firstName;
this.lastName = lastName;
}
Object.defineProperty(Person.prototype, "fullname", {
enumerable: false,
value: function(){
return this.firstName + " " + this.lastName;
}
} )
let p1 = new Person("John", "Doe");
console.log(p1.fullname());
//John Doe
for(let key in p1){
console.log(key);
}
// firstName
// lastName
Jak widać value to może być funkcja. Wszystko działa, i nasza metoda nie pojawia się w pętli for in.