一:函数声明
函数声明,重要特征就是函数声明提升。

  1. sayHi()
  2. function sayHi(){
  3. console.log("hi");
  4. }

二:函数表达式
函数表达式的几种不同语法形式

  • 匿名函数:创建一个函数并将它赋值给变量。function关键字后面没有标识符。 ```javascript var functionName = function(arg0,arg1,atg2){ //函数体 }

sayHi() //错误 函数还不存在 var sayHi = function(){ console.log(“hi”) }

  1. 关键点:理解函数提升,也就是理解函数声明和函数表达式之间的区别
  2. 不要这样写,错误示例。原因:这在ECMAscript中属于无效的语法,js引擎通常会尝试修正错误,将其转换为合理状态,问题是浏览器的做法都不一致。
  3. ```javascript
  4. if(condition){
  5. function sayHi(){
  6. console.log("hi")
  7. }
  8. }else{
  9. function sayHi(){
  10. console.log("yo")
  11. }
  12. }

正确写法
函数表达式的写法不会导致它提升

  1. var sayHi
  2. var condition = 1
  3. if(condition){
  4. sayHi = function(){
  5. console.log("hi")
  6. }
  7. }else{
  8. sayHi = function(){
  9. console.log("yo")
  10. }
  11. }
  12. sayHi() //hi

7.1递归

递归函数是一个函数通过名字调用自身的情况下构成的,

  1. function factorial(num){
  2. if(num<=1){
  3. return 1
  4. }else{
  5. return num*factorial(num-1)
  6. }
  7. }

arguments.callee 是一个指向正在执行的函数的指针,因此可以用它来实现对函数的递归调用

  1. function factorial(num){
  2. if(num<=1){
  3. return 1
  4. }else{
  5. return num*arguments.callee(num-1)
  6. }
  7. }

另一种方式

  1. var factorial = function f(num) {
  2. if (num <= 1) {
  3. return 1;
  4. } else {
  5. return num * f(num - 1);
  6. }
  7. };

7.2闭包

闭包是指有权访问另一个函数作用域中的变量的函数。
创建闭包的常见方式就是在一个函数内部创建另一个函数。

闭包与变量

作用域的这种配置机制引出了一个值得注意的副作用,即闭包只能取得包含函数中任何变量的最后一个值。
闭包保存的是整个变量对象,而不是某个特殊的变量。