第三章 函数
这一章主要介绍了在ES6规范中,对于函数这一块知识进行的一些修订和改进,主要目的就是让使用JavaScript编程可以更少出错,同时也更加灵活。
第1节. 函数形参的默认值
1.1 在ES5中,在函数体内要对形参的值进行进一步的判断,如果不满足条件,则给其一个默认值。例如:
function makeRequest(url, timeout, callback)
{
timeout = timeout || 2000;
//other code
}
而在ES6中,为了更加简化函数体的代码,给形参赋默认值的操作可以直接在写参数的时候加上,以此减少函数体内的代码量。例如:
function makeRequest(url, timeout = 2000, callback)
{
//other code
}
1.2 默认参数值对 arguments 对象的影响。
在ES5非严格模式下,函数命名参数的变化会体现在 arguments 对象中。即,参数值改变后,arguments 对象中原来存储的值会同时发生改变;而在ES5严格模式和ES6中,参数值改变后,arguments 对象中的值不会改变,仍旧是原来的值。
第2节 处理无命名参数
2.1 无命名参数,即没有显式声明的参数。在ES5中,可以使用 arguments 对象来表示和进行相应操作。
2.2 在ES6中,可以使用三个点 (...) 加上一个参数名来表示不定参数。例如:
function pick( object, ...keys )
{
// other code
}
注意:不定参数在使用的时候有两个限制:
1)每个函数只能声明一个,且只能放在参数的末尾;
2)不定参数不能用于对象字面量 setter 之中。
第3节 增强的Function构造函数
在ES5中,可以像下面这样使用构造函数:
var add = new Function( "first", "second", "return first + second" );
console.log( add(1, 1) ); // 2
在ES6中,Function构造函数可以使用默认参数和不定参数。例如:
var add = new Function("first", "second=first", "return first + second");
console.log( add(1, 1) ); //2
console.log( add(1) ); //2
var pickFirst = new Function( "...args", "return args[0]" );
console.log( pickFirst(1, 2) ); // 1
第4节 展开运算符
4.1 什么是展开运算符?
使用三个点 (...) 加上一个数组的名字,例如下面的 "...values" :
let values = [25, 50, 75, 100];
...values // 这个就是展开运算符
4.2 展开运算符的好处是什么?
好处就是可以让数组的元素可以作为单个的字符来使用。例如:
Math.max()方法中,只能传入字符串作为参数,但是如果想传入一个数组,然后找到这个数组的最大值,这个时候怎么办呢?这个时候可以使用展开运算符。如下:
let values = [25, 50, 75, 100];
Math.max( ...values );
第5节 name属性
5.1 JavaScript中,有多种定义函数的方式。例如:正常定义的函数、函数表达式、匿名函数等。为了便于调试函数,于是在ES6中,添加了函数的 name 属性。该属性的值可以返回当前的函数名。
5.2 当然也有一些特殊的情况,会在函数名的前面加上一些字符串前缀。例如:
getter函数,函数名前面会有get
setter函数,函数名前面会有set
bind()函数,函数名前面会有bound
5.3 注意,函数name属性不一定和原函数名完全相同,所以它只是一个调试的辅助信息,而不能用它来获取对函数的引用。
第6节 明确函数的多种用途
6.1 JavaScript函数有两个不同的内部方法:[[ Call ]] 、 [[ Construct ]]。
当通过 new 关键字调用函数的时候,执行的是 [[ Construct ]] 函数。如果不是通过 new 关键字来调用函数,那么执行的就是 [[ Call ]] 函数。
6.2 不是所有函数都有 [[ Construct ]]方法。
例如ES6中的箭头函数就没有这个[[ Condtruct ]]方法。
6.3 在ES6中,可以通过 new.target 这个属性来判断是否是通过 new 关键字调用的函数。
第7节 块级函数
7.1 先抛出4个概念:
ES5 非严格模式、ES5严格模式; ES6 非严格模式、ES6 严格模式。
7.2 块级函数是什么?
块级函数即在代码块中声明的一个函数。例如:
"use strict"
if (true)
{
//在ES5中抛出语法错误,在ES6中不报错
function doSomething()
{
// 空函数
}
}
7.3 在ES5严格模式中,此种声明会报错。
在ES6中,此种声明式合法的,不会报错。但是有一个小小的区别:
~在ES6 严格模式中,块级函数会被提升至代码块顶部,用完即销毁;
~在ES6 非严格模式中,块级函数会被提升至外围函数或者全局作用域的顶部。
第8节 箭头函数
8.1 定义:
箭头函数是使用箭头 ( => ) 定义的函数。
8.2 与传统函数的区别:
- 没有this / super / arguments / new.target 绑定
- 不能通过 new 关键字调用
- 没有原型(Prototype)
- 不可以改变 this 的绑定
- 不支持 arguments 对象
- 不支持重复的命名参数
8.3 箭头函数与this。
如果箭头函数被非箭头函数包裹,则 this 绑定的是最近一层非箭头函数的 this 。否则 this 的值会被设置为全局对象。
8.4 使用场景。
所有使用匿名函数的地方都适合使用箭头函数来改写。同时,箭头函数也适合数组处理。
第9节 尾调用优化
9.1 什么是尾调用?
当一个函数作为另一个函数的最后一条语句被调用时,就叫做尾调用。例如:
function doSomething()
{
return doSomethingElse(); //尾调用
}
9.2 使用场景:
当写递归函数的时候,可以使用这一特性。除非你尝试优化一个函数,否则无须思考此类问题。
(本节完)