Dalej drążymy temat Proxy w JavaScript. Odtwarzamy na klasach coś, co już wcześniej robiliśmy, dzięki obiektowi Proxy. Do dzieła.

Ok, przypomnijmy sobie poprzednią lekcję o proxy, następnie ten fragment kodu (dawno temu przerabiany):

function Person(name, age){

  if(!new.target)
      return new Person(name, age);
    
  this.name = name;
  this.age = age;
}

let jim =  Person("Jim", 20);

console.log(jim);
//Object { name: "Jim", age: 20 }

Wiemy, że z klasami i konstruktorami nie możemy się bawić bez new jak tutaj. Cóż, jest to tylko częściowo prawda, bo Proxy pozwala nam robić rzeczy niemożliwe.

Poprzednio robiliśmy funkcje partial nie patrząc na kolejność argumentów, teraz zrobimy klasę z konstruktorem wywoływanym bez new.

Zacznijmy od napisania tej klasy:

class Person {
    constructor(name, age){
        this.name = name;
        this.age = age;
    }
}

let person = new Person("John", 33)

console.log(person);
//Object { name: "John", age: 33 }

let p2 = Person("Jane", 20);
//TypeError: class constructors must be invoked with 'new'

Zastanówmy się, jakie pułapki są tutaj wywoływane:

  • dla new Person – pułapka construct
  • dla Person… pułapka apply

Tak, apply. Tak samo jak sobie pożyczaliśmy konstruktory z funkcji-konstruktorów przez call (dziedziczenie w stylu ES5) tak samo, musimy zrozumieć, to jest wywołanie funkcji.

Tak wygląda nasz kod:

const PersonProxy = new Proxy(Person, {
    apply(target, thisArg, argumentsList){
        return new target(...argumentsList);
    }
})

let p2 = PersonProxy("Jane", 20);
console.log(p2);
//Object { name: "Jane", age: 20 }

Natomiast pułapka construct będzie wywoływana, gdy używamy new i możemy tam ustawiać różne ograniczenia, np. że konstruktor musi mieć jakieś argumenty przekazane, albo cokolwiek.

Koniec końców Proxy daje nam możliwości wcześniej w JavaScript niespotykane.