函数的返回值
函数体内可以使用return关键字表示“函数的返回值”
调用一个有返回值的函数,可以被当做一个普通值,从而可以出现在任何可以书写值的地方
调用函数时,一旦遇见return语句则会立即退出函数,将执行权交还给调用者
结合if语句的时候,往往不需要写else分支
函数的参数
参数是函数内的一些待定值,在调用函数时,必须传入这些参数的具体值
函数的参数可多可少,函数可以没有参数,也可以有多个参数,多个参数之间需要用逗号隔开
函数内arguments表示它接收到的实参列表,它是一个类数组对象
类数组对象:所有属性均为从0开始的自然数序列,并且有length属性,和数组类似可以用方括号书写下标访问对象的某个属性值,但是不能调用数组的方法
函数的调用
执行函数体中的所有句,就称为“调用函数” 调用函数非常简单,只需要在函数名字后书写圆括号对即可
函数声明的提升
和变量声明提升类似,函数声明也可以被提升
如果函数是用函数表达式的写法定义的,则没有提升性
函数的定义
和变量类似函数必须先定义然后才能使用
使用function关键字定义函数function是功能的意思
函数的调用
执行函数体中的所有语句就称为“调用函数”调用函数非常简单只需要在函数名字后书写圆括号对即可
递归
函数的内部语句可以调用这个函数自身,从而发起对函数的一次迭代。在新的迭代中,又会执行调用函数自身的语句,从而又产生一次迭代。当函数执行到某一次时,不再进行新的迭代,函数被一层一层返回,函数被递归
递归是一种较为高级的编程技巧,它把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解
递归的要素
边界条件:确定递归到何时终止,也称为递归出口
递归模式:大问题是如何分解为小问题的,也称为递归体
实现深克隆
复习引用类型值的相关知识
JavaScript中的数据类型有两类:基本类型和引用类型值
复习浅克隆
使用var arr1=arr2这样的语句不能实现数组的克隆
浅克隆:准备一个空的结果数组,然后使用for循环遍历原数组,将遍历到的项都推入结果数组
浅克隆只克隆数组的一层,如果数组是多维数组,则克隆的项会“藕断丝连”
实现深克隆
使用递归思想,整体思路和浅克隆相似,但稍微进行一些改动:如果遍历到项是基本类型值,则直接推入结果数组;如果遍历到的项是又是数组,则重复执行浅克隆的操作。
全局变量与局部变量
JavaScript是函数级作用域编程语言:变量只在其定义时所在的function内部有意义
如果不将变量定义在任何函数的内部,此时这个变量就是全局变量,它在任何函数内都可以被访问和更改
遮蔽效应
如果函数中也定义了和全局同名的变量,则函数内的变量会将全局的变量“遮蔽”
形参也是局部变量
作用域链
先来认识函数的嵌套:一个函数内部也可以定义一个函数。 和局部变量类似,定义在一个函数内部的函数是局部函数。
在函数嵌套中,变量会从内到外逐层寻找它的定义。
不加var将定义全局变量
在初次给变量赋值时,如果没有加var,则将定义全局变量
闭包
什么是闭包
JavaScript中函数会产生闭包(closure)。闭包是函数本身和该函数声明时所处的环境状态的组合。
函数能够“记忆住”其定义时所处的环境,即使函数不在其定义的环境中被调用,也能访问定义时所处环境的变量
观察闭包现象
在JavaScript中,每次创建函数时都会创建闭包。
但是,闭包特性往往需要将函数“换一个地方”执行,才能被观察出来。
闭包非常实用
闭包很有用,因为它允许我们将数据与操作该数据的函数关联起来。这与“面向对象编程”有少许相似之处。
闭包的功能:记忆性、模拟私有变量。
闭包用途1-记忆性
当闭包产生时,函数所处环境的状态会始终保持在内存中,不会在外层函数调用后被自动清除。这就是闭包的记忆性。