Qual é a diferença entre uma função de seta e uma função normal?
1. Diferentes formas de escrever
Em js, funções nomeadas e expressões de função são chamadas de funções comuns. Para funções comuns, elas precisam ser declaradas com a palavra-chave function. A função de seta não precisa usar a palavra-chave function, escrever os parâmetros entre colchetes na frente da seta e escrever o corpo do método entre chaves depois dela. A sintaxe da função de seta é mais concisa e clara.
// 命名式函数
function normalFn(参数) {
// 方法体
return 'normalFn';
}
// 函数表达式
const normalFn = function(参数) {
// 方法体
return 'normalFn';
}
// 箭头函数
const arrowFn = (参数) => {
// 方法体
return 'arrowFn';
}
2. Isso aponta para diferentes
Função normal
Em funções comuns, o objetivo disso é dinâmico e seu valor depende de como a função é chamada. Normalmente, existem quatro métodos de chamada: 1) Ao chamar diretamente,
aponta para o objeto global (indefinido no modo estrito)
function fnc() {
console.log(this); //window{}
}
fnc(); // 全局对象(global 或 window)
2) Quando o método é chamado, aponta para o objeto que está chamando o método
let obj = {
fnc1(){
console.log('fnc1', this === obj); // fnc1 true
}
}
obj.fnc2 = function() {
console.log('fnc2', this === obj); // fnc2 true
}
function fnc3() {
console.log('fnc3', this === obj); // fnc3 true
}
obj.fnc3 = fnc3;
obj.fnc1(); // true
obj.fnc2(); // true
obj.fnc3(); // true
3) Quando new é chamado, ele aponta para o objeto de instância recém-criado
function fnc() {
console.log(this); //fnc {}
}
let obj = new fnc(); // fnc 的实例 fnc {} 这里就是obj
4) Quando call, apply e bind são chamados, eles apontam para o primeiro parâmetro dos três métodos
function fnc() {
console.log(this);
}
let obj = {
name: '张三',age: 18}
fnc.call(obj) // obj对象
fnc.apply(obj) // obj对象
fnc.bind(obj)() // obj对象
A função bind() serve para criar uma nova função, que não será executada imediatamente e precisa ser chamada manualmente
função de seta
O this point da função arrow é estático, não importa onde seja executado ou onde seja executado, isso dentro da função arrow sempre aponta para o objeto apontado pelo escopo quando ele foi criado. Como a função de seta não tem seu próprio ponteiro this, métodos como call(), apply() e bind() não podem alterar o que this aponta na função de seta.
const obj = {
fnc(arr) {
console.log(this === obj); // true(obj)
const cb = () => {
console.log(this === obj); // true(obj)
};
arr.forEach(cb);
}
};
obj.fnc([1, 2, 3]);
3. As funções de seta não podem ser usadas como construtoras
Porque a função de seta não tem seu próprio this, isso realmente herda o this no ambiente de execução externo, e esse ponto nunca mudará, e a função de seta não tem protótipo de protótipo, então é impossível deixar o atributo __proto__ de seu instância apontar para , portanto, a função de seta não pode ser usada como um construtor e um erro será relatado quando for chamado com new.
var Foo = () => {
};
var foo = new Foo();
A implementação interna de new é, na verdade, dividida nas quatro etapas a seguir:
1) criar um novo objeto vazio
2) vincular ao protótipo
3) ligar isso, executar o construtor
4) retornar um novo objeto
function myNew() {
// 1.新建一个空对象
let obj = {
}
// 2.获得构造函数
let con = arguments.__proto__.constructor
// 3.链接原型
obj.__proto__ = con.prototype
// 4.绑定this,执行构造函数
let res = con.apply(obj, arguments)
// 5.返回新对象
return typeof res === 'object' ? res : obj
}
4. As funções de seta não têm atributo de protótipo.
5. Parâmetros
A principal diferença entre funções comuns e funções de seta em termos de parâmetros é que as funções de seta não vinculam o objeto de argumentos.
Quando precisamos usar parâmetros, podemos considerar os parâmetros rest (rest) no ES6.
const fn = (...args) => args[0];
fn(1,2,3,4)