javascript函数(声明,传参,返回值,递归)

javascript函数(声明,传参,返回值,递归)

1、函数的基本概念

  • 函数:是由事件驱动的或者当他被调用时可执行的可重复使用的代码块。
  • 空调是由遥控器控制或者当开关打开时,可运行的家用电器(工具)

特点:

  • 封装代码----使代码更简洁
  • 重复使用---在重复功能的时候直接调用就好
  • 执行时机---随时可以在我们想要执行的时候执行

2、函数的创建和执行

1. 函数的创建

1、声明式

  • 函数声明的关键字 : function
  • function 关键字 和 var 关键字的行为几乎一致,都会在内存上开辟一块空间,用来存储变量之中的数据;
 function 函数名( 条件 ){
       代码 
  }
  • 规定 : 必须执行,不执行就报错;
  • 规范 : 最好执行,不执行也不会报错,但是会让程序有一些负面影响。
  • 函数定义的规范: 函数名的首字母小写!
    • 函数的命名规则和变量命名规则完全一致;
    • 函数推荐驼峰命名;
    • 变量推荐_命名;
function foo(){
console.log("hello world");
}
  • 函数定义了,会吧代码 默默的放在哪里不会去执行代码;
  • 只要在程序主动调用的时候,代码才会执行!;
  • 声明式-规定 : 不要漏掉函数的名字!;

2、赋值式

  • 函数也是数据类型的一种;
  • 基本类型 : 五种;
  • 引用类型 : 三种 => function(){}(其中一种)
  • 我们可以认为函数是一种数据;
  • 赋值式函数声明可以没有函数名!;
  • 其实就是和我们使用 var 关键字是一个道理了
  • 首先使用 var 定义一个变量,把一个函数当作值直接赋值给这个变量就可以了
var foo = function(){
  console.log("hello world");
}
  • 函数定义和调用规范 : 先声明再调用!;
 var foo = function poo(){
  console.log("hello world");
  // 只有在这个函数里面才会使用;
   }
  // poo 是无法被调用 , 因为他的作用范围是局部的;

2. 函数的执行

  1. 直接执行
  2. 通过行为执行

函数调用的两种形式:

  1. 你在代码之中调用;
  • 直接写 函数名() 就可以了
function foo(){
         console.log("hello world");
}
foo();

注意:

定义完一个函数以后,如果没有函数调用,那么写在 {} 里面的代码没有意义,只有 调用以后才会执行
2. 浏览器在特定时机帮你调用函数!;

  • 事件行为;
  • html标签进行触发 => 浏览器接受 => 浏览器调用函数;
<button id="btn">你点我一下试试</button>
function foo(){
         console.log("hello world");
 }
btn.onclick = foo

// console.log(btn);
// 在点击的时候会让浏览器调用对应的函数;

// btn 就是元素的id;
// onclick 是事件行为;

3、函数的参数(重点)

  • 我们在定义函数和调用函数的时候都出现过 ()
  • 现在我们就来说一下这个 () 的作用
  • 就是用来放参数的位置
  • 参数分为两种 行参实参
 // 声明式
 function fn(行参) {
 // 一段代码 
 }
 fn(实参) 
 // 赋值式函数 
 var fn = function (行参) {
 // 一段代码
 }
 fn(实参)

接收:形参

  • 就是在函数内部可以使用的变量,在函数外部不能使用
  • 每写一个单词,就相当于在函数内部定义了一个可以使用的变量(遵循变量名的命名规则和 命名规范)
  • 多个单词(形参)之间以 , 分隔
// 书写一个参数 
// 声明式
function fn(num) {
// 在函数内部就可以使用 num 这个变量 
}
// 赋值式
var fn1 = function (num) { 
// 在函数内部就可以使用 num 这个变量 
}

// 书写两个参数
// 声明式
function fun(num1, num2) { 
// 在函数内部就可以使用 num1 和 num2这两个变量 
}
// 赋值式
var fun1 = function (num1, num2) { 
// 在函数内部就可以使用 num1 和 num2 这两个变量 
}
  • 如果只有行参的话,那么在函数内部使用的值个变量是没有值的,也就是 undefined
  • 行参的值是在函数调用的时候由实参决定的

发送:实参

  • 在函数调用的时候给行参赋值的
  • 也就是说,在调用的时候是给一个实际的内容的
function fn(num) { 
// 函数内部可以使用 num 
}

fn(100)
// 这个函数的本次调用,书写的实参是 100 
// 那么本次调用的时候函数内部的 num 就是 100

