×

学习如何定义函数:普通函数和箭头函数的基础应用以及区别

作者:andy0012021.11.16来源:Web前端之家浏览:3120评论:0
关键词:函数箭头函数

学习如何定义函数:普通函数和箭头函数。自从ES6语法出来后,我们定义函数代码会简单了好多。接下来一起看下如何定义函数。

基础分析

介绍下普通函数和箭头函数的基本构架。

普通函数:

function test() {},函数分为四个部分:

第一部分,保留字function;

第二部分,函数名,可以省略(function(){}..这是一个匿名函数anonymous);

第三部分,一对圆括号,中间为参数,可为空,附带两个隐藏参数,this和arguments;

第四部分,执行的代码块;

这部分只有一对括号,作用却很大。比如调用一个函数:var ss = aa; 和 var ss = aa(); 是不一样的。前面的是把函数的指针赋给了ss,ss也就是这个函数,后面的是把aa函数执行的结果赋给了ss  , ss是它的返回值。

第五部分,最后还可以加一对圆括号,为调用函数。

ES6箭头函数

例 () => {},函数仅保留两个部分:

第一部分,一对圆括号,传参;

第二部分,执行的代码块。

第三部分,最后还可以加一对圆括号,为调用函数。

我们用具体的实例去解析普通函数的定义和箭头函数的应用,以及他们之间的一些区别。往下看吧。

实例解析

我们定义一个函数,可以使用function关键字,函数接收两个参数ab,返回ab的和。

function getSum(a, b) {
    return a + b;
}

若使用箭头函数来定义这个函数,可以写成如下形式,省略function关键字,用箭头=>定义一个函数。

const getSum = (a, b) => {
    return a + b;
};

省略大括号和 return

若定义的箭头函数,函数体内只有return语句,则可以省略大括号{}return

如下所示,定义的箭头函数,完整写法。

const getSum = (a, b) => {
    return a + b;
};

此箭头函数的函数体内只有return语句,那么,省略了大括号{}return后的精简写法如下:

const getSum = (a, b) => a + b;

省略小括号

若定义的箭头函数,参数只有一个,则可以省略小括号。

如下所示,定义的箭头函数,只有一个参数,完整写法。

const func = (a) => {
    return a + 2;
};

省略了参数旁边的小括号,以下代码等价于上面的代码。

const func = a => a + 2;

注意:若函数没有参数,或者多个参数的情况下,必须要使用括号。

箭头函数与普通函数的区别

大多数情况下,能使用普通函数的地方都可以用箭头函数代替,因为箭头函数更精简。

但在部分情况下,箭头函数与普通函数有着很大的却别。

箭头函数的 this 是父级作用域的 this

如下代码,定义了一个对象obj,对象中有个普通函数定义的方法getThis,打印出此处的this。调用obj.getThis(),会打印出obj对象。这说明方法内部的this指向对象obj

const obj = {
    name: 'Jack',
    getThis() {
        console.log(this);
    },
};
obj.getThis(); // {name: 'Jack', getThis: ƒ}

同样定义一个对象obj,但里面的方法用箭头函数定义,浏览器中调用obj.getThis()却打印出Window,这说明即使调用obj对象身上的方法,方法内部的this也不会指向obj,而是指向定义obj的上下文的this

const obj = {
    name: 'Jack',
    getThis: () => {
        console.log(this);
    },
};
obj.getThis(); // Window

call、apply、bind无法改变箭头函数的 this

如下代码,普通函数getName打印this.name,通过call将函数中的this绑定到obj身上,调用getName打印出obj身上的属性name

const obj = {
    name: 'Jack',
};
 
function getName() {
    console.log(this.name);
}
getName.call(obj); // Jack

若将函数改成箭头函数,那么call将不起作用,无法将函数内部的this绑定到obj,打印出undefined

const obj = {
    name: 'Jack',
};
 
const getName = () => {
    console.log(this.name);
};
getName.call(obj); // undefined

不可以作为构造函数

箭头函数不可以作为构造函数使用,若将箭头函数作为构造函数,将报错,如下代码所示。

const Person = () => {
    this.name = 'Jack';
};
const usr = new Person(); // Person is not a constructor

不可以使用 arguments

在普通函数内部,可以使用arguments来获取传入的参数,是一个类数组对象:

function func() {
    console.log(arguments);
}
func(1, 2, 3); // [Arguments] { '0': 1, '1': 2, '2': 3 }

而箭头函数就不可以使用arguments对象,获取不到输入的参数。

在浏览器中,若在箭头函数使用arguments对象,将报错。

const func = () => {
    // 浏览器环境
    console.log(arguments); // arguments is not defined
};
func(1, 2, 3);

但是箭头函数可以在参数内,以...args的方式,获取到输入的参数,得到的args是一个数组。

const func = (...args) => {
    console.log(args); // [ 1, 2, 3 ]
};
func(1, 2, 3);

箭头函数不支持 new.target

普通函数定义的构造函数内部,支持使用new.target,返回构造实例的构造函数。

function Person() {
    this.name = 'Jack';
    console.log(new.target);
}
// 指向构造函数
new Person(); // [Function: Person]

而在箭头函数中,不支持使用new.target。在浏览器环境中,箭头函数使用new.target将报错:new.target expression is not allowed here

const Person=() =>{
    this.name = 'Jack';
    console.log(new.target);
}
// 浏览器环境
new Person(); // new.target expression is not allowed here

总结

总而言之,使用了箭头函数后,我们的代码发现可以大大减少,也方便了许多。不过我们平时在项目开发的时候也需要去考虑到兼容性,毕竟不是所有的项目都支持。

您的支持是我们创作的动力!
温馨提示:本文作者系 ,经Web前端之家编辑修改或补充,转载请注明出处和本文链接:
https://www.jiangweishan.com/article/hanshu20211116a3.html

网友评论文明上网理性发言 已有0人参与

发表评论: