js之函数

209 阅读7分钟

1、概念:

      函数表达了某一种特定的规律,将这种特定的规律用一种方法表达出来就称之为函数.

2、函数的定义:

  • 第一种方式

      函数声明,使用function关键字,基本格式如:

functin 函数名称 (可选参数1,可选参数2,...){
}

      例如:

function hello(){
    alert("hello,world!");
}

函数定义完之后,并不会自动执行,需要调用才可以执行函数中的代码.

      函数的调用:

            函数名(参数),核心就是小括号。

function hello(){
    alert("hello,world!");
}
//调用函数
hello();

          注*

      (1)、定义函数,需要关键字function,关键字之后和函数名需要空格。

      (2)、函数名称,和定义变量时规则是一样的.

      (3)、大小写区分的,在定义普通函数(目前所学的阶段),首字母使用小写,如果有多个单词,仍然遵循小驼峰命名法则。

      (4)、函数名不要以数字开头,可以使用一些特殊符号,如下划线。

      (5)、函数名称后面是小括号,必不可少,用来装载形式参数的.

      (6)、{}就是函数体,不能少,

  • 第二种方式

      函数表达式。

let hello=function(){
    alert("hello,world!");
}
hello();

            注*

            (1)、将function整体,放在赋值运算符的右边,作为表达式来使用。

            (2)、通过一个变量来引用当前的function,便于后续的调用。

            (3)、函数名称可以加上,但是只对函数内部起作用.

            将function整体,放在赋值运算符的右边,作为表达式来使用。 通过一个变量来引用当前的function,便于后续的调用。 函数名称可以加上,但是只对函数内部起作用,如图:

           在js中,我们把使用声明方式来定义函数的这种用法 —– 函数声明提前。

可以这么来理解,在js中,只要有函数声明,相当于这行代码放在最前面

           对于函数表达式这种方式,其实它就是一个变量,只不过我们在赋值的时候,是将函数这种类型的数据赋值给它了。既然是变量,那么就遵循变量的规则,一定要先声明,然后再使用。

3、函数的调用及返回值

      (1)、函数调用

      *作为函数调用:

            自定义函数的调用:function f(){};f();

            js提供的内置函数:alert(),parseInt(),parseFloat(),setTimeout等

       * 作为方法来调用

      将函数定义到某个具体的对象上面,然后通过.语法来进行调用,如:console.log(str);

      (2)、函数返回值

      函数一定会有返回值。 你调用任何一个函数,都会得到这个函数的返回值,如果这个函数没有写明return,则有一个默认的返回值undefined。

      默认情况下,Js函数只能返回一个值。如果你想返回多个值的话,那么你可以使用容器。

      通过return返回,返回到函数的调用处。 在函数体中,return后面的代码就不会执行了。return也叫跳转语句。

      返回值有

  • 返回一个值: a=123;    return a;
  • 返回多个值:

            (1)、使用数组:[1,2,3,"hello",true] 获取某个元素,使用索引。

            (2)、使用对象:对象:{name:"wangcai",age:100} name和age叫key,wangcai和100叫value(key:value是成对出现的)

4、函数的参数

      形参:函数定义时,()中写的参数,叫形参,相当于函数内部的局部变量,作用是用来接收实参。(相当于函数内部的局部变量)

      实参:函数调用时,()中写的参数,叫实参,作用是给函数传递真实的数据,传递过去形参接收了。

let add = function (a, b) {//此处()内的a,b是形参
        return a + b;
    }
    add(1,2);//此处()内的1,2是实参

      参数的传递:

基本数据类型的数据(值传递)
    就是把栈区的数据copy一份给了形参,形参和实参是一个独立一个内存空间。改变形参,
    实参是没有影响。 
引用数据类型的数据(引用传递)
    就是把栈栈区的地址copy一份给了形参,形参和实参同时指向堆区同一个内存空间。通过
    形参改变堆区内存空间的数据,实参这个地址应对的数据也会发生改变。
//基本数据类型参数传递
     function f(a){
         a = 666;
     }
     let x = 110;
     f(x);
     console.log(x)  // 110
     
//引用数据类型参数传递
     function f(a){
         a = [4,5]
     }
     let x = [1,2];
     f(x);
     console.log(x)  
     console.log(a)  

      函数可以作为另一个函数的参数:

    一个函数可以作为另一个函数的参数,这个函数可以是函数声明,也可以是函数表达式
在JS,我们可以把一个函数声明,作为别一个函数的参数
// 函数表达式
     var add = function (a, b) {
        return a + b;
     }
     function compute(f, x, y) {
        return f(x, y);
    }
    console.log(compute(add,1,2))
    
// 函数声明
     function compute(f, x, y) {
         return f(x, y);
     }
     // 函数调用  调用的时候,给它传递了一个函数声明
     let rs = compute(function(a,b){
         return a + b;
     },1,2)
     console.log(rs)

          arguments:

        函数调用的过程就是实参向形参赋值的过程。实参会复制一份给形参,除此之外,它还会给arguments一份。

arguments中收集了实参。 
arguments只是函数内部的属性(类数组), 在函数外面是不能访问的。
arguments和形参这间有一一对应的关系:
    当形参改变了,那么arguments里面的数据也会改变
    当改变了arguments里面的数据,形参也会发生改变
什么时候使用形参,什么时候使用arguments?
    1,当实参非常多时,写一堆的形参来接收,不方便,此时你就可以使用arguments
    2,当实参有特殊含义时,需要有一个特殊的标识,就可以使用形参来标识。

5、箭头函数

      * 省略function关键字

     function f(a,b){
         return a+b;
     }
     箭头函数 没有function关键字   =>
     var f = (a,b)=>{
         return a+b;
     }
     console.log(f(1,2))

      * 如果形参只有1个,()可不写 只有一个形参时,()才能省,其它情况都不省

    let f = (a)=>{
         console.log(a)
     }
     let f = a=>{
         console.log(a)
     }
     f(2)

      * 如果函数体只有一条语句,{}也可以省,return也需要省。

     let f = (a)=>{
         return a;
     }
     let f = (a)=>a;
     console.log(f(2))

      *如果返回对象,把{} 和 return 省掉的话,需要给这个对象加()

     let f = ()=>{
         return {name:"wangcai"}
     }
     let f = ()=>({name:"wangcai"})
     console.log(f())
     let f = ()=>console.log(123)
     f()