ES6特性总结(3)——函数的变化

Wesley13
• 阅读 464

前言

es6中的一系列关于函数用法的变化是非常有趣的,在es6的新标准下,你可以更加轻便地使用函数,并且可以仿照面向对象编程的思想来使用函数,将函数转化为“类”。(这里的类加了引号,原因我们会在后面的学习中解释)下面就让我们来一起看一看es6下的函数有哪些有趣的变化。

1.箭头函数

箭头函数是es6下实现的一种新的函数书写方法。在过去的编程中,我们如果实现一个将数组内的字符串全部变成大写,需要这样的匿名函数进行实现:

const Marvel = ['spider man', 'iron man', 'thor', 'hulk', 'captain'];

const UpperMarvel = Marvel.map(function (name) {
    return name.toUpperCase();
});

console.log(UpperMarvel); // Uppercase of all the elements in Marvel[]

现在,我们可以通过箭头函数来实现这一过程了:

const Marvel = ['spider man', 'iron man', 'thor', 'hulk', 'captain'];

const UpperMarvel = Marvel.map(
    name => name.toUpperCase()
);
console.log(UpperMarvel);

可以看到,我们去掉了function关键字,去掉了参数的圆括号,函数体的花括号,以及return语句。直接采用: 参数 => 参数的操作,这一形式来代替之前冗长的匿名函数。 需要注意的是,我们并不是彻底抛弃了圆括号和花括号,在以下情况时,我们需要召回我们的括号兄弟:

  • 当我们有不止一个参数时——需要圆括号
  • 当我们的函数体不能用一个表达式完成,而需要多个语句时——需要花括号,而且我们需要召回return语句!

请看下面这个例子:

const Marvel = ['spider man', 'iron man', 'thor', 'hulk', 'captain'];

const UpperMarvel = Marvel.map(
    name => {
        name = name.toUpperCase();
        return `${name} has ${name.length} characters in their name`;
    });
console.log(UpperMarvel);

这里我们需要对name先进行大写处理,再通过模板字面量输出,多个语句,此时就必须有花括号出现。并且,由于我们当前花括号内的操作不再是一个单一表达式了,函数体必须由我们制定返回值,因此,return语句也是必不可少的!

2.箭头函数的this指针

提到this指针,还真是个非常头大的事情,对于初学者来说,javascript的第一个难点可能就在这里,很多人都不理解这个this指针到底是什么东西。我个人比较习惯把this理解为“所在地”,或者“你现在所处于”的意思,也就是说,它就是一个表示上下文环境的标志!我们来回顾一下在一般的javascript函数中,this都有哪些用法。

(1)当我们对某一对象调用方法的时候,例如Data.getName()

此时getName()函数中的this就指向对象Data。限定了当前大环境是Data对象,那么getName()得到的没准就是Data.name的值。

(2)Data1.getName().call(Data2),此时我们的call()方法传入了对象Data2,了解call()方法,你应该就明白这里我们虽然调用了 Data1的getName()方法,但是已经把this指向了Data2!

(3)this指向全局对象

以上是this指针在以往普通函数中的使用。那么在新的箭头函数中,this指针的规则有什么新的调整吗? 不难发现,在过去的函数中,this指针的指向取决于“怎么被调用,谁调用”,就像我们前面提到的Data.getName()一样,this指向Data。但在箭头函数中,this的指向更加直接,就是当前箭头函数的所在上下文环境! 我们通过一个例子就可以看出this指针在箭头函数中的用法:

function Latte() {
    this.sugar = 0;
    this.milk = 0;
}

Latte.prototype.addSugar = function () {
    setTimeout(function () {
        this.sugar++;
        console.log('sugar added!');
    }, 500);
};

const latte1 = new Latte();
latte1.addSugar();

setTimeout(function () {
    console.log(latte1.sugar); // 0
}, 1000);

你可能会以为这里setTimeout函数中的this.sugar++已经给sugar属性增加了啊!为什么还是0呢,这个+1去哪里了?让我们想想前面提到的普通匿名函数中的this指针的情况。注意这里this指针出现在setTimeout的第一个参数匿名函数中,这意味着什么?这个里层的匿名函数的this指针,可和addSugar方法中的this指针不是一个东西哦!这个this指针本身是没有制定上下文的,它会直接被指向全局对象,那么这个+1就加给了全局对象中的sugar(实际上相当于undefined + 1 =NaN)。这里我们解决方法就是使用闭包,把addSugar的this指针**“塞进”**setTimeout的匿名函数中,比如通过建立一个新变量赋值为this,再在里层的匿名函数中使用这个变量代替this指针即可!

但是如果使用箭头函数,情况就不是上述这样了。牢记我们的箭头函数中的this指针永远指向当前所处函数的上下文!也就是你即便有一百个箭头函数嵌套在一起,最里面的this指针一样指向最外层的函数的上下文!我们看看同样的例子,换作匿名函数:

