A instanceof
palavra-chave em JavaScript pode ser bastante confusa quando é encontrada pela primeira vez, pois as pessoas tendem a pensar que o JavaScript não é uma linguagem de programação orientada a objetos.
- O que é isso?
- Que problemas ele resolve?
- Quando é apropriado e quando não?
javascript
operators
instanceof
Alon Gubkin
fonte
fonte
"foo" instanceof String
=> falso,1 instanceof Number
=> falso,{} instanceof Object
=> falso. Diga o quê?!"foo" instanceof String => false
está correto, porquetypeof "foo" == 'string'
.new String("foo") instanceof String => true
, porquetypeof String == 'function'
- você deve tratar a função como classe (definição de classe). A variável se tornainstanceof
algumafunction
(classe) quando você a atribui comovar v = new AnythingWhatTypeofEqualsFunction()
. O mesmo se aplica a1
.typeof 1 == 'number'
- 'number' não é 'function' :) Em seguida -{} instanceof Object
estáTRUE
no nó e nos navegadores modernos({}) instanceof Object
retornarátrue
. De fato, o código que você escreveu causará um erro.Respostas:
instancia de
O operando do lado esquerdo (LHS) é o objeto real sendo testado no operando do lado direito (RHS), que é o construtor real de uma classe. A definição básica é:
Aqui estão alguns bons exemplos e um exemplo extraído diretamente do site de desenvolvedores da Mozilla :
Uma coisa que vale a pena mencionar é
instanceof
avaliada como verdadeira se o objeto herdar do protótipo da classe:Isso é
p instanceof Person
verdade, poisp
herda dePerson.prototype
.Por solicitação do OP
Adicionei um pequeno exemplo com algum código de exemplo e uma explicação.
Quando você declara uma variável, atribui a ela um tipo específico.
Por exemplo:
O acima mostrar-lhe algumas variáveis, ou seja
i
,f
, ec
. Os tipos sãointeger
,float
e um utilizador definidoCustomer
tipo de dados. Tipos como o acima podem ser para qualquer idioma, não apenas JavaScript. No entanto, com JavaScript, quando você declara uma variável, você não define explicitamente um tipovar x
, x pode ser um número / string / um tipo de dados definido pelo usuário. Então, o queinstanceof
faz é checar o objeto para ver se é do tipo especificado, de cima, pegar oCustomer
objeto que poderíamos fazer:Acima vimos que
c
foi declarada com o tipoCustomer
. Nós o atualizamos e verificamos se é do tipoCustomer
ou não. Certamente, ele retorna verdadeiro. Ainda usando oCustomer
objeto, verificamos se é umString
. Não, definitivamente não é umString
novoCustomer
objeto, não umString
objeto. Nesse caso, ele retorna false.É realmente muito simples!
fonte
color1 instanceof String;
isso retornará true porque color1 é uma string.person p = new person()
p agora é um tipo de pessoa e não um tipo de string.var zero = 0; alert(zero); zero = "0"; alert(zero)
passamos de um primitivoint
para um primitivostring
sem problemas.int
para primitivostring
.Há uma faceta importante, por exemplo, que parece não estar coberta em nenhum dos comentários até agora: herança. Uma variável que está sendo avaliada pelo uso de instanceof pode retornar true para vários "tipos" devido à herança prototípica.
Por exemplo, vamos definir um tipo e um subtipo:
Agora que temos algumas "classes", vamos criar algumas instâncias e descobrir do que são instâncias:
Vê a última linha? Todas as chamadas "novas" para uma função retornam um objeto que herda de Object. Isso vale mesmo quando se usa uma abreviação de criação de objeto:
E as próprias definições de "classe"? De que são exemplos?
Eu sinto que entender que qualquer objeto pode ser uma instância de vários tipos é importante, já que você (incorretamente) assume que pode diferenciar entre, digamos, objeto e uma função usando
instanceof
. Como este último exemplo mostra claramente uma função é um objeto.Isso também é importante se você estiver usando qualquer padrão de herança e quiser confirmar a descendência de um objeto por outros métodos que não a digitação de patos.
Espero que ajude alguém a explorar
instanceof
.fonte
SubFoo.prototype = new Foo();
você pode adicionar mais métodos para isso, e osubfoo instanceof Foo
cheque ainda vai passar, bem comosubfoo instanceof SubFoo
As outras respostas aqui estão corretas, mas elas não explicam como
instanceof
realmente funciona, o que pode ser do interesse de alguns advogados de idiomas por aí.Todo objeto em JavaScript possui um protótipo, acessível através da
__proto__
propriedade As funções também têm umaprototype
propriedade, que é a inicial__proto__
de qualquer objeto criado por elas. Quando uma função é criada, recebe um objeto exclusivo paraprototype
. Oinstanceof
operador usa essa exclusividade para dar uma resposta. Aqui está o queinstanceof
pode parecer se você o escreveu como uma função.Isso é basicamente parafraseando a ECMA-262 edição 5.1 (também conhecida como ES5), seção 15.3.5.3.
Observe que você pode reatribuir qualquer objeto à
prototype
propriedade de uma função e pode reatribuir a__proto__
propriedade de um objeto após sua construção. Isso fornecerá alguns resultados interessantes:fonte
__proto__
propriedade " " não é permitida no IE. Se bem me lembro, a manipulação direta da propriedade também não está incluída nas especificações da ECMA; portanto, provavelmente é uma má idéia usá-la para tarefas que não sejam atividades acadêmicas.Object.getPrototypeOf(o)
, será o mesmo que__proto__
você descreve, mas está em conformidade com o ECMAScript.Eu acho que vale a pena notar que instanceof é definido pelo uso da palavra-chave "new" ao declarar o objeto. No exemplo de JonH;
O que ele não mencionou é isso;
A especificação de "new" na verdade copiou o estado final da função do construtor String para a var color1, em vez de apenas defini-lo com o valor de retorno. Eu acho que isso mostra melhor o que a nova palavra-chave faz;
Usar "novo" atribui o valor de "this" dentro da função ao var declarado, enquanto não o usa atribui o valor de retorno.
fonte
new
qualquer um dos tipos de JavaScript, o que torna a resposta aceita muito mais confusa para iniciantes.text = String('test')
eoptions = {}
não serão testados,instanceof
mas sim comtypeof
.E você pode usá-lo para tratamento de erros e depuração, assim:
fonte
fonte
Javascript é uma linguagem prototípica, o que significa que usa protótipos para 'herança'. o
instanceof
operador testa se o tipo deprototype
propriedade de uma função construtora está presente na__proto__
cadeia de um objeto. Isso significa que ele fará o seguinte (assumindo que testObj é um objeto de função):obj.__proto__ === testObj.prototype
>> se este fortrue
instanceof
retornarátrue
.obj.__proto__.__proto__ === testObj.prototype
>> se fortrue
instanceof
o caso retornarátrue
.testObj.prototype
, oinstanceof
operador retornaráfalse
.Exemplo:
Resolveu o problema de verificar convenientemente se um objeto deriva de um determinado protótipo. Por exemplo, quando uma função recebe um objeto que pode ter vários protótipos. Então, antes de usar métodos da cadeia de protótipos, podemos usar o
instanceof
operador para verificar se esses métodos estão no objeto.Exemplo:
Aqui na
talk()
função primeiro é verificado se o protótipo está localizado no objeto. Depois disso, o método apropriado é escolhido para execução. Não fazer essa verificação pode resultar na execução de um método que não existe e, portanto, um erro de referência.Nós meio que já repassamos isso. Use-o quando precisar verificar o protótipo de um objeto antes de fazer algo com ele.
fonte
PersonX.prototype.talk
, para que atalk
função possa simplesmente fazê-loperson.talk()
.__proto__
na documentação, ele está obsoleto - writeObject.getPrototype()
vezSobre a pergunta "Quando é apropriado e quando não?", Meus 2 centavos:
instanceof
raramente é útil no código de produção, mas útil em testes nos quais você deseja afirmar que seu código retorna / cria objetos dos tipos corretos. Por ser explícito sobre os tipos de objetos que seu código está retornando / criando, seus testes se tornam mais poderosos como uma ferramenta para entender e documentar seu código.fonte
instanceof
é apenas açúcar sintático paraisPrototypeOf
:instanceof
depende apenas do protótipo de um construtor de um objeto.Um construtor é apenas uma função normal. A rigor, é um objeto de função, pois tudo é um objeto em Javascript. E esse objeto de função tem um protótipo, porque toda função tem um protótipo.
Um protótipo é apenas um objeto normal, localizado na cadeia de protótipos de outro objeto. Isso significa que estar na cadeia de protótipos de outro objeto transforma um objeto em um protótipo:
O
instanceof
operador deve ser evitado porque falsifica classes, que não existem em Javascript. Apesar daclass
palavra - chave também não no ES2015, já queclass
é apenas açúcar sintático para ... mas isso é outra história.fonte
instanceof
é derivadoisPrototypeOf
. Eu chamo isso de açúcar sintático. E sua fonte MDN é uma piada, não é?instanceof
não faz a mesma coisa queisPrototypeOf
. É isso aí.Acabei de encontrar um aplicativo do mundo real e o utilizarei com mais frequência agora, eu acho.
Se você usa eventos jQuery, às vezes deseja escrever uma função mais genérica que também pode ser chamada diretamente (sem evento). Você pode
instanceof
verificar se o primeiro parâmetro da sua função é uma instânciajQuery.Event
e reagir adequadamente.No meu caso, a função precisava calcular algo para todos (via evento click em um botão) ou apenas um elemento específico. O código que eu usei:
fonte