读书笔记:深入理解ES6 (三)

第三章 函数

这一章主要介绍了在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 什么是尾调用?

    当一个函数作为另一个函数的最后一条语句被调用时,就叫做尾调用。例如:

1 function doSomething()
2 {
3     return doSomethingElse(); //尾调用 
4 }

  9.2 使用场景:

    当写递归函数的时候,可以使用这一特性。除非你尝试优化一个函数,否则无须思考此类问题。

(本节完)

  

    

猜你喜欢

转载自www.cnblogs.com/zxxsteven/p/11437941.html