Refletir introdução:
O objeto refletir não foi implementado no meu nó (v4.4) e Babel (6.7.7) não é implementado. A nova versão do Chrome é suportada. O FF apoiou proxy e reflete por um longo tempo. Se você deseja que o nó suporte reflita, você pode instalar o Harmony-refletir;
Refletir não é um construtor. Quando usado, é chamado diretamente através do reflete.Method (). Alguns métodos de reflexo são semelhantes ao proxy e a maioria reflete os métodos objetos nativos foram reimplementados.
O que usar refletir
Aqui estão algumas razões pelas quais o reflete é usado. Endereço de tradução: refletir, traduzido aproximadamente:
1: Valor de retorno mais útil: reflete possui alguns métodos como o método de objeto no ES5, como: reflet.GetownPropertyDescriptor e Reflice.DefineProperty. No entanto, se o objeto.DefineProperty (OBJ, nome, desc) for executado com sucesso, ele retornará o OBJ e outros erros causados por outros motivos. Reflice.DefineProperty retornará apenas false ou verdadeiro para indicar se as propriedades do objeto foram definidas. O código a seguir pode ser reformado:
tente {object.DefineProperty (obj, nome, desc); // propriedade definida com sucesso} catch (e) {// Possível falha (e pode acidentalmente capturar a exceção errada)}Reconstruído assim:
if (reflete.DefineProperty (obj, nome, desc)) {// succcess} else {// falha}Os outros métodos, como o RECECT.SET, REFLEFER.DELETEPROPERTY, REFLEFT.PreventExtensions, reflet.SetPrototypeOf, podem ser refatorados;
2: Operação da função. Se você deseja determinar que um OBJ possui um nome definido ou herda o nome do atributo, você pode julgá -lo no ES5 como este: nome em obj;
Ou exclua um atributo: exclua obj [nome]. Embora sejam muito úteis, muito curtos e claros, eles também devem ser encapsulados em uma classe quando devem ser usados;
Com refletir, ajuda a encapsular, refletir.has (obj, nome), refletir.deleteProperty (obj, nome);
3: Método de execução funcional mais confiável: em ES, se você deseja executar uma função f e passar um conjunto de parâmetros args e vincular isso, você precisa escrever isso:
F.Apply (OBJ, Args)
No entanto, o aplicativo F pode ser redefinido como o próprio aplicativo do usuário, por isso é mais confiável para escrever desta maneira:
Function.prototype.apply.call (f, obj, args)
O código acima é muito longo e difícil de entender. Com refletir, podemos ser mais curtos e mais concisos e mais claros:
Reflete.Apply (f, obj, args)
4: Construtores na forma de parâmetros variádicos: imagine que você deseja instanciar um construtor através de parâmetros de comprimento incerto. No ES5, podemos usar símbolos de extensão, que podem ser escritos assim:
var obj = novo f (... args)
No entanto, no ES5, os caracteres de extensão não são suportados; portanto, podemos passar apenas parâmetros diferentes em F.Apply ou F.Call. Infelizmente, F é um construtor, que é uma farsa, mas com refletir,
Podemos escrever isso no ES5:
var obj = reflet.Construct (F, args)
5: Isso controla o acessador ou leitor: no ES5, se você quiser ler os atributos de um elemento ou definir os atributos da seguinte forma:
Var Nome = ... // Obtenha o nome da propriedade como um stringobj [nome] // Propriedade genérica LookuPOBJ [nome] = Valor // Propriedade genérica
Os métodos UpdateReflect.
var name = ... // Obtenha o nome da propriedade como um stringReflect.get (obj, nome, wrapper) // se obj [nome] for um acessador, ele é executado com `this === wrapper`reflect.set (obj, nome, valor, wrapper) o acessador não deseja usar seu próprio método, mas quer que seja redirect {varring: }, bar: function () {alert (1);}}; var wrapper = {bar: function () {console.log ("wrapper");}} reflete.set (obj, "foo", "value", wrapper);6: Evite o acesso direto a __proto__:
O ES5 fornece Object.getProTypeOf (OBJ) para acessar o protótipo do objeto, e o ES6 fornece também
Reflet.GetProTypeOf (OBJ) e Reflince.SetProTypeOf (OBJ, NewProto), este é um novo método para acessar e definir o protótipo do objeto:
Reflete.Aply Uso
Reflete.Apply é na verdade a função.prototype.apply () substituto no ES5. Três parâmetros são necessários para executar o reflete.Apply.
O primeiro parâmetro é: a função a ser executada;
O segundo parâmetro é: o contexto que precisa ser executado;
O terceiro parâmetro é: é uma matriz ou pseudo-matriz, que será usada como um parâmetro para executar a função;
<Cript> deixe fn = function () {this.attr = [0,1,2,3];}; deixe obj = {}; reflet.Apply (fn, obj, []) console.log (obj); Demonstração de <cript> reflete.apply: <cript> reflete.apply (math.floor, indefinido, [1.75]); // saída: 1; reflete.Apply (String.FromCharCode, indefinido, [104, 101, 108, 108, 111]); // output: "hello" reflet.Apply (regexp.prototype.exec,/ab/, ["confabulação"]). // saída: 4Reflect.Apply ("". Charat, "Ponies", [3]); //Ou saída: "i" </sCript> reflete pode ser usado em combinação com proxy: {var fn = function () {}; fn.prototype.run = function () {console.log ("executado");}; var proxyfn = new CROXY (fn, {{constructs, Arugs) {Arugs) {ARUGTIs) {" Target (... raugments); // Como usar refletir.Apply; reflete.Apply (Target.Prototype.run, obj, raios); retorno obj;}}); new proxyfn (); // a saída primeiro: "construtor proxy"; e então Saída: Execute} reflete.Construct (): Reflet.Construct é na verdade um construtor de instanciação. É implementado através do formulário de argumento. O método de execução é diferente. O efeito é realmente o mesmo. O primeiro parâmetro do construto é o construtor, e o segundo parâmetro é uma matriz ou um pseudo-gray composto por parâmetros. O método de uso básico é: var fn = function (arg) {this.args = [arg]}; console.log (novo fn (1), reflet.construct (fn, [1])); // a saída é a mesma var d = reflet.Construct (data, [1776, 6, 4]); D InstanceOf Date; // Trued.getlyear (); // 1776 // SO REFLEFT.Construct e New Construct So Reflice.Construct e New Construct são os mesmos, pelo menos até agora ... podemos passar no terceiro parâmetro a se refletir. O novo elemento herdará essa superclasse; <Cript> função somEconstructor () {} var resultado = reflet.Construct (Array, [], SomEconstructor); reflet.GetProTypeOf (resultado); // SOMECOSTRUTOR.PROTOTYPEARRAY.ISARRAY (resultado); // true // orvar fn = function () {this.attr = [1];}; var pessoa = function () {}; pessoa.prototype.run = function () {}; console.log (reflete.construct (fn, [], pessoa); var fn = function () {Array.Apply (this, argumentos); this.shot = () => {console.log ("heheda");};}; var arr = reflet.Construct (fn, []) reflet.DefineProperty; Reflet.DefineProperty retorna um valor booleano e o valor do atributo é adicionado ao objeto por atribuição direta. Retorna um objeto inteiro, se a adição falhar, um erro será lançado; var obj = {}; obj.x = 10; console.log (obj.x) // saída: 10; Adicione valor usando refletir.DefineProperty; <script>var obj = {};if( Reflect.defineProperty(obj, "x", {value : 7 }) ) {console.log("added success");}else{console.log("added success");};</script> If we execute preventExtensions, we report an error by defining the new property through Object.defindProperty, but there is no error by Refletir.DefineProperty, e um valor falso é retornado: var obj = {}; object.PreventExtensions (obj); object.DefineProperty (obj, "x", {valor: 101, gravável: false, enumerável: false, configurável: false}); // diretamente errado; console.log (reflete.defineProperty (obj, "x", {value: 101})) // retorna false: se o valor for atribuído diretamente, o valor definido será retornado independentemente de o valor ser atribuído corretamente, a menos que confirmemos manualmente se o valor da propriedade do objeto é definido com sucesso; <Cript> var obj = {}; object.preventExtensions (obj); console.log (obj.aa = 1); // saída: 1; console.log (obj.aa) // saída: indefinido; </sCript> reflete.DeleteProperty Uso: refletir.DeleteProperty e refletir.DefineProperty O uso é semelhante. Os resultados da operação do reflete.DeleteProperty e excluem obj.xx são os mesmos. A diferença é que os formulários de uso são diferentes: um é um operador e o outro é uma chamada de função; Reflete.DeleteProperty (object.freeze ({foo: 1}), "foo"); // falsedelete objeto.freeze ({foo: 1}). foo; // saída: false; Existem dois parâmetros necessários para o uso do método reflet.get (): o primeiro é o objeto de destino OBJ, o segundo é o objeto de nome do atributo e o terceiro é opcional, que é o contexto do leitor (este); var obj = {}; obj.foo = 1; console.log (obj.foo); // saída: 1; console.log (reflet.get (obj, "foo")) // saída: 1; se refletir.get tiver um terceiro parâmetro, o terceiro parâmetro será usado como o contexto do leitor: var refletir = requer ('harmonia-refleção'); var obj = {"foo": 1, get bar () {return this.foo;}}; var foo = {}; foo.foo = "heheda"; console.log (reflete.get (obj, "bar", foo)); reflete.towrowropertydScriptor (): get the bens descrição por meio de propriedade.TeRyTer, por meio de propriedades. Reflete.getownPropertyDescriptor ({x: "hello"}, "x"); // Você também pode obtê -lo assim: object.getownPropertyDescriptor ({x: "1"}, "x"); // a diferença entre esses dois é que se pode embrulhar o objeto, não é: não: reflet.GetownPropertyDes (":" Alegen); // Lança um objeto de exceção.GetownPropertyDescriptor ("Hello", 0); // saída: {value: "h", gravável: false, enumerável: true, configurável: false} reflet.getProtypeOf () Uso do método: reflete.getPrototypeof e object.getProtypeOf são os mesmos, ambos retornam o protótipo de um objeto reflete.getProtypeOf (}); // output: object.protoTyPereflect.getProTypeOf (object.prototype); // saída: nullReflect.getProTypeOf (object.create (null)); // saída: nullReflect. Reflete.has ({y: 0}, "y") // saída: true; var obj = {x: 0}; console.log ("x" em obj); var proxy = new proxy (obj, {has: function (target, args) {console.log ("Execute tem método"); retorno reflete.has (Target, ... args);}}); console.log ("x" em proxy); // saída: true; console.log (reflete.has (proxy, "x")) // saída: true; </script> O OBJ desta demonstração é equivalente a se tornar um método, é inútil, apenas usa seu método tem: obj = novo proxy ({}, {has (t, k) {return k.startswith ("Door");}}); Reflete.Has (Obj, "Doorbell"); // Truereflect.has (obj, "Dormitório"); // FalSereflect.isextensible () use // agora esse elemento pode ser estendido; var em vazio = {}; reflet.isextensible (vazio); // === TRUE // Use o método PreventExtensions para impedir que esse objeto estenda novos atributos; Reflete.PreventExtensions (vazio); Reflete.isExtensible (vazio); // === FALSE // Este objeto não pode estender novos atributos, e os atributos graváveis ainda podem ser alterados var seloned = object.seal ({}); reflet.isExtensible (selado); // === FALSE // Este objeto é completamente congelado var Frozen = object.Freeze ({}); reflet.isExtensible (Frozen); // === FALSO A diferença entre refletir.Extetensible e Object.Sextetensible é que, se o parâmetro não estiver correto, um jogará o errado e o outro retornará verdadeiro ou falso: reflete.isextetensible (1); // arremesso errado: 1 não é um objectObject.isextensible (1); // retornar false; Reflet.ownsKeys () Uso do método: reflete.ownskeys, o objeto não possui o método OwnKeys, reflete.ownKeysz Sua função é retornar as chaves do objeto; console.log (reflete.ownskeys ({"A": 0, "B": 1, "C": 2, "D": 3})); // saída: ["a", "b", "c", "d"] console.log (reflete.ownskeys ([])); // ["comprimento"] var sym = símbolo.for ("cometa"); var sym2 = símbolo.for ("meteoro"); var obj = {[sym]: 0, "str": 0, "773": 0, "0": 0, [sym2]: 0, "-1": 0, "8": 0, "Second str": 0}; reflete.owns (obj); // saída: /["0", "8", "773", "str", "-1", "Second str", símbolo (cometa), símbolo (meteoro)] reflete.ownkeys é classificado por: primeiro exibe os números, os números são classificados pelo tamanho e, em seguida, as seqüências são classificadas pela ordem da inserção. Finalmente, as chaves do tipo de símbolo também são classificadas de acordo com a ordem de inserção; A classificação ocorre porque quando você atribui um valor a um atributo de objeto, a regra de classificação da chave do objeto é o primeiro número, em uma string e, finalmente, os dados do tipo de símbolo; O método de uso de refletir.PreventExtensions (): Objeto também possui um método de prevenção de extensões, que é um pouco diferente de refletir.PreventExtensions (). Se o parâmetro reflet.PreventExtensions não for um objeto, ele lançará um erro; var em vazio = {}; reflet.isextensible (vazio); // === TRUE // O objeto após a execução do PreventExtensions pode ser modificado; Reflete.PreventExtensions (vazio); Reflete.isExtensible (vazio); // === FalSereflect.PreventExtensions (1); // TypeError: 1 não é um objectObject.PreventExtensions (1); // Nenhum erro é lançado, ele retornará: 1Reflect.Set () Reflince.Set O método é semelhante ao obtenção; var obj = {}; reflet.set (obj, "prop", "value"); // saída: TrueConsole.log (obj.prop); // saída: "value" var arr = ["pato", "pato", "pato"]; reflet.set (arr, 2, "ganso"); // TrueConsole.log (arr [2]); // "ganso" reflete.set (arr, "comprimento", 1); // trueconsole.log (arr); // ["pato"]; reflet.set (obj) é equivalente a refletir.set (obj, indefinido, indefinido); var obj = {}; reflet.set (obj); // saída: true // O código acima é equivalente a refletir.set (obj, indefinido, indefinido); reflet.GetownPropertyDescriptor (obj, "indefinido"); // {value. {console.log ("setter"); this.value = value;}, get key () {return this.value;}}; reflete.set (obj, "key", "heheda", obj); console.log (obj); reflete.setProTypeOf () reflet.SetProTypeof (). Ele definirá um protótipo para o objeto, que é alterar o atributo __proto__ do objeto ...; refletir.SetProTypeOf ({}, object.prototype); // saída true // para a matriz de objetos [[prototype]] é null.reflect.setPrototypeof ({}, null); // true // Neste momento, obj .__ proto__ é indefinido // livre o objeto e redefinir [[protótipo]] reflet.SetPrototypeof (object.freeze ({}), nulo); // false // Se a cadeia do protótipo depende do loop, ele retornará false.var destino = {}; var proto = object.Create (Target); refletir.SetPrototypeOf (Target, Proto); // false