【函数进阶】

函数进阶

  • 1 本节目标
  • 2 函数的定义和调用
    • 2.1 函数的定义方式
    • 2.2 函数的调用方式
  • 3 this
    • 3.1 函数内 this 的指向
    • 3.2 改变函数内部 this 的指向
      • 3.2.1 call方法
      • 3.2.2 apply方法
      • 3.2.3 bind方法
      • 3.2.4 call apply bind 总结
  • 4 严格模式
    • 4.1 什么是严格模式
    • 4.2 开启严格模式
      • 4.2.1 为脚本开启严格模式
      • 4.2.2 为函数开启严格模式
    • 4.3 严格模式中的变化
      • 4.3.1 变量规定
      • 4.3.2 严格模式下this指向问题
      • 4.3.3 函数变化
  • 5 高阶函数
  • 6 闭包
    • 6.1 变量作用域
    • 6.2 什么是闭包
    • 6.3 闭包案例
      • 6.3.1 ==循环注册点击事件(点击li打印当前索引号)==
      • 6.3.2 循环中的setTimeout(3秒钟之后打印li内容)
      • 6.3.3 计算打车价格
      • 6.3.4 思考题
      • 6.3.5 闭包总结
  • 7 递归
    • 7.1 什么是递归?
    • 7.2 利用递归求数学题
      • 7.2.1 求1 * 2 * 3...* n 阶乘
      • 7.2.2 求斐波那契数列
      • 7.2.3 利用递归求:根据id返回对应的数据对象
    • 7.3 浅拷贝和深拷贝

1 本节目标

  • 说出函数的多种定义和调用方式
  • 说出和改变函数内部this的指向
  • 说出严格模式的特点
  • 能把函数作为参数和返回值传递
  • 说出闭包的作用
  • 说出递归的两个条件
  • 说出深拷贝和浅拷贝的区别

2 函数的定义和调用

2.1 函数的定义方式

  • 函数声明方式function关键字(命名函数)
  • 函数表达式(匿名函数)
  • new Function()
    var fn = new Function('参数1', '参数2'....., '函数体')
    Function里面的参数都必须是字符串格式
  • 第三种方式执行效率低,也不方便书写,因此较少使用。
  • 所有函数都是Function的实例(对象)。
  • 函数也属于对象。
    【函数进阶】_第1张图片
    【函数进阶】_第2张图片

2.2 函数的调用方式

  • 普通函数
  • 对象的方法
  • 构造函数
  • 绑定事件函数
  • 定时器函数
  • 立即执行函数
    【函数进阶】_第3张图片

3 this

3.1 函数内 this 的指向

  • 这些this的指向,是当我们调用函数的时候确定的。调用方式的不同决定了this的指向不同。一般指向我们的调用者。
    【函数进阶】_第4张图片
    【函数进阶】_第5张图片

3.2 改变函数内部 this 的指向

  • JavaScript提供了一些函数方法来帮我们更优雅的处理函数内部this的指向问题,常用的有bind()、call()、apply()三种方法。

3.2.1 call方法

  • call()方法调用一个对象。简单理解为调用函数的方式,但它可以改变函数的this指向。
  • fun.call(thisArg, arg1, arg2,...)
    【函数进阶】_第6张图片

3.2.2 apply方法

  • apply()方法调用一个函数。简单理解为调用函数的方式,但是它可以改变函数的this指向。
  • fun.apply(thisArg, [argsArray])
    thisArg:在fun函数运行时指定的this值
    argsArray:传递的值,必须包含在数组里面
  • 返回值就是函数的返回值,因为它就是调用函数。
    【函数进阶】_第7张图片

3.2.3 bind方法

  • bind()方法不会调用函数。但是能改变函数内部this指向。
  • fun.bind(thisArg, arg1, arg2,...)
    thisArg:在fun函数运行时指定的this值
    arg1,arg2:传递的其他参数
  • 返回由指定的this值和初始化参数改造的原函数拷贝
    【函数进阶】_第8张图片

3.2.4 call apply bind 总结

  • 相同点:都可以改变函数内部的this指向
  • 不同点:
    1.call和apply会调用函数,并且改变函数内部this指向
    2.call和apply传递的参数不一样,call传递参数aru1,aru2…形式,apply必须是数组形式[arg]
    3.bind不会调用函数,可以改变函数内部this指向
  • 主要应用场景:
    1.call经常做继承
    2.apply经常跟数组有关系。比如借助于数学对象实现数组最大值最小值
    3.bind不调用函数,但还想改变this指向。比如改变定时器内部的this指向

4 严格模式

