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 proposal
Wydaje się, że postęp w projekcie specyfikacji ECMAScript 6 . Ten dokument obecnie przedstawia w Reflect
zarysie metody -obiektu i podaje tylko następujące informacje Reflect
dotyczą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ą apply
przykładu pytania ).
Bardziej przydatne wartości zwracane
Wiele operacji w programie Reflect
jest podobnych do operacji ES5 zdefiniowanych w Object
, takich jak Reflect.getOwnPropertyDescriptor
i Reflect.defineProperty
. Jednak podczas gdy funkcja Object.defineProperty(obj, name, desc)
zwróci, obj
gdy właściwość została pomyślnie zdefiniowana, lub wyrzuci w TypeError
przeciwnym 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 obj
definiuje 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 Reflect
operacje 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ę f
ze zmienną liczbą argumentów spakowanych jako tablica args
i wiążącą this
wartość do obj
, można napisać:
f.apply(obj, args)
Jednak f
może to być obiekt, który celowo lub nieumyślnie definiuje własną apply
metodę. Jeśli naprawdę chcesz się upewnić, że apply
wywoł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.apply
lub F.call
wywoływać tylko funkcję ze zmienną liczbą argumentów, ale nie ma F.construct
funkcji do new
funkcji 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 Proxy
obiektó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 Reflect
i 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:Proxy
Proxy
Reflect
Reflect
var loggedObj = new Proxy(obj, {
get: function(target, name) {
console.log("get", target, name);
return Reflect.get(target, name);
}
});
Zwracany typ Reflect
metod jest zgodny z typem zwracanym Proxy
puł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.get
i Reflect.set
metody pozwalają zrobić to samo, ale dodatkowo przyjąć jako ostatnia opcjonalnym argumentem jest receiver
parametr, 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 obj
i chcesz, aby wszelkie wysyłki własne w akcesorium zostały przekierowane do twojego opakowania, np. Jeśli obj
jest 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 Reflect
definiuje 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 Realms
i przedstawia Loader
obiekty.
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!
Reflect
jest to tylko pojemnik naRealm
iLoader
obiekty, ale nie wiem, co robią te ostatnie.