Por que não posso atribuir um novo valor a “this” em uma function de protótipo?

Por que eu posso fazer isso:

Array.prototype.foo = function() { this.splice(0, this.length); return this.concat([1,2,3]); } 

Mas eu não posso fazer isso:

 Array.prototype.foo = function() { return this = [1,2,3]; } 

Ambas as funções destroem o valor disso e mudam para [1,2,3] mas o segundo gera o seguinte erro: Uncaught ReferenceError: Invalid left-hand side in assignment

Eu suspeito que seja porque permitir a atribuição significa que eu poderia potencialmente mudar a matriz para outra coisa (como uma string), mas espero que alguém de fora saiba ao certo e / ou tenha uma explicação mais detalhada.

Não é permitido atribuir um valor a this dentro de uma function. Suponha que você possa fazer isso e seu código seja parecido com:

 Array.prototype.foo = function() { return this = [1, 2, 3]; } var a = ["beans", "rice"]; a.foo(); // a now points to an object containing [1, 2, 3] 

Agora, e se você fez isso:

 var a = ["beans", "rice"]; var b = a; // b refers to the same object as a b.foo(); // what does b refer to now? how about a? 

O ato de chamar uma function .foo() em um object não deve alterar a identidade do object. Isso seria muito confuso para o chamador se de repente começasse a se referir a um object diferente de a simplesmente porque algum método foi chamado.

Você está confundindo objects com referências.

Uma matriz é um object, quando você usa um literal como [1,2,3] você está criando uma nova matriz.

Um nome de variável como this ou a é uma referência a um object. Se isso ajudar, imagine um object como pessoa e a referência como seu apelido. Você pode ter mais de uma referência ao mesmo object, por exemplo:

 var a = [1,2]; var b = a; b.push(3); alert(a.length); // Gives "3" 

Imagine se você tivesse uma amiga chamada Sarah. Você também as chama de “Ace”. Se Sarah corta o cabelo um dia, Ace também tem um corte de cabelo, porque “Sarah” e “Ace” são nomes diferentes para a mesma pessoa.

Se você usar um método de matriz mutante como a.push ou a.splice (a concat não é uma!), Você altera o object Array existente e ainda se refere ao mesmo object. Isso é como cortar o cabelo – você pode parecer diferente, mas ainda é a mesma pessoa.

Quando você atribui uma referência a um novo valor, com a = [1,2,3] , você está criando uma nova matriz e alterando a para se referir a ela. É como encontrar um novo amigo com cabelo diferente e decidir chamá-lo de Ace.

Agora this é um nome especial gerado pelo Javascript. Não é um nome dado como Sarah, mas mais um título, como “mãe”. Sua mãe pode fazer um novo corte de cabelo, mas você não pode ter uma nova mãe. Da mesma forma, você não pode mudar o que this dentro de uma function.

Você não tem permissão para reatribuir this . Porque esse valor associado a um contexto de execução é imutável.

É possível alterar o valor this ? Não por atribuição, você não pode atribuir um valor a this

Seu caso:

 Array.prototype.foo = function() { this.splice(0, this.length); return this.concat([1,2,3]); } 

Mas eu não posso fazer isso:

 Array.prototype.foo = function() { return this = [1,2,3]; } 

Quando você modifica o método de adição de protótipo foo() , a primeira parte torna a matriz vazia, igual a reatribuir sua instância.

Por exemplo, para var a = []

Então, no valor de retorno:

 return this.concat([1,2,3]); 

Lembre-se que a concat não destrói uma matriz, cria uma nova matriz e a devolve

Dado a = ['x'] b = ['y'] , c = a.concat(b) resulta em c = ['x','y'] , e a e b permanecem os mesmos que foram

Agora, já que você está fazendo isso dentro da matriz

 a=['a','b','c'] 

então você chama a.foo(); , dentro de a será igual a=[] , com this.splice(0, this.length); então concatenará [ ] com [1,2,3]

Então, se eu disser apenas a.foo() , na verdade nada acontece fora se eu não atribuir o resultado a algo, apenas um permanece vazio.

Se a é atribuído a algo

 c = a.foo() 

então c será [1,2,3] e a ainda vazio [ ]

Na segunda parte, this = [1,2,3]

É possível alterar o valor disto ?, não por atribuição, você não pode atribuir um valor a este