Pergunta

Eu vi em mdn o código que deve ser usado - se não houver indexOf implementação.

Este algoritmo corresponde ao especificado na ECMA-262 ... como eles dizem

E aqui está o código:

/*1*/   if (!Array.prototype.indexOf) {
/*2*/     Array.prototype.indexOf = function (searchElement , fromIndex) {
/*3*/       var i,
/*4*/           pivot = (fromIndex) ? fromIndex : 0,
/*5*/           length;
/*6*/   
/*7*/       if (!this) {
/*8*/         throw new TypeError();
/*9*/       }
/*10*/   
/*11*/       length = this.length;
/*12*/   
/*13*/       if (length === 0 || pivot >= length) {
/*14*/         return -1;
/*15*/       }
/*16*/   
/*17*/       if (pivot < 0) {
/*18*/         pivot = length - Math.abs(pivot);
/*19*/       }
/*20*/   
/*21*/       for (i = pivot; i < length; i++) {
/*22*/         if (this[i] === searchElement) {
/*23*/           return i;
/*24*/         }
/*25*/       }
/*26*/       return -1;
/*27*/     };
/*28*/   }

Mas minha pergunta é sobre a linha #7:

Se eu escrever:

[].indexOf então - this é a própria matriz. (Heck, está anexado a Array.prototype.indexOf - em primeiro lugar).

Quero dizer - this sempre será o valor verdadeiro. assim Por quê essa verificação existe?

Além disso - Resharper me mostra isso (que é perfeitamente lógico):

enter image description here

Então - por que essa verificação existe? Estou perdendo alguma coisa aqui?

Foi útil?

Solução

Não necessariamente - é porque o indexOf() Função nativa usa o direto this valor aprovado, não aquele convertido em um objeto (equivalente ao que acontece no modo rigoroso), e esse calço precisaria verificar se isso fosse compatível. Por exemplo, este código jogará um TypeError:

var a = Array.prototype.indexOf;
a();

Vai jogar um TypeError, Enquanto o this O valor não é convertido em um objeto ou alterado para o objeto global. Nas funções não rigíveis definidas pelo usuário, o valor de this é o objeto global se não houver objeto pai, mas no modo estrito ES5, ele é passado como undefined em si. Outra situação é quando você chama especificamente com qualquer null ou undefined:

"use strict";
Array.prototype.indexOf.call(null); // TypeError, what else can we do?

Na especificação ES5, a isto valor refere -se ao valor original aprovado como o thisArg, sem nenhuma alteração. No modo não rito, a isto valor não é acessível ao código em funções definidas pelo usuário, mas as funções nativas são capazes de especificar explicitamente o uso de a isto valor em vez do que o this a palavra -chave avalia (que é referido como o ThisBinding na especificação). No modo rigoroso, ambos avaliam a mesma coisa.

Porque a versão nativa pode acessar a versão não caixa do this valor no modo não rigoroso (que é passado diretamente para a função interna [[ToObject]], que joga um TypeError Ao tentar converter null ou undefined), essa verificação precisa ser implementada para atender aos requisitos da especificação.

Nota: Tecnicamente, a amostra de código em sua pergunta não é bastante pela especificação ES5, como o this o valor pode ser falsamente, o que falharia, mesmo que deve proceder em teoria (implementações nativas de indexOf() Não jogue se false é passado como o this valor). Também, já que o objeto global seria aprovado se o valor deste era realmente indefinido ou nulo, passava pelo if (!this) teste, mesmo quando não deve. Isso não pode ser resolvido simplesmente verificando se o argumento não é o objeto global, porque isso falharia se o objeto global fosse explicitamente aprovado (o que é permitido).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top