A diferença entre a função de seta e a função comum
Como a sintaxe de função de seta recém-adicionada no ES6, ela é profundamente amada pelos desenvolvedores e também é uma pergunta típica que costuma ser feita durante entrevistas de front-end. Ele não apenas simplifica nosso código, mas também permite que os desenvolvedores se livrem do "errático" neste ponto.Este artigo analisa a diferença entre funções de seta e funções comuns.
Na minha opinião, o que mais preocupa o entrevistador e a diferença mais crítica entre os dois é a diferença desse apontamento. Isso em uma função normal aponta para o objeto que a função é chamada, portanto, para chamadores diferentes, o valor desse é diferente. A função de seta não tem seu próprio this (ao mesmo tempo, não há outras variáveis locais na função de seta, como this, argumento, super, etc.), então o this na função de seta é fixo e aponta para o objeto onde a função é definida.
Funções comuns
Acredito que todos já estejam muito familiarizados com o uso de funções comuns, vamos dar um exemplo simples abaixo.
var a = 3;
var obj = {
a : 1,
foo : function(){
console.log(this.a);
}
}
obj.foo(); //1
var bar = obj;
bar.a = 2;
bar.foo(); //2
var baz = obj.foo;
baz(); //3
No código acima, existem três situações:
Chame o método foo diretamente através de obj. Neste momento, este apontará para o objeto que chama a função foo, ou seja, obj;
atribua o objeto obj a uma nova barra de objetos. Neste momento, chame a função foo através de bar, e o valor disso será Aponte para a barra do chamador;
atribua obj.foo a um novo objeto baz, chame a função foo por meio de baz(), neste momento isso aponta para janela;
disso podemos tirar uma conclusão:
O this de uma função normal sempre se refere ao seu chamador direto.
No modo estrito, se nenhum chamador direto for encontrado, isso na função é indefinido.
No modo padrão (modo não estrito), se nenhum chamador direto for encontrado, isso na função aponta para janela.
Considere novamente a seguinte situação:
var obj = {
a : 1,
foo : function(){
setTimeout(
function(){
console.log(this.a),3000})
}
}
obj.foo(); //undefined
Você pode pensar que a saída deve ser 1 neste ponto, mas o resultado é indefinido. Porque neste momento isso aponta para o objeto de janela global.
Através dos exemplos acima, as seguintes conclusões podem ser tiradas:
Para um método (ou seja, a função é chamada por meio de um objeto), this em uma função comum sempre aponta para seu chamador.
Para funções gerais, isso aponta para variáveis globais (no modo não estrito) ou indefinidas (no modo estrito). No exemplo acima, a função em setTimeout não é chamada por nenhum objeto, então este ponto ainda é o objeto janela. Portanto, isso também pode ser resumido da seguinte forma: javascript's isso pode ser simplesmente considerado como ligação tardia.Quando não há lugar para vincular, ele será vinculado à janela ou indefinido por padrão.
E se quisermos usar isso na função setTimeout no exemplo acima? Antes do surgimento das funções de seta, tendemos a usar os dois métodos a seguir:
Fora da função setTimeout, ou seja, dentro da função de nível superior foo, isso é obtido atribuindo o valor this a uma variável temporária.
var obj = {
a : 1,
foo : function(){
var that = this;
setTimeout(
function(){
console.log(that.a),3000})
}
}
obj.foo(); //1
Vincule isso por meio de bind ().
var obj = {
a : 1,
foo : function(){
setTimeout(
function(){
console.log(this.a),3000}.bind(this))
}
}
obj.foo(); //1
Esse fenômeno foi aprimorado após a introdução das funções de seta no ES6.
Função de seta
A função de seta é um novo recurso introduzido no ES6, o método de uso é:
()=>{
console.log(this)}
O () é o parâmetro a ser inserido e o {} é a instrução a ser executada. A função de seta é uma manifestação da programação funcional. A programação funcional coloca mais foco na relação entre entrada e saída, omitindo alguns fatores do processo, portanto, a função de seta não possui seu próprio this, argumentos, novo alvo (ES6) e super( ES6). As funções de seta são equivalentes a funções anônimas, portanto, new não pode ser usado como construtor.
A função this em uma seta sempre aponta para this em seu escopo pai. Em outras palavras, a função de seta captura o valor this de seu contexto como seu próprio valor this. Qualquer método não pode mudar seu ponto, como call(), bind(), apply(). Quando this é chamado em uma função de seta, ele simplesmente procura na cadeia de escopo e encontra o this mais próximo para usar, o que não tem nada a ver com o contexto da chamada. Vamos explicar com código.
var obj = {
a: 10,
b: () => {
console.log(this.a); // undefined
console.log(this); // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
},
c: function() {
console.log(this.a); // 10
console.log(this); // {a: 10, b: ƒ, c: ƒ}
},
d:function(){
return ()=>{
console.log(this.a); // 10
}
},
e:function(){
setTime
}
}
obj.b();
obj.c();
obj.d()();
Basta analisar o código, isso em obj.b() vai herdar o valor this no contexto pai, ou seja, tem o mesmo ponto this que obj, e é a variável global window. O ponto this de obj.c() é o chamador obj, e o this em obj.d().() também herda do this no contexto pai, ou seja, o ponto this de d, que é obj.
Através deste exemplo, podemos entender aproximadamente a diferença entre this em funções comuns e this em funções anônimas, para que possamos usar essas duas funções de maneira correta e razoável de acordo com nossas necessidades em nosso trabalho.