Quais "recursos ocultos" do JavaScript você acha que todo programador deveria saber?
Depois de ter visto a excelente qualidade das respostas para as seguintes perguntas, pensei que era hora de solicitar JavaScript.
- Recursos ocultos do HTML
- Recursos ocultos do CSS
- Recursos ocultos do PHP
- Recursos ocultos do ASP.NET
- Recursos ocultos do c #
- Recursos ocultos do Java
- Recursos ocultos do Python
Embora o JavaScript seja sem dúvida a linguagem mais importante do lado do cliente no momento (basta perguntar ao Google), é surpreendente como a maioria dos desenvolvedores da Web aprecia o quão poderoso ele realmente é.
javascript
hidden-features
Binoj Antony
fonte
fonte
Respostas:
Você não precisa definir nenhum parâmetro para uma função. Você pode apenas usar o
arguments
objeto de matriz da função .fonte
arguments
objeto torna a chamada de uma função muito mais lenta - por exemplo. argumentos if (false); vai doer perf.arguments.callee
está sendo preterido.Eu poderia citar a maior parte do excelente livro de Douglas Crockford, JavaScript: The Good Parts .
Mas vou levar apenas um para você, sempre use
===
e em!==
vez de==
e!=
==
não é transitivo. Se você usá-===
lo, daria false para todas essas instruções conforme o esperado.fonte
==
é'\n\t\r ' == 0
=>true
...: DAs funções são cidadãos de primeira classe em JavaScript:
Técnicas de programação funcional podem ser usadas para escrever javascript elegante .
Particularmente, funções podem ser passadas como parâmetros, por exemplo, Array.filter () aceita um retorno de chamada:
Você também pode declarar uma função "privada" que existe apenas no escopo de uma função específica:
fonte
new Function()
é tão mau quantoeval
. Não use.Você pode usar o operador in para verificar se existe uma chave em um objeto:
Se você achar os literais de objeto muito feios, poderá combiná-lo com a dica de função sem parâmetros:
fonte
Atribuindo valores padrão a variáveis
Você pode usar o lógico ou o operador
||
em uma expressão de atribuição para fornecer um valor padrão:A
a
variável terá o valor dec
somente seb
é Falsas (se énull
,false
,undefined
,0
,empty string
, ouNaN
), caso contrário,a
irá obter o valor deb
.Isso geralmente é útil em funções, quando você deseja atribuir um valor padrão a um argumento, caso não seja fornecido:
Exemplo de fallback do IE em manipuladores de eventos:
Os seguintes recursos de idioma estão conosco há muito tempo, todas as implementações de JavaScript os suportam, mas eles não faziam parte da especificação até o ECMAScript 5th Edition :
A
debugger
declaraçãoDescrito em: § 12.15 A declaração do depurador
Esta declaração permite que você coloque pontos de interrupção programaticamente em seu código apenas por:
Se um depurador estiver presente ou ativo, ele fará com que ele se quebre imediatamente, exatamente nessa linha.
Caso contrário, se o depurador não estiver presente ou ativo, esta instrução não terá efeito observável.
Literais de sequência de linhas múltiplas
Descrito em: § 7.8.4 Literais de cordas
Você tem que ter cuidado porque o personagem ao lado do
\
deve ser um terminador de linha, se você tem um espaço após o\
por exemplo, o código vai olhar exatamente o mesmo, mas vai levantar umSyntaxError
.fonte
O JavaScript não tem escopo de bloco (mas tem fechamento, então vamos chamá-lo mesmo?).
fonte
Você pode acessar as propriedades do objeto em
[]
vez de.
Isso permite procurar uma propriedade que corresponda a uma variável.
Você também pode usar isso para obter / definir propriedades do objeto cujo nome não é um identificador legal.
Algumas pessoas não sabem disso e acabam usando eval () como este, o que é uma péssima ideia :
Isso é mais difícil de ler, mais difícil de encontrar erros (não é possível usar o jslint), é mais lento para executar e pode levar a explorações do XSS.
fonte
foo.bar
, de acordo com as especificações de qualquer maneira, se comporta exatamente comofoo["bar"]
. Observe também que tudo é uma propriedade de string. mesmo quando você faz acesso à matriz,array[4]
o 4 é convertido em um string (novamente, pelo menos de acordo com ECMAScript v3 especificação)Se você estiver pesquisando no Google uma referência decente sobre JavaScript sobre um determinado tópico, inclua a palavra-chave "mdc" na sua consulta e seus primeiros resultados serão do Mozilla Developer Center. Eu não carrego nenhuma referência offline ou livros comigo. Eu sempre uso o truque de palavras-chave "mdc" para obter diretamente o que estou procurando. Por exemplo:
Google: javascript array sort mdc
(na maioria dos casos, você pode omitir "javascript")
Atualização: O Mozilla Developer Center foi renomeado para Mozilla Developer Network . O truque da palavra-chave "mdc" ainda funciona, mas em breve poderemos ter que começar a usar "mdn" .
fonte
Talvez um pouco óbvio para alguns ...
Instale o Firebug e use console.log ("olá"). Muito melhor do que usar o alert random (); é o que me lembro de ter feito há alguns anos.
fonte
Métodos particulares
Um objeto pode ter métodos particulares.
fonte
Também mencionado em "Javascript: The Good Parts" de Crockford:
parseInt()
é perigoso. Se você passar uma string sem informar a base correta, poderá retornar números inesperados. Por exemplo,parseInt('010')
retorna 8, não 10. Passar uma base para parseInt faz com que funcione corretamente:fonte
Math.floor
ouNumber
?10 === Math.floor("010"); 10 === Number("010");
carros alegóricos:42 === Math.floor("42.69"); 42.69 === Number("42.69");
parseInt
função inofensiva poderia facilmente ser feita para fazer algo não tão inofensivo.__parseInt = parseInt; parseInt = function (str, base) { if (!base) throw new Error(69, "All your base belong to us"); return __parseInt(str, base); }
Funções são objetos e, portanto, podem ter propriedades.
fonte
Eu teria que dizer funções auto-executáveis.
Como o Javascript não tem escopo de bloco , você pode usar uma função de execução automática se desejar definir variáveis locais:
Aqui,
myvar
is não interfere ou polui o escopo global e desaparece quando a função termina.fonte
.js
arquivos em uma função de execução automática anônima e anexo qualquerwindow
objeto que eu queira que seja acessível globalmente ao objeto. Impede a poluição global do espaço para nome.Saiba quantos parâmetros são esperados por uma função
Saiba quantos parâmetros são recebidos pela função
fonte
function.length
.Aqui estão algumas coisas interessantes:
NaN
com qualquer coisa (mesmoNaN
) é sempre falsa, que inclui==
,<
e>
.NaN
Significa Não é um número, mas se você solicitar o tipo, ele realmente retornará um número.Array.sort
pode assumir uma função comparadora e é chamado por um driver do tipo quicksort (depende da implementação).$0
,$1
,$2
membros em um regex.null
é diferente de qualquer outra coisa. Não é um objeto, um booleano, um número, uma string, nemundefined
. É um pouco como uma "alternativa"undefined
. (Notatypeof null == "object"
:)this
gera o objeto [Global], de outro modo inominável.var
, em vez de apenas confiar na declaração automática da variável, dá ao tempo de execução uma chance real de otimizar o acesso a essa variávelwith
construção destruirá essas otimizaçõesbreak
. Os loops podem ser rotulados e usados como destino decontinue
.undefined
. (depende da implementação)if (new Boolean(false)) {...}
irá executar o{...}
bloco[atualizado um pouco em resposta a bons comentários; por favor, veja os comentários]
fonte
typeof null
retorna "objeto".undefined
, mas esse é apenas o valor padrão que você obtém ao procurar um índice que não existe. Se você selecionou um [2000], isso também seriaundefined
, mas isso não significa que você alocou memória para ele ainda. No IE8, algumas matrizes são densas e outras esparsas, dependendo da sensação do mecanismo JScript no momento. Leia mais aqui: blogs.msdn.com/jscript/archive/2008/04/08/…Sei que estou atrasado para a festa, mas não acredito
+
que a utilidade do operador não tenha sido mencionada além de "converter qualquer coisa em um número". Talvez seja assim que oculta uma característica?Obviamente, você pode fazer tudo isso usando
Number()
, mas o+
operador é muito mais bonito!Você também pode definir um valor de retorno numérico para um objeto substituindo o
valueOf()
método do protótipo . Qualquer conversão numérica realizada nesse objeto não resultaráNaN
, mas o valor de retorno dovalueOf()
método:fonte
0xFF
etc., não há necessidade+"0xFF"
.0xFF
, da mesma maneira que você pode escrever, em1
vez de+true
. Estou sugerindo que você possa usar+("0x"+somevar)
como alternativaparseInt(somevar, 16)
, se quiser." Métodos de extensão em JavaScript " através da propriedade prototype.
Isso adicionará um
contains
método a todos osArray
objetos. Você pode chamar esse método usando esta sintaxefonte
Para remover corretamente uma propriedade de um objeto, você deve excluir a propriedade em vez de apenas defini-la como indefinida :
A propriedade prop2 ainda fará parte da iteração. Se você quiser se livrar completamente do prop2 , faça:
A propriedade prop2 não aparecerá mais quando você estiver iterando pelas propriedades.
fonte
with
.É raramente usado e, francamente, raramente útil ... Mas, em circunstâncias limitadas, ele tem seus usos.
Por exemplo: literais de objeto são bastante úteis para configurar rapidamente propriedades em um novo objeto. Mas e se você precisar alterar metade das propriedades em um objeto existente?
Alan Storm ressalta que isso pode ser um pouco perigoso: se o objeto usado como contexto não tiver uma das propriedades atribuídas, ele será resolvido no escopo externo, possivelmente criando ou substituindo uma variável global. Isso é especialmente perigoso se você estiver acostumado a escrever código para trabalhar com objetos em que as propriedades com valores padrão ou vazios são deixadas indefinidas:
Portanto, é provavelmente uma boa idéia evitar o uso da
with
declaração para essa tarefa.Veja também: Existem usos legítimos para a declaração "with" do JavaScript?
fonte
Métodos (ou funções) podem ser chamados em objetos que não são do tipo para o qual foram projetados para trabalhar. É ótimo chamar métodos nativos (rápidos) em objetos personalizados.
Este código falha porque
listNodes
não é umArray
Esse código funciona porque
listNodes
define propriedades do tipo matriz suficientes (comprimento, [] operador) para serem usadassort()
.fonte
A herança prototípica (popularizada por Douglas Crockford) revoluciona completamente a maneira como você pensa sobre muitas coisas em Javascript.
É um assassino! Pena como quase ninguém a usa.
Permite "gerar" novas instâncias de qualquer objeto, estendê-las, mantendo um link de herança prototípica (ao vivo) para suas outras propriedades. Exemplo:
fonte
Alguns chamariam isso de questão de gosto, mas:
O operador trinário pode ser encadeado para agir como o de Scheme (cond ...):
pode ser escrito como ...
Isso é muito "funcional", pois ramifica seu código sem efeitos colaterais. Então, em vez de:
Você pode escrever:
Também funciona bem com recursão :)
fonte
Números também são objetos. Então você pode fazer coisas legais como:
fonte
times
não é eficiente:Math.floor
é chamada sempre, em vez de apenas uma vez.Que tal fechamentos em JavaScript (semelhante aos métodos anônimos no C # v2.0 +). Você pode criar uma função que cria uma função ou "expressão".
Exemplo de fechamentos :
fonte
Você também pode estender (herdar) classes e substituir propriedades / métodos usando a colher de cadeia de protótipo16 mencionada.
No exemplo a seguir, criamos uma classe Pet e definimos algumas propriedades. Também substituímos o método .toString () herdado de Object.
Depois disso, criamos uma classe Dog que estende Pet e substitui o método .toString () novamente alterando seu comportamento (polimorfismo). Além disso, adicionamos outras propriedades à classe filho.
Depois disso, verificamos a cadeia de herança para mostrar que Dog ainda é do tipo Dog, do tipo Pet e do tipo Object.
Ambas as respostas a essa pergunta foram códigos modificados a partir de um ótimo artigo do MSDN de Ray Djajadinata.
fonte
Você pode capturar exceções, dependendo do tipo. Citado pelo MDC :
NOTA: As cláusulas de captura condicional são uma extensão do Netscape (e, portanto, do Mozilla / Firefox) que não faz parte da especificação do ECMAScript e, portanto, não pode ser invocada, exceto em navegadores específicos.
fonte
Em cima da minha cabeça...
Funções
argumentos.callee refere-se à função que hospeda a variável "argumentos", para que possa ser usada para processar funções anônimas:
Isso é útil se você quiser fazer algo assim:
Objetos
Uma coisa interessante sobre os membros do objeto: eles podem ter qualquer string como nome:
Cordas
String.split pode usar expressões regulares como parâmetros:
String.replace pode usar uma expressão regular como parâmetro de pesquisa e uma função como parâmetro de substituição:
fonte
arguments.callee
é obsoleto e irá lançar e exceção no ECMAScript 5.Você pode usar objetos em vez de alternar na maioria das vezes.
Atualização: se você está preocupado com a ineficiência dos casos em avaliar antecipadamente (por que você está preocupado com a eficiência no início do design do programa?), Pode fazer algo assim:
É mais oneroso para digitar (ou ler) do que um comutador ou um objeto, mas preserva os benefícios do uso de um objeto em vez de um comutador, detalhados na seção de comentários abaixo. Esse estilo também torna mais fácil transformar isso em uma "classe" adequada, uma vez que cresce o suficiente.
update2: com extensões de sintaxe propostas para ES.next, isso se torna
fonte
var arr = []; typeof arr; // object
Certifique-se de usar o método hasOwnProperty ao iterar pelas propriedades de um objeto:
Isso é feito para que você acesse apenas as propriedades diretas de anObject e não use as propriedades que estão na cadeia de protótipos.
fonte
Variáveis privadas com uma interface pública
Ele usa um pequeno truque com uma definição de função de chamada automática. Tudo dentro do objeto retornado está disponível na interface pública, enquanto todo o resto é privado.
fonte