fn(200)
// 这个函数的本次调用,书写的实参是 200 
// 那么本次调用的时候函数内部的 num 就是 200

  • 函数内部的行参的值,由函数调用的时候传递的实参决定
  • 多个参数的时候,是按照顺序一一对应的
function fn(num1, num2) { 
// 函数内部可以使用 num1 和 num2 
}

fn(100, 200)
// 函数本次调用的时候,书写的参数是 100 和 200 
// 那么本次调用的时候,函数内部的 num1 就是 100,num2 就是 200 

多个参数的关系

  • 原则上来说,形参和实参的数量应该一一对应
    但,如果,二者数量不一致:
    • 形参多,实参少:多出来的形参为undefined
    • 实参多,形参少:多出来的实参找arguments
    • arguments是一个在函数内部才能使用的,用来保存当前函数所有实参的类数组,也叫对象
    • 可以通过索引和长度来解析arguments
  • 形参比实参多 :
// 参数多了怎么办 ? 
// 形参 : 变量 => 函数体之中;
// 实参数量比形参数量少; 其余未赋值的形参值都为 undefined;
function foo( a , b , c , d ){
     console.log( a , b , c , d );
 }
 foo( 1 );
  • 实参比形参多 :
  • 剩下的实参都哪里去了 ?
  • 剩下的参数都使用arguments关键字进行接收, 使用 [] 进行取出;
function foo( a ){
    // console.log(a);
    // 函数之中有一个关键字 : arguments => 接受所有的实际参数;
    // arguments 里面可以存很多很多的数据; 
    // console.log( arguments );
    // 想要取出复杂结构之中的数据 :  取出运算符 =>  . 
    // arguments.0 
    // Uncaught SyntaxError: Unexpected number
    // 语法报错 : 不允许使用数字;

    // JS之中的取出运算符 =>  .纯英文 
    //                   =>  [] 里面可以放任何数据;
    // document.write() ===  document["write"]()
     console.log(arguments[2]);
}
foo( 1 , 2 , 3 , 4 , 5 , 6 , 7 );

4、函数的返回值-return(重点)

  • 将函数执行处理的数据,返回出来,
  • 便于其他程序或用户调用或做二次使用
    • 关键字 : return => 函数体内使用;
 function foo(){
    return "hello world";
 }
 console.log(foo());
 // = > "hello world"
  • return的特性
    • 在函数之中,只要遇到了return关键字,表示函数执行结束,会立即跳出函数执行。
    • 无论有多少个return ,只会执行第一个return,因为后面的就不执行了。
    • 因此函数有一个特点, 返回值只能有一个;
 function foo(){
    return "hello world1";
    return "hello world2";
    return "hello world3";
 }
 console.log(foo());
 // = > "hello world1"
  • 函数的运算结果可以是什么样的数据类型;
  • return 可以返回什么数据类型那 ?
  • 任意数据类型都可以返回;

**如果函数返回了一个函数会发生什么 ? **

 function foo(){
     console.log("foo");
         function poo(){
            console.log("poo")
         }
     return poo;
  }
   var res = foo();
   // 此时 res 里面存储的是 poo 函数的地址;
   // 此时的 res 和 poo 完全一样;
   res();

5、函数的递归(重点)

  • 一个函数调用了他自身,这种现象叫递归

注意

  • 递归就是函数自己调用自己
  • 递归类似于循环
  • 递归函数要注意停止返回,否则会造成死递归
  • 递归比较消耗性能,尽量少用

我们想要把递归进行正经的应用:

  1. 终止条件 => 包裹在if之中的 return;
  2. 运算条件 => 算法; => 极简算法;
  3. 返回结果 => return ;

用递归做一个简单的案例:

// num 求 1 ~ num 的累加 ;
// 累加 :  1 + 2 + 3 + 4 + 5 + 6 ....
    var count = 0;
    function sum( num ){
       // count(查看运行次数)
        count ++;
       // 这个运算的起始值,归到起始点;
       // 终止条件(必须要有不然会照成死循环)
        if( num === 1){
            return 1;
         }
         // 运算条件
         return sum( num - 1 ) + num;
      }   
        // sum( 1 ); // 1;
        // sum( 2 ); // sum(1) + 2; => 3;
        // sum( 3 ); // sum(2) + 3; => 6;
     var res = sum(100);
     console.log( res );
     console.log(count);

posted @ 2020-03-01 18:20  sunhuan欢  阅读(1264)  评论(0编辑  收藏  举报