ATUALIZAÇÃO 2015:
Como apontado por 7ª 's resposta , agora que ES6 (ECMAScript 2015) foi finalizado, a documentação mais apropriado já está disponível:
Resposta original (para compreensão (histórica) e exemplos extras) :
O Reflection proposalparece ter progredido para a Especificação ECMAScript 6 do Projeto . Este documento atualmente descreve os Reflectmétodos do -objeto e afirma apenas o seguinte sobre o Reflectpróprio -objeto:
O objeto Reflect é um único objeto comum.
O valor do slot interno [[Prototype]] do objeto Reflect é o objeto de protótipo padrão interno do objeto (19.1.3).
O objeto Reflect não é um objeto de função. Ele não tem um método interno [[Construct]]; não é possível usar o objeto Reflect como um construtor com o novo operador. O objeto Reflect também não possui um método interno [[Call]]; não é possível invocar o objeto Reflect como uma função.
No entanto, há uma breve explicação sobre seu propósito no ES Harmony :
O módulo “@reflect” tem várias finalidades:
- Agora que temos módulos, um módulo “@reflect” é um lugar mais natural para muitos dos métodos de reflexão previamente definidos em Object. Para fins de compatibilidade com versões anteriores, é improvável que os métodos estáticos em Object desapareçam. No entanto, novos métodos provavelmente devem ser adicionados ao módulo “@reflect” ao invés do construtor Object.
- Um lar natural para proxies, evitando a necessidade de uma ligação de proxy global.
- A maioria dos métodos neste módulo mapeia um a um em armadilhas de proxy. Os manipuladores de proxy precisam desses métodos para encaminhar convenientemente as operações, conforme mostrado abaixo.
Portanto, o Reflectobjeto fornece várias funções de utilitário, muitas das quais parecem se sobrepor aos métodos ES5 definidos no objeto global.
No entanto, isso não explica realmente quais problemas existentes isso pretende resolver ou quais funcionalidades são adicionadas. Suspeitei que isso pudesse ser corrigido e, de fato, as especificações de harmonia acima se vinculam a uma 'implementação aproximada não normativa desses métodos' .
Examinar esse código pode dar (mais) idéias sobre seu uso, mas felizmente também há um wiki que descreve uma série de razões pelas quais o objeto Reflect é útil :
(Copiei (e formatei) o seguinte texto para referência futura daquele fonte pois são os únicos exemplos que consegui encontrar. Além disso, fazem sentido, já têm uma boa explicação e tocam no applyexemplo da pergunta .)
Valores de retorno mais úteis
Muitas operações em Reflectsão semelhantes às operações ES5 definidas em Object, como Reflect.getOwnPropertyDescriptore Reflect.defineProperty. No entanto, enquanto Object.defineProperty(obj, name, desc)irá retornar objquando a propriedade foi definida com sucesso, ou lançar um TypeErrorcaso contrário, Reflect.defineProperty(obj, name, desc)é especificado para simplesmente retornar um booleano que indica se a propriedade foi definida com sucesso ou não. Isso permite que você refatore este código:
try {
Object.defineProperty(obj, name, desc);
} catch (e) {
}
Para isso:
if (Reflect.defineProperty(obj, name, desc)) {
} else {
}
Outros métodos que retornam esse status de sucesso booleano são Reflect.set(para atualizar uma propriedade), Reflect.deleteProperty(para excluir uma propriedade), Reflect.preventExtensions(para tornar um objeto não extensível) e Reflect.setPrototypeOf(para atualizar o link de protótipo de um objeto).
Operações de primeira classe
No ES5, a maneira de detectar se um objeto objdefine ou herda um determinado nome de propriedade é escrever (name in obj). Da mesma forma, para excluir uma propriedade, usa-se delete obj[name]. Embora a sintaxe dedicada seja boa e curta, também significa que você deve envolver explicitamente essas operações em funções quando quiser passar a operação como um valor de primeira classe.
Com Reflect, essas operações são prontamente definidas como funções de primeira classe:
Reflect.has(obj, name)é o equivalente funcional de (name in obj)e Reflect.deleteProperty(obj, name)é uma função que faz o mesmo quedelete obj[name].
Aplicação de função mais confiável
No ES5, quando se deseja chamar uma função fcom um número variável de argumentos empacotados como uma matriz argse vincular o thisvalor a obj, pode-se escrever:
f.apply(obj, args)
No entanto, fpode ser um objeto que define intencionalmente ou não seu próprio applymétodo. Quando você realmente deseja ter certeza de que a applyfunção integrada é chamada, normalmente escreve-se:
Function.prototype.apply.call(f, obj, args)
Não é apenas prolixo, mas rapidamente se torna difícil de entender. Com o Reflect, agora você pode fazer uma chamada de função confiável de uma forma mais curta e fácil de entender:
Reflect.apply(f, obj, args)
Construtores de argumento variável
Imagine que você deseja chamar uma função construtora com um número variável de argumentos. No ES6, graças à nova sintaxe difundida, será possível escrever códigos como:
var obj = new F(...args)
No ES5, isso é mais difícil de escrever, porque só se pode usar F.applyou F.callchamar uma função com um número variável de argumentos, mas não há F.constructfunção para newa função com um número variável de argumentos. Com Reflect, agora é possível escrever, em ES5:
var obj = Reflect.construct(F, args)
Comportamento de encaminhamento padrão para armadilhas de proxy
Ao usar Proxyobjetos para encapsular objetos existentes, é muito comum interceptar uma operação, fazer algo e, em seguida, "fazer a coisa padrão", que normalmente é aplicar a operação interceptada ao objeto encapsulado. Por exemplo, digamos que eu queira simplesmente registrar todos os acessos de propriedade a um objeto obj:
var loggedObj = new Proxy(obj, {
get: function(target, name) {
console.log("get", target, name);
}
});
As APIs Reflecte foram projetadas em conjunto , de forma que para cada armadilha, existe um método correspondente que "faz a coisa padrão". Portanto, sempre que você quiser "fazer o padrão" dentro de um manipulador Proxy, a coisa correta a fazer é sempre chamar o método correspondente no objeto:ProxyProxyReflectReflect
var loggedObj = new Proxy(obj, {
get: function(target, name) {
console.log("get", target, name);
return Reflect.get(target, name);
}
});
O tipo de retorno dos Reflectmétodos tem garantia de compatibilidade com o tipo de retorno das Proxyarmadilhas.
Controlar esta ligação de acessores
No ES5 é bastante fácil fazer um acesso de propriedade genérico ou atualização de propriedade. Por exemplo:
var name = ...
obj[name]
obj[name] = value
Os métodos Reflect.gete Reflect.setpermitem que você faça a mesma coisa, mas, adicionalmente, aceitam como último argumento opcional um receiverparâmetro que permite definir explicitamente a this-binding quando a propriedade que você obtém / define é um acessador:
var name = ...
Reflect.get(obj, name, wrapper)
Reflect.set(obj, name, value, wrapper)
Isso é ocasionalmente útil quando você está empacotando obje deseja que qualquer envio automático dentro do acessador seja redirecionado para seu wrapper, por exemplo, se objfor definido como:
var obj = {
get foo() { return this.bar(); },
bar: function() { ... }
}
Chamar Reflect.get(obj, "foo", wrapper)fará com que a this.bar()chamada seja redirecionada para wrapper.
Evite legado __proto__
Em alguns navegadores, __proto__é definido como uma propriedade especial que dá acesso ao protótipo de um objeto. ES5 padronizou um novo método Object.getPrototypeOf(obj)para consultar o protótipo. Reflect.getPrototypeOf(obj)faz exatamente o mesmo, exceto que Reflecttambém define um correspondente Reflect.setPrototypeOf(obj, newProto)para definir o protótipo do objeto. Esta é a nova maneira compatível com ES6 de atualizar o protótipo de um objeto.
Note-se que: setPrototypeOf também existe emObject (como corretamente apontado por Knu 's comentário )!
EDIT:
Nota lateral (endereçando comentários ao Q): Há uma resposta curta e simples em 'Q: Módulos ES6 vs. Importações de HTML' que explica Realmse Loaderobjeta.
Outra explicação é oferecida por este link :
Um objeto de domínio abstrai a noção de um ambiente global distinto, com seu próprio objeto global, cópia da biblioteca padrão e "intrínsecos" (objetos padrão que não estão vinculados a variáveis globais, como o valor inicial de Object.prototype).
Web extensível : este é o equivalente dinâmico de uma mesma origem
<iframe>sem DOM.
Vale a pena mencionar: tudo isso ainda está em projeto, esta não é uma especificação gravada na pedra! É ES6, portanto, mantenha a compatibilidade do navegador em mente!
Espero que isto ajude!
Reflecté apenas um contêiner para objetosRealmeLoader, mas também não sei o que estes fazem.