Também não saberei disso, vá para casa e faça o agricultor.
A cópia do código é a seguinte:
exclua thisisObject [chave]
ou
exclua thisisObject.Key
A propósito, vamos falar sobre o uso de excluir
Algumas semanas atrás, tive a chance de ler o livro JavaScript orientado a objetos de Stoyan Stefanov. Este livro é altamente classificado na Amazon (12 resenhas, 5 estrelas), então fiquei curioso para ver se era um livro recomendado, então comecei a ler o capítulo de funções. Eu realmente aprecio a maneira como este livro explica as coisas, e os exemplos são organizados de uma maneira muito bonita e gradual, e parece que mesmo os iniciantes podem facilmente dominar esse conhecimento. No entanto, quase imediatamente, descobri um mal -entendido interessante ao longo do capítulo - excluindo funções funcionais. Existem também alguns outros erros (como a diferença entre declarações de função e expressões de função), mas não os discutiremos neste momento.
O livro afirma:
"A função é tratada como uma variável normal - ela pode ser copiada em diferentes variáveis ou até excluída". Um exemplo é anexado a esta explicação:
A cópia do código é a seguinte:
var sum = função (a, b) {return a + b;}
var add = sum;
Excluir soma
verdadeiro
tipo de soma;
"indefinido"
Ignore alguns semicolons ausentes, você pode ver onde estão os erros nesses códigos? Obviamente, o erro é que a operação de excluir a variável da soma não terá sucesso. A expressão de exclusão não deve retornar verdadeira e a soma do tipo de não deve retornar "indefinida". Tudo isso é porque é impossível excluir variáveis no JavaScript. Pelo menos, é impossível nessa maneira de declaração.
Então, o que exatamente aconteceu neste exemplo? É um bug? Ou um uso especial? Provavelmente não. Esse código é na verdade a saída real no console do Firebug, e Stoyan deve tê -lo usado como uma ferramenta para testes rápidos. É quase como se o Firebug seguisse algumas outras regras de exclusão. É o Firebug que fez Stoyan se perder! Então, o que exatamente aconteceu aqui?
Antes de responder a essa pergunta, primeiro precisamos entender como o operador de exclusão funciona no JavaScript: o que exatamente pode ser excluído e o que não pode ser excluído? Hoje, tentarei explicar isso em detalhes. Veremos o comportamento "estranho" da Firebug e perceberemos que não é tão estranho. Vamos nos aprofundar no que está escondido nos bastidores, onde variáveis, funções, atribuem valores aos atributos e excluíram -os. Veremos a compatibilidade do navegador e alguns dos bugs mais notórios. Também discutiremos o padrão rigoroso do ES5 e como ele muda o comportamento dos operadores excluídos.
Vou trocar JavaScript e Ecmascript, que significam o ECMAScript (a menos que seja óbvio que a implementação de JavaScript de Mozilla)
Como esperado, na internet, as explicações de delete são bastante escassas. O artigo do MDC é provavelmente o melhor recurso para entender, mas, infelizmente, não possui alguns detalhes interessantes do tópico. Estranhamente, uma das coisas esquecidas é a razão da estranha manifestação de Firebug. E a referência do MSDN é quase inútil nesses aspectos.
Teoria
Então, por que somos capazes de excluir as propriedades de um objeto:
A cópia do código é a seguinte:
var o = {x: 1};
excluir boi; // verdadeiro
boi; // indefinido
Mas o objeto declarado assim não pode ser excluído:
A cópia do código é a seguinte:
var x = 1;
excluir x; // false
x; // 1
Ou a função:
A cópia do código é a seguinte:
função x () {}
excluir x; // false
tipo de x; // "função"
Nota: Quando uma propriedade não pode ser excluída, o operador de exclusão retornará apenas false.
Para entender isso, primeiro precisamos dominar esses conceitos sobre instâncias e propriedades de atributos variáveis - esses conceitos são infelizmente raramente mencionados nos livros de JavaScript. Vou tentar revisar brevemente esses conceitos nos próximos parágrafos. Esses conceitos são difíceis de entender! Se você não se importa "por que essas coisas funcionam dessa maneira", apenas pule este capítulo.
Tipo de código:
No ECMAScript, existem 3 tipos diferentes de código executável: código global, código de função e código de avaliação. Esses tipos são mais ou menos auto-explicativos em termos de nome, aqui está uma breve visão geral:
Quando um código -fonte é considerado um programa, ele será executado em um ambiente global e é considerado código global. Em um ambiente de navegador, o conteúdo dos elementos de script é geralmente interpretado como programas e, portanto, é executado como código global.
Qualquer código executado diretamente em uma função é obviamente considerado código de função. Em um navegador, o conteúdo das propriedades do evento (como <p onclick = "...">) é geralmente interpretado como código de função.
Finalmente, o texto do código aplicado à função interno avalia é interpretado como código de avaliação. Em breve, descobriremos por que esse tipo é especial.
Contexto de execução:
Quando o código do ECMAScript é executado, geralmente ocorre em um contexto de execução específico. O contexto de execução é um conceito de entidade um tanto abstrato, que pode ajudar a entender como o escopo e as instâncias variáveis funcionam. Para cada um dos três códigos executáveis, existe um contexto de execução correspondente a ele. Quando uma função é executada, dizemos "o controle do programa entra no contexto de execução do código da função"; Quando uma parte do código global é executada, o controle do programa entra no contexto de execução do código global, etc.
Como você pode ver, o contexto de execução pode formar logicamente uma pilha. Primeiro, pode haver um pedaço de código global e seu próprio contexto de execução e, em seguida, esse pedaço de código pode chamar uma função com seu contexto de execução (função). Essa função pode chamar outra função, etc. Mesmo que a função seja chamada recursivamente, ela será inserida em um novo contexto de execução cada vez que for chamado.
Objeto ativo (objeto de ativação) / objeto variável:
Cada contexto de execução possui o chamado objeto variável associado a ele. Semelhante ao contexto de execução, um objeto variável é uma entidade abstrata, um mecanismo usado para descrever instâncias variáveis. Curiosamente, variáveis e funções declaradas no código -fonte geralmente são adicionadas a esse objeto variável como propriedades.
Quando o controle do programa insere o contexto de execução do código global, um objeto global é usado como um objeto variável. É exatamente por isso que as variáveis de função declaradas globais tornam -se propriedades globais de objetos.
A cópia do código é a seguinte:
/ * Lembre -se de que `` isto 'se refere ao objeto global quando estiver no escopo global */
var global_object = this;
var foo = 1;
Global_object.foo; // 1
foo === global_object.foo; // verdadeiro
barra de função () {}
typeof global_object.bar; // "função"
Global_object.bar === bar; // verdadeiro
OK, então as variáveis globais se tornarão propriedades dos objetos globais, mas o que acontece com as variáveis locais (as definidas no código da função)? De fato, eles se comportam de maneira muito semelhante: eles se tornarão propriedades de objetos variáveis (objetos variáveis). A única diferença é que, quando no código da função, um objeto variável não é um objeto global, mas o chamado objeto de ativação. O objeto ativo é criado toda vez que entra no contexto de execução do código da função.
Não apenas variáveis e funções declaradas no código da função se tornarão propriedades do objeto ativo; Isso também ocorrerá em cada parâmetro de função (o nome correspondente ao parâmetro formal correspondente) e um objeto de argumentos especiais (o nome dos argumentos). Observe que o objeto ativo é um mecanismo de descrição interno e não pode ser acessado no código do programa.
A cópia do código é a seguinte:
(function (foo) {
barra var = 2;
função baz () {}
/*
Em termos abstratos,
O objeto especial `argumentos` se torna uma propriedade do objeto de ativação da função:
Ativação_object.argudents; // objeto de argumentos
... assim como argumento `foo`:
Ativação_object.foo; // 1
... assim como variável `bar`:
Ativação_object.bar; // 2
... assim como a função declarada localmente:
typeof ativação_object.baz; // "função"
*/
}) (1);
Finalmente, as variáveis declaradas no código de avaliação tornam -se propriedades de objetos variáveis no contexto do chamador. O código de avaliação simplesmente usa objetos variáveis no contexto de execução do código que o chama.
A cópia do código é a seguinte:
var global_object = this;
/* `foo` é criado como uma propriedade de chamar o objeto de variável de contexto,
que neste caso é um objeto global */
Eval ('var foo = 1;');
Global_object.foo; // 1
(função(){
/* `bar` é criado como uma propriedade de chamar o objeto de variável de contexto,
que neste caso é um objeto de ativação de contenção de função */
Eval ('var bar = 1;');
/*
Em termos abstratos,
Ativação_object.bar; // 1
*/
}) ();
Atributos da propriedade
Estamos quase aqui. Agora que estamos bem cientes do que está acontecendo com variáveis (elas se tornam propriedades), o único conceito restante a ser entendido são os atributos da propriedade. Cada atributo pode ter 0 ou mais propriedades, que são selecionadas entre os seguintes conjuntos: ReadOnly, Donntenum, DontDelete e Internal. Você pode pensar neles como sinalizadores - um recurso que pode existir ou não em propriedades. Para nossa discussão hoje, estamos interessados apenas em não.
Quando variáveis e funções declaradas se tornam atributos de objetos variáveis (ou objetos ativos do código da função, ou objetos globais do código global), esses atributos são criados com o atributo DONTDELETE. No entanto, quaisquer atributos explícitos (ou implícitos) não serão incluídos no atributo DONTDELETE. É por isso que podemos excluir alguns atributos, mas não podemos excluir outros.
A cópia do código é a seguinte:
var global_object = this;
/* `Foo` é uma propriedade de um objeto global.
É criado por declaração variável e, portanto, não tem atributo.
É por isso que não pode ser excluído. */
var foo = 1;
excluir foo; // false
tipo de foo; // "número"
/* `bar` é uma propriedade de um objeto global.
É criado via declaração de função e o atributo não temelete.
É por isso que também não pode ser excluído. */
barra de função () {}
excluir barra; // false
tipo de barra; // "função"
/* `Baz` também é uma propriedade de um objeto global.
No entanto, ele é criado via atribuição de propriedades e, portanto, não tem atributo nãoDELETE.
É por isso que pode ser excluído. */
Global_object.baz = 'blá';
exclua global_object.baz; // verdadeiro
typeof global_object.baz; // "indefinido"
Objetos embutidos e nãoddelete
Então, isso é tudo sobre isso (dontDelete): uma propriedade especial da propriedade que controla se essa propriedade pode ser excluída. Observe que alguns objetos embutidos são especificados para conter o DONTDELETE, para que não possam ser excluídos. Por exemplo, uma variável de argumento especial (ou, como sabemos agora, a propriedade de um objeto ativo) tem que não tem. A propriedade de comprimento de uma instância de função também possui propriedade não.
A cópia do código é a seguinte:
(função(){
/ * Não é possível excluir `argumentos ', pois não tem que não tem */
excluir argumentos; // false
tipo de argumentos; // "objeto"
/* Não é possível excluir o `comprimento` da função; também tem dontDelete */
função f () {}
excluir f.length; // false
tipo de f.length; // "número"
}) ();
O atributo correspondente ao parâmetro da função também possui o recurso DONTDELETE desde o seu estabelecimento, por isso não podemos excluí -lo.
A cópia do código é a seguinte:
(function (foo, bar) {
excluir foo; // false
foo; // 1
excluir barra; // false
bar; // 'blá'
}) (1, 'blá');
Tarefa não declarada:
Você também deve se lembrar que uma tarefa não declarada cria uma propriedade no objeto global, a menos que a propriedade tenha sido encontrada em outras partes desta cadeia de escopo antes do objeto global. E agora sabemos a diferença entre a atribuição de propriedades e a declaração variável - o último define a propriedade DONTDELETE, mas a primeira não. Devemos esclarecer por que uma atribuição não declarada cria uma propriedade deletionável.
A cópia do código é a seguinte:
var global_object = this;
/* Crie propriedade global via declaração variável; A propriedade tem dontDelete */
var foo = 1;
/* Crie propriedade global por meio de atribuição não declarada; A propriedade não tem não DONTDELETE */
bar = 2;
excluir foo; // false
tipo de foo; // "número"
excluir barra; // verdadeiro
tipo de barra; // "indefinido"
Observação: as propriedades são determinadas quando o atributo é criado e as atribuições subsequentes não modificam as propriedades dos atributos existentes. É muito importante entender essa diferença.
A cópia do código é a seguinte:
/ * `foo` é criado como uma propriedade com dontDelete */
function foo () {}
/* As atribuições posteriores não modificam atributos. Não está lá! */
foo = 1;
excluir foo; // false
tipo de foo; // "número"
/* Mas atribuindo a uma propriedade que não existe,
Cria essa propriedade com atributos vazios (e assim sem doNTDelete) */
this.Bar = 1;
excluir barra; // verdadeiro
tipo de barra; // "indefinido"
Confusão de Firebug:
O que acontece no Firebug? Por que as variáveis declaradas no console podem ser excluídas? Isso não é contrário ao que aprendemos antes? Bem, como eu disse antes, o código de avaliação tem desempenho especial ao enfrentar declarações variáveis. As variáveis declaradas em Eval são realmente criadas como atributos sem o atributo nãoDELETE.
A cópia do código é a seguinte:
Eval ('var foo = 1;');
foo; // 1
excluir foo; // verdadeiro
tipo de foo; // "indefinido"
Da mesma forma, da mesma forma, quando chamado código de função:
A cópia do código é a seguinte:
(função(){
Eval ('var foo = 1;');
foo; // 1
excluir foo; // verdadeiro
tipo de foo; // "indefinido"
}) ();
Esta é a base para o comportamento anormal do Firebug. Todo o texto no console será analisado e executado como código de avaliação, em vez de código global ou de função. Obviamente, todas as variáveis declaradas aqui acabarão se tornando propriedades sem o atributo nãoDELETE, para que todas possam ser facilmente excluídas. Precisamos entender a diferença entre o código global e o console do Firebug.
Excluir variáveis através da avaliação:
Esse comportamento interessante de avaliação, juntamente com outro aspecto do ECMAScript, pode tecnicamente nos permitir excluir as propriedades de "não deliciosas". Uma coisa sobre declarações de função é que elas são capazes de substituir variáveis com o mesmo nome no mesmo contexto de execução.
A cópia do código é a seguinte:
função x () {}
var x;
tipo de x; // "função"
Observe como as declarações da função obtêm prioridade e substituem variáveis com o mesmo nome (ou, em outras palavras, as mesmas propriedades no objeto variável). Isso ocorre porque as declarações da função são instanciadas após a declaração variável e podem substituí -las (declarações variáveis). As declarações de função não apenas substituem o valor de uma propriedade, mas também substituem as propriedades dessa propriedade. Se declararmos uma função através da avaliação, essa função deve substituir as propriedades da propriedade original (substituída) por suas próprias propriedades. E, como as variáveis declaradas através da avaliação criam propriedades sem o atributo nãoDELETE, a instanciando essa nova função removerá o atributo DONTDELETE existente da propriedade, para que uma propriedade possa ser excluída (e, obviamente, aponta seu valor para a função recém -criada).
A cópia do código é a seguinte:
var x = 1;
/ * Não é possível excluir, `x` tem dontDelete */
excluir x; // false
tipo de x; // "número"
Eval ('função x () {}');
/ * `x` agora a função referências e não deve ter nãoDelete */
tipo de x; // "função"
excluir x; // deve ser `true`
tipo de x; // deve ser "indefinido"
Infelizmente, esse "engano" não funciona em nenhuma implementação no momento. Talvez eu esteja perdendo alguma coisa aqui, ou talvez o comportamento seja muito obscuro que o implementador não note.
Compatibilidade do navegador:
É útil em teoria entender como as coisas funcionam, mas a prática é a coisa mais importante. O navegador segue os padrões quando se trata de criar/excluir variáveis/propriedades? A resposta é: na maioria dos casos, sim.
Escrevi um conjunto de testes simples para testar a compatibilidade do navegador com os operadores de exclusão, incluindo testes sob código global, código de função e código de avaliação. O conjunto de testes verifica se o valor de retorno e os valores de atributo do operador de exclusão (como eles devem se comportar) são realmente excluídos. O valor de retorno da exclusão não é tão importante quanto seu resultado real. Se o delete retornar verdadeiro em vez de falso, isso não é importante, e o importante é que os atributos com o atributo não são excluídos e vice -versa.
Os navegadores modernos são geralmente bastante compatíveis. Além dos recursos de avaliação que mencionei anteriormente, os seguintes navegadores passaram todos os conjuntos de testes: Opera 7.54+, Firefox 1.0+, Safari 3.1.2+, Chrome 4+.
Safari 2.x e 3.0.4 têm problemas ao excluir parâmetros da função; Essas propriedades parecem ser criadas sem o DONTDELETE, para que possam ser excluídas. O Safari 2.x tem mais problemas - a exclusão de variáveis não referenciadas (como excluir 1) lançará exceções; As declarações de função criam propriedades exclusivas (mas, estranhamente, declarações variáveis não); As declarações variáveis na avaliação se tornarão não deliciosas (mas as declarações de função são deletáveis).
Semelhante ao Safari, o KonQueror (3,5, não 4,3) lança uma exceção ao excluir um tipo não referenciado (como: excluir 1) e faz com que as variáveis de função deletem.
Nota do tradutor:
Testei as versões mais recentes do Chrome, Firefox e IE, e basicamente mantive a situação em que todos os outros passes, exceto 23 e 24, falharão. Ao mesmo tempo, testei a UC e alguns navegadores móveis. Exceto pelo navegador embutido do Nokia E72, que também falhou 15 e 16, os outros navegadores embutidos são os mesmos que os navegadores de mesa. Mas vale a pena mencionar que o navegador embutido do BlackBerry Curve 8310/8900 pode passar 23, o que me surpreendeu.
Bug bug bug bug:
Gecko 1.8.x Navegador - Firefox 2.x, Camino 1.x, Seamonkey 1.x, etc. - mostra um bug muito interessante, atribuição explícita de uma propriedade removerá sua propriedade DONTDELETE, mesmo que essa propriedade seja criada por meio de declarações variáveis ou declarações de função.
A cópia do código é a seguinte:
function foo () {}
excluir foo; // false (como esperado)
tipo de foo; // "função" (como esperado)
/ * Agora atribua a uma propriedade explicitamente */
this.foo = 1; // Limpa erroneamente o atributo nãoDelete
excluir foo; // verdadeiro
tipo de foo; // "indefinido"
/ * Observe que isso não acontece ao atribuir a propriedade implicitamente */
barra de função () {}
bar = 1;
excluir barra; // false
tipo de barra; // "Número" (embora a atribuição substituída)
Surpreendentemente, o Internet Explorer 5.5 - 8 passou o conjunto de testes completo, exceto que a exclusão de tipos não referenciados (como Excluir 1) lançará exceções (assim como o antigo Safari). No entanto, existem bugs mais graves no IE, o que não é tão óbvio. Esses bugs estão relacionados ao objeto global.
Ou seja, bugs:
Todo esse capítulo fala sobre bugs do Internet Explorer? Uau! É incrível!
No IE (pelo menos IE 6-8), a seguinte expressão lança uma exceção (quando executada no código global):
this.x = 1;
excluir x; // typeError: objeto não suporta esta ação
Este também o fará, mas lançará exceções diferentes, o que torna as coisas ainda mais interessantes:
var x = 1;
exclua this.x; // typeError: não é possível excluir 'this.x'
Parece que, no IE, as declarações variáveis no código global não criam atributos no objeto global. Criando atributos por atribuição (this.x = 1) e excluindo -o por excluir x posteriormente lança um erro. Criar atributos por declaração (var x = 1) e excluí -lo depois lança outro erro.
Mas isso não é tudo. Criar propriedades por tarefas explícitas sempre causará exceções de arremesso quando excluídas. Não há apenas erros aqui, mas as propriedades criadas parecem ter o atributo DONTDELETE, o que, obviamente, não deveria ser.
this.x = 1;
exclua this.x; // typeError: objeto não suporta esta ação
tipo de x; // "Número" (ainda existe, não foi excluído como deveria ter sido!)
excluir x; // typeError: objeto não suporta esta ação
tipo de x; // "número" (não foi excluído novamente)
Agora, pensaríamos que, no IE, as atribuições não declaradas (as propriedades devem ser criadas em objetos globais) criam propriedades deletadas.
x = 1;
excluir x; // verdadeiro
tipo de x; // "indefinido"
No entanto, se você excluir essa propriedade por meio dessa referência no código global (excluir this.x), um erro semelhante será exibido.
x = 1;
exclua this.x; // typeError: não é possível excluir 'this.x'
Se quisermos resumir esse comportamento, parece que o uso delete. Quando a propriedade na pergunta é criada por atribuição explícita (this.x = 1), o exclusão lança um erro; Quando a propriedade é criada por uma atribuição não declarada (x = 1) ou por uma declaração (var x = 1), a exclusão lança outro erro.
Excluir x, por outro lado, um erro deve ser lançado somente quando a propriedade for criada por atribuição explícita - this.x = 1. Se uma propriedade for criada por declaração (var x = 1), a operação de exclusão nunca ocorre e a operação de exclusão retorna corretamente falsa. Se uma propriedade for criada pela atribuição não declarada (x = 1), a operação de exclusão funciona conforme o esperado.
Pensei nessa questão novamente em setembro. Garrett Smith sugeriu que, no IE,
"O objeto Global Variable é implementado como um objeto JScript, e o objeto global é implementado pelo host".
Garrett usou a entrada do blog de Eric Lippert como referência.
Podemos confirmar mais ou menos essa teoria implementando alguns testes. Observe que isso e a janela parecem apontar para o mesmo objeto (se pudermos confiar no operador ===), mas o objeto variável (o objeto em que a declaração de função está localizada) é diferente do que isso aponta.
A cópia do código é a seguinte:
/ * No código global */
function getBase () {return this; }
getBase () === this.getBase (); // false
this.getBase () === this.getBase (); // verdadeiro
window.getBase () === this.getBase (); // verdadeiro
window.getBase () === getBase (); // false
mal-entendido:
A beleza de entender por que as coisas funcionam dessa maneira é não ser subestimada. Vi alguns mal -entendidos sobre o operador de exclusão na Internet. Por exemplo, a resposta no Stackoverflow (com classificação surpreendentemente alta), explica com confiança
"Quando o operando de destino não é uma propriedade de objeto, a exclusão deve estar operacional".
Agora que entendemos o núcleo do comportamento da operação de exclusão, o erro nesta resposta se torna óbvio. A exclusão não distingue entre variáveis e atributos (de fato, para excluir, ambos são tipos de referência) e, de fato, se importa apenas com os atributos do DONTDELETE (e se os próprios atributos existem).
Também é muito interessante ver vários mal -entendidos se refutando. No mesmo tópico, uma pessoa sugeriu primeiro que apenas excluir variáveis (isso não funcionará, a menos que seja declarado em avaliação), enquanto outra pessoa forneceu uma correção de bugs de como excluir é usada para excluir variáveis no código global, mas não no código da função.
Tenha cuidado com a explicação do JavaScript na Internet. O método ideal é sempre entender a essência do problema. ;)
Excluir e host objeto (objeto host):
O algoritmo de exclusão é aproximadamente assim:
Retorne true se o operando não for do tipo de referência
Se o objeto não tiver um atributo direto desse nome, retorne true (como sabemos, o objeto pode ser um objeto ativo ou um objeto global)
Se a propriedade existir, mas tiver o atributo não
Em outros casos, exclua o atributo e retorne verdadeiro
No entanto, o comportamento do operador de exclusão no objeto host é imprevisível. E esse comportamento não está realmente errado: (pelo padrão), o objeto do host pode implementar qualquer comportamento para vários operadores como Read (método interno [[get]]), write (método interno [[put]]]) e excluir (interno [[delete]]]. Essa graça para o comportamento personalizado [[delete]] é o que torna o objeto host tão confuso.
Vimos algumas peculiaridades do IE, onde excluir objetos específicos (que são obviamente implementados como objetos host) lançarão erros. Algumas versões do Firefox lançarão ao excluir a janela.Location. Quando operandos são objetos de host, você não pode confiar no valor de retorno da exclusão. Vamos ver o que acontece no Firefox:
A cópia do código é a seguinte:
/ * "Alert" é uma propriedade direta de `window` (se acreditarmos em 'HasownProperty) */
Window.HasownProperty ('Alert'); // verdadeiro
exclua window.alert; // verdadeiro
typeof window.alert; // "função"
Excluir window.alert retorna true, mesmo que não haja razão para essa propriedade causar esse resultado. Ele resolverá uma referência (para que não retorne verdadeiro na primeira etapa). Esta é uma propriedade direta de um objeto de janela (para que não retorne a segunda etapa). Portanto, o único caso em que excluir o retorno é verdadeiro é chegar à quarta etapa e excluir essa propriedade. No entanto, essa propriedade nunca é excluída.
A moral desta história é: nunca confie no objeto anfitrião.
ES5 Modo Estrito:
Então, o que o Modo Estrito ECMAScript5 traz para nós? Introduz poucas limitações. Quando a expressão do operador de exclusão é uma referência direta a uma variável, um parâmetro de função ou um identificador de função, um erro de sintaxe será lançado. Além disso, se a propriedade tiver uma propriedade interna [[configurável]] == false, um erro de tipo será lançado.
A cópia do código é a seguinte:
(function (foo) {
"Use rigoroso"; // Ative o modo rigoroso dentro desta função
barra var;
função baz () {}
excluir foo; // SyntaxError (ao excluir o argumento)
excluir barra; // SyntaxError (ao excluir a variável)
excluir baz; // SyntaxError (ao excluir a variável criada com a declaração de função)
/ * `comprimento` das instâncias de função tem {[[configurável]]: false} */
delete (function () {}). Length; // typeError
}) ();
Além disso, a exclusão de variáveis não declaradas (ou referências não resolvidas) também lançará erros de sintaxe:
"Use rigoroso";
exclua i_dont_exist; // SyntaxError
A atribuição não declarada se comporta de maneira semelhante às variáveis não declaradas no modo rigoroso (exceto que desta vez leva um erro de cotação em vez de um erro de sintaxe):
"Use rigoroso";
i_dont_exist = 1; // ReferenceError
Como você entende agora, todas as restrições fazem mais ou menos sentido, porque a exclusão de variáveis, declarações de funções e parâmetros pode causar tanta confusão. Em vez de ignorar silenciosamente a operação de exclusão, o padrão estrito requer uma medida mais radical e descritiva.
Resumir:
Esta postagem do blog acabou sendo bastante longa, então não vou falar sobre algo como usar excluir para excluir um objeto de matriz ou o que ele significa. Você pode consultar a explicação especial do artigo do MDC (ou ler os padrões e fazer seus próprios experimentos).
Aqui está um breve resumo de como as operações de exclusão funcionam em JavaScript:
Variáveis e declarações de função são propriedades de objetos ativos ou objetos globais
Os atributos têm algumas características, e o DontDelete é o atributo que determina se esse atributo pode ser excluído.
Variáveis e declarações de função no código global ou de função sempre criam atributos com atributos do DONTDELETE.
Os parâmetros da função são sempre atributos do objeto ativo e são acompanhados por nãodDelete.
Variáveis e funções declaradas no código de avaliação sempre criam propriedades sem dontDelete.
Novas propriedades não têm atributos quando são criados (é claro que também não há não.
O objeto host pode decidir por si só como reagir à operação de exclusão.
Se você quiser estar mais familiarizado com o que é descrito aqui, consulte a especificação da 3ª edição ECMA-262.
Espero que você possa aproveitar este artigo e aprender algo novo. Quaisquer perguntas, sugestões ou correções são bem -vindas.