No meu caso particular:
callback instanceof Function
ou
typeof callback == "function"
isso importa, qual é a diferença?
Recurso adicional:
JavaScript-Garden typeof vs instanceof
javascript
instanceof
typeof
farinspace
fonte
fonte
Object.prototype.toString
ecma-international.org/ecma-262/6.0/….constructor
propriedade.Respostas:
Use
instanceof
para tipos personalizados:Use
typeof
para tipos simples incorporados:Use
instanceof
para tipos integrados complexos:E o último é um pouco complicado:
fonte
Use instanceof for complex built in types
- isso ainda é propenso a erros. Melhor usar ES5Array.isArray()
et al. ou os calços recomendados.Ambos são semelhantes em funcionalidade porque ambos retornam informações de tipo, no entanto, eu pessoalmente prefiro
instanceof
porque ele está comparando tipos reais em vez de strings. A comparação de tipos é menos propensa a erros humanos, e é tecnicamente mais rápida, pois está comparando ponteiros na memória, em vez de fazer comparações de cadeias inteiras.fonte
Um bom motivo para usar typeof é se a variável pode ser indefinida.
Um bom motivo para usar instanceof é se a variável pode ser nula.
Então, realmente, na minha opinião, isso dependeria de que tipo de dados possíveis você está verificando.
fonte
instanceof
não é possível comparar com tipos primitivos, typeof can.undefined instanceof Object
retorna false e não gera uma exceção. Não sei quão recente é essa mudança, mas ela se tornainstanceof
mais atraente.undefined instanceof Object
não lança uma exceção porque, eh,undefined
está definido. A constante existe no espaço para nome. Quando uma variável não existe (devido a erros de digitação, por exemplo), instanceof lançará uma exceção. Usar typeof em uma variável inexistente gera 'indefinido', por outro lado.Para deixar as coisas claras, você precisa conhecer dois fatos:
Object.setPrototypeOf()
método (ECMAScript 2015) ou pela__proto__
propriedade (navegadores antigos, obsoletos). Não é recomendável alterar o protótipo de um objeto, devido a problemas de desempenho.Assim, instanceof é aplicável apenas a objetos. Na maioria dos casos, você não está usando construtores para criar seqüências ou números. Você pode. Mas você quase nunca faz.
Também instanceof não pode verificar, exatamente qual construtor foi usado para criar o objeto, mas retornará true, mesmo se o objeto for derivado da classe que está sendo verificada. Na maioria dos casos, esse é o comportamento desejado, mas às vezes não é. Então você precisa manter essa mente.
Outro problema é que diferentes escopos têm diferentes ambientes de execução. Isso significa que eles têm diferentes recursos internos (objeto global diferente, diferentes construtores etc.). Isso pode resultar em resultados inesperados.
Por exemplo,
[] instanceof window.frames[0].Array
retornaráfalse
, porqueArray.prototype !== window.frames[0].Array
e matrizes herdam da primeira.Além disso, ele não pode ser usado com valor indefinido, porque não possui um protótipo.
Agora vamos falar sobre uma coisa complicada. E se você usar o construtor para criar um tipo primitivo?
Parece mágica. Mas não é. É o chamado boxe (agrupando o valor primitivo por objeto) e o unboxing (extraindo o valor primitivo agrupado do objeto). Esse tipo de código parece ser "um pouco" frágil. Obviamente, você pode evitar criar tipos primitivos com construtores. Mas há outra situação possível, quando o boxe pode atingir você. Quando você usa Function.call () ou Function.apply () em um tipo primitivo.
Para evitar isso, você pode usar o modo estrito:
upd: Desde o ECMAScript 2015, há mais um tipo chamado Symbol, que possui seu próprio typeof == "symbol" .
Você pode ler sobre isso no MDN: ( Símbolo , tipo de ).
fonte
if an object is created by a given constructor
Isto está incorreto.o instanceof C
retornará true se o herda de C.prototype. Você mencionou algo sobre isso mais tarde na sua resposta, mas não está muito claro.Eu descobri um comportamento realmente interessante (lido como "horrível") no Safari 5 e no Internet Explorer 9. Eu estava usando isso com muito sucesso no Chrome e Firefox.
Então eu testo no IE9, e não funciona. Grande surpresa. Mas no Safari, é intermitente! Então, inicio a depuração e acho que o Internet Explorer é sempre retornando
false
. Mas o mais estranho é que o Safari parece estar fazendo algum tipo de otimização em sua VM JavaScript, onde étrue
a primeira vez, masfalse
toda vez que você clica em recarregar!Meu cérebro quase explodiu.
Então agora eu decidi sobre isso:
E agora tudo funciona muito bem. Observe que você pode chamar
"a string".toString()
e ele apenas retorna uma cópia da string, ou seja,Então, eu vou usar os dois a partir de agora.
fonte
Outras diferenças práticas significativas:
fonte
instanceof
também funciona quandocallback
é um subtipoFunction
, achofonte
instanceof
em Javascript pode ser esquisito - acredito que grandes estruturas tentam evitar seu uso. Janelas diferentes é uma das maneiras pelas quais ele pode quebrar - acredito que as hierarquias de classe também podem confundi-lo.Existem maneiras melhores de testar se um objeto é um determinado tipo interno (que geralmente é o que você deseja). Crie funções utilitárias e use-as:
E assim por diante.
fonte
instanceof
não funcionará para primitivos, por exemplo"foo" instanceof String
, retornaráfalse
enquantotypeof "foo" == "string"
retornarátrue
.Por outro lado
typeof
, provavelmente não fará o que você quer quando se trata de objetos personalizados (ou classes, como você quiser chamá-los). Por exemplo:Acontece que as funções são primitivas da 'função' e instâncias da 'Função', o que é um pouco estranho, uma vez que não funciona assim para outros tipos primitivos, por exemplo.
mas
fonte
Eu recomendaria o uso de protótipos
callback.isFunction()
.Eles descobriram a diferença e você pode contar com a razão deles.
Eu acho que outras estruturas JS também têm essas coisas.
instanceOf
não funcionaria em funções definidas em outras janelas, acredito. A função deles é diferente da suawindow.Function
.fonte
Ao verificar uma função, é preciso sempre usar
typeof
.Aqui está a diferença:
É por isso que nunca se deve usar
instanceof
para verificar uma função.fonte
typeof
que está errado -f
é o seguinte: umObject
(um objeto) e umaFunction
(uma função). Exceto para mim, faz mais sentido usarinstanceof
porque, sabendo que é uma função, sei que também é um objeto, pois todas as funções são objetos no ECMAScript. O inverso não é verdadeiro - sabendotypeof
dissof
é de fato umobject
eu não tenho idéia de que também é uma função.length
,name
ecall
de função, mas todos eles são extinta. O que é pior, ele não pode ser chamado eoTypeError
diz que:f is not a function
.Diferença prática significativa:
Não me pergunte o porquê.
fonte
str
está uma cadeia de caracteres primitiva, não um objeto de cadeia. O mesmo vale para primitivas numéricas e primitivas booleanas, elas não são instâncias de suas contrapartes "construídas", os objetos String, Number e Boolean. O JavaScript converte automaticamente essas três primitivas em objetos quando necessário (como a utilização de um método na cadeia de protótipos do objeto). Por outro lado, sua diferença prática, instanceof é melhor para verificar as matrizes desde entãotypeof [] == "object" // true
.atuação
typeof
é mais rápido do queinstanceof
nas situações em que ambos são aplicáveis.Dependendo do seu mecanismo, a diferença de desempenho a favor
typeof
pode ser de cerca de 20% . ( Sua milhagem pode variar )Aqui está um teste de benchmark para
Array
:Resultado
fonte
instanceof
sempre segue a cadeia de protótipos do objeto; portanto, a penalidade no desempenho dependerá do nível de classe da cadeia de protótipos em queinstanceof
for testada. Portanto, para uma cadeia de herança curta, a penalidade será menor (como[] instanceof Array
,,{} instanceof Object
) e por muito tempo maior. Portanto, se ambosobj instanceof SomeClass
etypeof obj !== 'string'
significam o mesmo da perspectiva de algum código hipotético (por exemplo, se você está apenas testandoif
e nãoswitch
analisando várias classes etc.), é melhor escolher o segundo, em termos de desempenho,Este é apenas conhecimentos complementares a todas as outras explicações aqui - estou não sugerindo a utilizar
.constructor
em todos os lugares.TL; DR: Em situações em que
typeof
não é uma opção e quando você sabe que não se importa com a cadeia de protótipos ,Object.prototype.constructor
pode ser uma alternativa viável ou até melhor do queinstanceof
:Ele está no padrão desde a versão 1.1, então não se preocupe com a compatibilidade com versões anteriores.
Muhammad Umer mencionou brevemente isso em um comentário em algum lugar aqui também. Funciona em tudo com um protótipo - portanto, tudo não
null
ouundefined
:Além disso, dependendo do seu caso de uso, pode ser muito mais rápido do que
instanceof
(o motivo provavelmente é que ele não precisa verificar toda a cadeia de protótipos). No meu caso, eu precisava de uma maneira rápida de verificar se um valor é uma matriz digitada:https://run.perf.zone/view/isTypedArray-constructor-vs-instanceof-1519140393812
E os resultados:
Chrome 64.0.3282.167 (64 bits, Windows)
Firefox 59.0b10 (64 bits, Windows)
Por curiosidade, fiz uma referência rápida de brinquedo contra
typeof
; surpreendentemente, ele não apresenta um desempenho muito pior e parece ainda mais rápido no Chrome:https://run.perf.zone/view/typeof-vs-constructor-string-or-number-1519142623570
NOTA: A ordem na qual as funções estão listadas alterna entre imagens!
Chrome 64.0.3282.167 (64 bits, Windows)
Firefox 59.0b10 (64 bits, Windows)
NOTA: A ordem na qual as funções estão listadas alterna entre imagens!
fonte
Use instanceof porque se você alterar o nome da classe, receberá um erro do compilador.
fonte
fonte
Vindo de uma educação estrita OO eu iria para
Cordas são propensas a minha ortografia terrível ou outros erros de digitação. Além disso, sinto que lê melhor.
fonte
Apesar de instanceof poder ser um pouco mais rápido que o typeof , prefiro o segundo por causa de uma mágica possível:
fonte
Mais um caso é que você só pode comparar
instanceof
- ele retorna verdadeiro ou falso. Comtypeof
você pode obter o tipo de algo fornecidofonte
com o desempenho em mente, é melhor usar typeof com um hardware típico, se você criar um script com um loop de 10 milhões de iterações, a instrução: typeof str == 'string' levará 9ms, enquanto 'string' instanceof String levará 19ms
fonte
Claro que importa ........!
Vamos seguir com exemplos. No nosso exemplo, declararemos a função de duas maneiras diferentes.
Nós estaremos usando ambos
function declaration
e Function Constructor . Vamos ver comotypeof
einstanceof
se comportar nesses dois cenários diferentes.Crie uma função usando a declaração de função:
A explicação possível para um resultado tão diferente é que, como fizemos uma declaração de função,
typeof
podemos entender que é uma função.typeof
Porque verifica se a expressão em que typeof está operando, no nosso caso, implementou o método de chamada ou não . Se ele implementa método é uma function.Otherwise não .Para verificação esclarecimentos especificação ECMAScript para typeof .MyFunc
Call
Crie uma função usando o construtor de funções:
Aqui
typeof
afirma queMyFunc2
é uma função bem como ainstanceof
operator.We já sabetypeof
seleção seMyFunc2
implementadoCall
método ou not.AsMyFunc2
é uma função e ele implementacall
método, é assim quetypeof
sabe que é um function.On outro lado, foi utilizadofunction constructor
para criarMyFunc2
, ele torna-se uma instância deFunction constructor
. É por isso queinstanceof
também resolvetrue
.O que é mais seguro de usar?
Como podemos ver nos dois casos, o
typeof
operador pode afirmar com êxito que estamos lidando com uma função aqui, é mais seguro queinstanceof
.instanceof
falhará no caso defunction declaration
porquefunction declarations
não é uma instância deFunction constructor
.Melhor prática :
Como Gary Rafferty sugeriu, a melhor maneira deve ser usar o tipo e a instância de juntos.
fonte
Para ser muito preciso, deve-se usar instanceof em que o valor é criado através do construtor (geralmente tipos personalizados), por exemplo
enquanto typeof para verificar valores criados apenas por atribuições para, por exemplo
fonte
não há necessidade de sobrecarregar-se com vários exemplos acima, mas lembre-se de dois pontos de vista:
typeof var;
é um operador unário retornará o tipo original ou o tipo raiz de var. de modo que ela retorne tipos de primitivas (string
,number
,bigint
,boolean
,undefined
, esymbol
) ouobject
do tipo.no caso de objetos de nível superior, como objetos internos (String, Number, Boolean, Array ..) ou objetos complexos ou personalizados, todos eles são do
object
tipo raiz, mas o tipo de instância construído com base neles é variável (como a classe OOP conceito de herança), aquia instanceof A
- um operador binário - irá ajudá-lo, ele percorrerá a cadeia de protótipos para verificar se o construtor do operando certo (A) aparece ou não.portanto, sempre que desejar verificar "tipo raiz" ou trabalhar com variável primitiva - use "typeof", caso contrário, use "instanceof".
null
é um caso especial, aparentemente primitivo, mas de fato é um caso especial para objeto. Usandoa === null
para verificar nulo.por outro lado,
function
também é um caso especial, que é um objeto embutido, mastypeof
retornafunction
como você pode ver,
instanceof
deve passar pela cadeia de protótipos enquanto isso,typeof
basta verificar o tipo de raiz uma vez, para que seja fácil entender por quetypeof
é mais rápido do queinstanceof
fonte
De acordo com a documentação do MDN sobre typeof , os objetos instanciados com a palavra-chave "new" são do tipo 'object':
Enquanto a documentação sobre instanceof aponta que:
Portanto, se alguém quiser verificar, por exemplo, se algo é uma string, não importa como ela foi criada, a abordagem mais segura seria usar
instanceof
.fonte