UPDATE 2015:
Jak podkreślił 7 „s odpowiedź , teraz ES6 (ECMAScript 2015) została sfinalizowana, bardziej odpowiednia dokumentacja jest już dostępny:
Oryginalna odpowiedź (dla (historycznego) zrozumienia i dodatkowych przykładów) :
Reflection proposalWydaje się, że postęp w projekcie specyfikacji ECMAScript 6 . Ten dokument obecnie przedstawia w Reflectzarysie metody -obiektu i podaje tylko następujące informacje Reflectdotyczące samego -obiektu:
Obiekt Reflect to pojedynczy zwykły obiekt.
Wartość wewnętrznego gniazda [[Prototype]] obiektu Reflect to standardowy wbudowany obiekt prototypowy Object (19.1.3).
Obiekt Reflect nie jest obiektem funkcji. Nie ma wewnętrznej metody [[Construct]]; nie jest możliwe użycie obiektu Reflect jako konstruktora z operatorem new . Obiekt Reflect również nie ma wewnętrznej metody [[Call]]; nie jest możliwe wywołanie obiektu Reflect jako funkcji.
Jednak istnieje krótkie wyjaśnienie jego celu w ES Harmony :
Moduł „@reflect” służy wielu celom:
- Teraz, gdy mamy moduły, moduł „@reflect” jest bardziej naturalnym miejscem dla wielu metod odbicia zdefiniowanych wcześniej w Object. Ze względu na kompatybilność wsteczną jest mało prawdopodobne, że metody statyczne w Object znikną. Jednak nowe metody powinny być prawdopodobnie dodane do modułu „@reflect” zamiast do konstruktora Object.
- Naturalne miejsce dla serwerów proxy, eliminujące potrzebę globalnego wiązania proxy.
- Większość metod w tym module mapuje jeden do jednego na pułapki proxy. Programy obsługi proxy potrzebują tych metod do wygodnego przesyłania dalej operacji, jak pokazano poniżej.
Tak więc Reflect obiekt zapewnia szereg funkcji narzędziowych, z których wiele wydaje się pokrywać z metodami ES5 zdefiniowanymi w globalnym Object.
Jednak to nie wyjaśnia, jakie istniejące problemy ma to rozwiązać, ani jakie funkcje zostały dodane. Podejrzewałem, że można to zniwelować i rzeczywiście, powyższa specyfikacja harmonii łączy się z „nienormatywną, przybliżoną implementacją tych metod” .
Zbadanie tego kodu może dać (dalsze) wyobrażenie o jego użyciu, ale na szczęście istnieje również wiki, które przedstawia szereg powodów, dla których obiekt Reflect jest przydatny :
(Skopiowałem (i sformatowałem) następujący tekst do wykorzystania w przyszłości z tego bo to jedyne przykłady, jakie udało mi się znaleźć. Poza tym mają sens, mają już dobre wyjaśnienie i dotykają applyprzykładu pytania ).
Bardziej przydatne wartości zwracane
Wiele operacji w programie Reflectjest podobnych do operacji ES5 zdefiniowanych w Object, takich jak Reflect.getOwnPropertyDescriptori Reflect.defineProperty. Jednak podczas gdy funkcja Object.defineProperty(obj, name, desc)zwróci, objgdy właściwość została pomyślnie zdefiniowana, lub wyrzuci w TypeErrorprzeciwnym razie, określono Reflect.defineProperty(obj, name, desc)po prostu zwrócenie wartości logicznej, która wskazuje, czy właściwość została pomyślnie zdefiniowana. Pozwala to na refaktoryzację tego kodu:
try {
Object.defineProperty(obj, name, desc);
} catch (e) {
}
Do tego:
if (Reflect.defineProperty(obj, name, desc)) {
} else {
}
Inne metody, które zwracają taki logiczny status sukcesu, to Reflect.set(aby zaktualizować właściwość), Reflect.deleteProperty(aby usunąć właściwość), Reflect.preventExtensions(aby obiekt nie był rozszerzalny) i Reflect.setPrototypeOf(aby zaktualizować łącze prototypu obiektu).
Operacje pierwszej klasy
W ES5 sposobem na wykrycie, czy obiekt objdefiniuje lub dziedziczy określoną nazwę właściwości, jest zapis (name in obj). Podobnie, aby usunąć właściwość, używa się delete obj[name]. Chociaż dedykowana składnia jest ładna i krótka, oznacza to również, że musisz jawnie opakować te operacje w funkcje, jeśli chcesz przekazać operację jako wartość pierwszej klasy.
Dzięki temu Reflectoperacje te można łatwo zdefiniować jako funkcje pierwszej klasy:
Reflect.has(obj, name)jest funkcjonalnym odpowiednikiem (name in obj)i Reflect.deleteProperty(obj, name)jest funkcją, która robi to samo, codelete obj[name].
Bardziej niezawodna aplikacja funkcji
W ES5, gdy chce się wywołać funkcję fze zmienną liczbą argumentów spakowanych jako tablica argsi wiążącą thiswartość do obj, można napisać:
f.apply(obj, args)
Jednak fmoże to być obiekt, który celowo lub nieumyślnie definiuje własną applymetodę. Jeśli naprawdę chcesz się upewnić, że applywywoływana jest funkcja wbudowana , zazwyczaj pisze się:
Function.prototype.apply.call(f, obj, args)
Jest to nie tylko gadatliwe, ale szybko staje się trudne do zrozumienia. Dzięki Reflect, możesz teraz wykonać niezawodne wywołanie funkcji w krótszy i łatwiejszy do zrozumienia sposób:
Reflect.apply(f, obj, args)
Konstruktory ze zmiennymi argumentami
Wyobraź sobie, że chcesz wywołać funkcję konstruktora ze zmienną liczbą argumentów. W ES6, dzięki nowej składni spreadów, będzie można pisać kod taki jak:
var obj = new F(...args)
W ES5 jest to trudniejsze do napisania, ponieważ można używać F.applylub F.callwywoływać tylko funkcję ze zmienną liczbą argumentów, ale nie ma F.constructfunkcji do newfunkcji ze zmienną liczbą argumentów. Dzięki Reflect, można teraz pisać, w ES5:
var obj = Reflect.construct(F, args)
Domyślne zachowanie przekazywania dla pułapek proxy
Podczas używania Proxyobiektów do zawijania istniejących obiektów, bardzo często przechwytuje się operację, robi coś, a następnie „robi coś domyślnego”, co zazwyczaj polega na zastosowaniu przechwyconej operacji na opakowanym obiekcie. Na przykład, powiedzmy, że chcę po prostu rejestrować dostęp do wszystkich właściwości obiektu obj:
var loggedObj = new Proxy(obj, {
get: function(target, name) {
console.log("get", target, name);
}
});
Funkcje API Reflecti zostały zaprojektowane w tandemie , tak że dla każdej pułapki istnieje odpowiednia metoda, która „robi coś domyślnego”. Dlatego za każdym razem, gdy chcesz wykonać „domyślną” czynność wewnątrz procedury obsługi proxy, należy zawsze wywołać odpowiednią metodę w obiekcie:ProxyProxyReflectReflect
var loggedObj = new Proxy(obj, {
get: function(target, name) {
console.log("get", target, name);
return Reflect.get(target, name);
}
});
Zwracany typ Reflectmetod jest zgodny z typem zwracanym Proxypułapek.
Kontroluj to powiązanie akcesorów
W ES5 dość łatwo jest wykonać ogólny dostęp do właściwości lub aktualizację właściwości. Na przykład:
var name = ...
obj[name]
obj[name] = value
Te Reflect.geti Reflect.setmetody pozwalają zrobić to samo, ale dodatkowo przyjąć jako ostatnia opcjonalnym argumentem jest receiverparametr, który pozwala jawnie ustawić this-binding gdy właściwość, że masz / zestaw jest accessor:
var name = ...
Reflect.get(obj, name, wrapper)
Reflect.set(obj, name, value, wrapper)
Jest to czasami przydatne, gdy pakujesz obji chcesz, aby wszelkie wysyłki własne w akcesorium zostały przekierowane do twojego opakowania, np. Jeśli objjest zdefiniowane jako:
var obj = {
get foo() { return this.bar(); },
bar: function() { ... }
}
Wywołanie Reflect.get(obj, "foo", wrapper)spowoduje this.bar()przekierowanie połączenia do wrapper.
Unikaj dziedzictwa __proto__
W niektórych przeglądarkach __proto__jest definiowana jako specjalna właściwość, która zapewnia dostęp do prototypu obiektu. ES5 ustandaryzowała nową metodę Object.getPrototypeOf(obj)odpytywania prototypu. Reflect.getPrototypeOf(obj)robi dokładnie to samo, z tą różnicą, że Reflectdefiniuje również odpowiedni Reflect.setPrototypeOf(obj, newProto)do ustawienia prototyp obiektu. Jest to nowy sposób aktualizowania prototypu obiektu, zgodny z ES6.
Należy pamiętać, że: setPrototypeOf również istnieje naObject (jak słusznie wskazał KNU „s komentarzu )!
EDYCJA:
Uwaga dodatkowa (adresowanie komentarzy do pytającego): Istnieje krótka i prosta odpowiedź na temat „P: Moduły ES6 a import HTML”, która wyjaśnia Realmsi przedstawia Loaderobiekty.
Inne wyjaśnienie można znaleźć pod tym linkiem :
Obiekt obszaru abstrakcyjnie wyodrębnia pojęcie odrębnego globalnego środowiska, z własnym globalnym obiektem, kopią standardowej biblioteki i „elementami wewnętrznymi” (standardowe obiekty, które nie są powiązane ze zmiennymi globalnymi, jak początkowa wartość Object.prototype).
Rozszerzalna sieć : jest to dynamiczny odpowiednik tego samego źródła
<iframe>bez DOM.
Warto jednak wspomnieć: wszystko to jest wciąż w wersji roboczej, to nie jest specyfikacja wyryta w kamieniu! To ES6, więc pamiętaj o zgodności z przeglądarkami!
Mam nadzieję że to pomoże!
Reflectjest to tylko pojemnik naRealmiLoaderobiekty, ale nie wiem, co robią te ostatnie.