4.1 什么是严格模式

  • JavaScript除了提供正常模式外,还提供了严格模式(strict mode)。ES5的严格模式是采用具有限制性JavaScript变体的一种方式,即在严格的条件下运行JS代码。
  • 严格模式对正常的JavaScript语义做了一些更改:
    1.消除了JavaScript语法的一些不合理、不严谨之处,减少了一些怪异行为。
    2.消除代码运行的一些不安全之处,保证代码运行的安全。
    3.提高编译器效率,增加运行速度。
    4.禁用了在ECMAScript的未来版本中可能会定义的一些语法,为未来新版本的JavaScript做好铺垫。比如一些保留字如:class、enum、export、extends、import、super不能做变量名。

4.2 开启严格模式

  • 严格模式可以应用到整个脚本或个别函数中。因此在使用时,我们可以将严格模式分为脚本开启严格模式和为函数开启严格模式两种情况。

4.2.1 为脚本开启严格模式

  • 为整个脚本文件开启严格模式,需要在所有语句之前放一个特定语句"use strict";'use strict';
    【函数进阶】_第9张图片

4.2.2 为函数开启严格模式

  • 要给某个函数开启严格模式,需要把"use strict";'use strict';声明放在函数体所有语句之前。
    【函数进阶】_第10张图片

4.3 严格模式中的变化

  • 严格模式对JavaScript的语法和行为都做了一些改变。

4.3.1 变量规定

  • 在正常模式中,如果一个变量没有声明就赋值,默认是全局变量;严格模式禁止这种用法,变量都必须先用var命令声明,然后再使用。
  • 严禁删除已经声明变量。例如delete x;语法是错误的。

4.3.2 严格模式下this指向问题

  • 以前在全局作用域函数中的this指向window对象;
  • 严格模式下全局作用域中函数中的this是undefined
  • 以前构造函数时不加new也可以调用,当普通函数,this指向全局对象;
  • 严格模式下,如果构造函数不加new调用,this会报错;
  • new实例化的构造函数指向创建的对象实例。
  • 定时器里面的this还是指向window。
  • 事件、对象还是指向调用者。

4.3.3 函数变化

  • 严格模式下,函数不能有重名的参数。
  • 函数必须声明在顶层。新版本的JavaScript会引入“块级作用域”(ES6中已引入)。为了与新版本接轨,不允许在非函数的代码块内声明函数。
    【函数进阶】_第11张图片
    【函数进阶】_第12张图片

5 高阶函数

  • 高阶函数是对其他函数进行操作的函数,它接收函数作为参数将函数作为返回值输出。(函数也是一种数据类型,同样可以作为参数,传递给另外一个参数使用。最典型的就是作为回调函数)
    【函数进阶】_第13张图片

6 闭包

6.1 变量作用域

  • 变量根据作用域的不同分为两种:全局变量和局部变量。
    1.函数内部可以使用全局变量。
    2.函数外部不可以使用局部变量。
    3.当函数执行完毕,本作用域的局部变量会销毁。

6.2 什么是闭包

  • 闭包(closure)指有权访问另一个函数作用域中变量的函数。
  • 简单理解就是,一个作用域可以访问另外一个函数内部的局部变量。

  • 闭包就是典型的高阶函数。
    【函数进阶】_第14张图片
  • 闭包的主要作用:延伸了变量的作用范围

6.3 闭包案例

6.3.1 循环注册点击事件(点击li打印当前索引号)

【函数进阶】_第15张图片

6.3.2 循环中的setTimeout(3秒钟之后打印li内容)

【函数进阶】_第16张图片

6.3.3 计算打车价格

【函数进阶】_第17张图片

6.3.4 思考题

6.3.5 闭包总结

  • 什么是闭包:闭包是一个函数(一个作用域可以访问另外一个函数的局部变量)
  • 闭包的作用:延伸变量的作用范围

7 递归

7.1 什么是递归?

  • 如果一个函数在内部可以调用其本身,那么这个函数就是递归函数。
  • 简单理解:函数内部自己调用自己。这个函数就是递归函数。
  • 递归函数的作用和循环效果一样。
  • 由于递归很容易发生“栈溢出”错误(stack overflow),所以必须要加退出条件return。
    【函数进阶】_第18张图片

7.2 利用递归求数学题

7.2.1 求1 * 2 * 3…* n 阶乘

【函数进阶】_第19张图片

7.2.2 求斐波那契数列

【函数进阶】_第20张图片

7.2.3 利用递归求:根据id返回对应的数据对象

【函数进阶】_第21张图片

7.3 浅拷贝和深拷贝

  • 浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用。
  • 深拷贝拷贝多层,每一级别的数据都会拷贝。
  • Object.assign(target,...sources)ES6新增方法可以浅拷贝。
    【函数进阶】_第22张图片
    【函数进阶】_第23张图片

你可能感兴趣的:(ES6,es6)