Latte.prototype.addSugar = function () {
    setTimeout( () => {
        this.sugar++;
        console.log('sugar added!');
    }, 500);
};

这里我们的sugar终于会+1了,原因就是我们的this指针会自动指向当前setTimeout所在的上下文,也就是addSugar的function的this内容,这样就可以找到我们的latte1对象中的sugar属性了!

3.默认参数函数

在es6中我们可以给函数进行默认函数参数的设定,尤其是和之前我们讲到的数组对象的解构结合起来的时候,你就会发现我们可以用很简单的代码实现一个参数灵活的函数!一个显示咖啡里面配料比重的函数:

function Latte(coffee = 30, sugar = 10, milk = 60){
    return `this cup of latte contains ${coffee}% of coffee,${sugar}% of sugar and ${milk}% of milk`;
}

对应的输出如下:

console.log(Latte()); // this cup of latte contains 30% of coffee,10% of sugar and 60% of milk
console.log(Latte(15)); // this cup of latte contains 15% of coffee,10% of sugar and 60% of milk
console.log(Latte(15,25,45)); // this cup of latte contains 15% of coffee,10% of sugar and 60% of milk

这就是默然参数函数的用处,你不再需要像以往一样,分别讨论参数的缺省情况。现在你可以考虑一下,如果我们的参数包括数组和对象,那么通过之前学到的解构,是不是可以发挥更强大的作用?这个留给你自己去尝试一下! 以上就是es6中的一些函数方面的总结。

点赞
收藏
评论区
推荐文章
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
ES6新增内容(部分)
ES6新增内容(部分)一、两个声明变量的方法let、constlet:不能重复声明、有暂时性死区,不能提前访问、{}块级作用域。const:声明常量、声明之后不能被修改。二、箭头函数语法:(参数){表达式}箭头函数中this没有固定指向,一般指向宿主对象。
Stella981 Stella981
2年前
JS 对象数组Array 根据对象object key的值排序sort,很风骚哦
有个js对象数组varary\{id:1,name:"b"},{id:2,name:"b"}\需求是根据name或者id的值来排序,这里有个风骚的函数函数定义:function keysrt(key,desc) {  return function(a,b){    return desc ? ~~(ak
Stella981 Stella981
2年前
HIVE 时间操作函数
日期函数UNIX时间戳转日期函数: from\_unixtime语法:   from\_unixtime(bigint unixtime\, string format\)返回值: string说明: 转化UNIX时间戳(从19700101 00:00:00 UTC到指定时间的秒数)到当前时区的时间格式举例:hive   selec
Wesley13 Wesley13
2年前
ES6箭头函数与普通函数的区别
箭头函数:letfun(){console.log('lala');}普通函数functionfun(){console.log('lalla');}箭头函数相当于匿名函数,并且简化了函数定义。箭头函数有两种格式,一
Wesley13 Wesley13
2年前
ES6 箭头函数
一、在es6中函数的定义和es5之间有明显区别。不需要关键字function来进行定义,使用来指向函数。不可以new也就是做构造函数以及没有arguments参数。箭头函数的this是在定义的时候确定指向这和es5不一样,es5是谁调用他,他就指向谁。1document.addEventListene
Stella981 Stella981
2年前
ES6对象的super关键字
super是es6新出的关键字,它既可以当作函数使用,也可以当作对象使用,两种使用方法不尽相同1.super用作函数使用的时候,代表父类的构造函数,es6规定在子类中使用this之前必须先执行一次super函数,super相当于Father.prototype.constructor.call(this)classFather{
Stella981 Stella981
2年前
ES6中箭头函数与普通函数this的区别(转)
看到一篇别人的博客,对this的理解又加深了一些。普通函数中的this:1\.this总是代表它的直接调用者,例如obj.func,那么func中的this就是obj2.在默认情况(非严格模式下,未使用'usestrict'),没找到直接调用者,则this指的是window3.在严格模式下,没有直接调用者的函数中的thi
Wesley13 Wesley13
2年前
ES6新增的一些特性
1、let关键字,用来代替var的关键字,特点: 1、变量不允许被重复定义2、不会进行变量声明提升3、保留块级作用域中i的2、const定义常量,特点:1、常量值不允许被改变2、不会进行变量声明提升3、箭头函数  与普通函数的区别:1、书写上用代替了function         2、普通函数的this指向window而ES6
Wesley13 Wesley13
2年前
ES6中的箭头函数=>
ES6标准新增了一种新的函数:ArrowFunction(箭头函数)。为什么叫ArrowFunction?因为它的定义用的就是一个箭头:xxx相当于:function(x){returnxx;}箭头函数