函数概念,声明及调用,函数表达式(匿名函数),函数传参,函数返回值

296 阅读6分钟

1.函数

1.函数概念,声明及调用

JS中的函数:把一段需要重复使用的代码,用function语法包起来,方便重复调用,分块和简化代码。复杂一点的,也会加入封装、抽象、分类等思想。

声明方式:严格意义上两种方式,但还有匿名函数

方式一:

function 方法名(){
     //要执行的代码
}

方式二:ES6中声明方式箭头函数:()=>{}

方式三:匿名函数,将函数存到变量里 let fn = function(){};

函数调用:两种方式调用

调用方式一:名字(); 函数可以多次调用

2.函数表达式(匿名函数)

函数表达式:就是把函数存到变量里。

匿名函数:没有名字的函数;

匿名函数在使用时只有两种情况:

匿名函数自执行:声明后不需要调用就直接执行

(function(){
    console.log("匿名函数自执行");
})();
  • 函数表达式:把函数存到变量,或将函数存到数组的对应位置里等,调用时通过变量或数组对应位置进行调用。调用时需要写括号。

    //2,函数表达式:把函数存到变量或数组等里,调用时通过变量进行调用
    var fn = function(){
        console.log("函数表达式:将函数存到变量里");
    };
    fn();//调用时需要写括号
     
    //2,函数表达式:把函数存到数组第0位,调用时通过数组第0位进行调用
    var arr = [];
    arr[0] = function(){
         console.log("函数表达式:将函数存到数组的对应位置");
    };
    arr[0]();//调用时需要写括号要写括号
    

    结果:

    匿名函数自执行

    函数表达式:将函数存到变量里

    函数表达式:将函数存到数组的对应的位置

       事件函数扩展:给元素添加事件的说法是不正确的。事件时元素本身就具有的特征,只是触发事件后,默认没有相关的一些处理。这种操作其实就是给元素的某个事件添加一个事件处理函数。当事件被触发后,判断到属于该事件类型,就触发该事件函数的处理函数

可以通过console.dir()把对象的所有属性和方法打印出来,查看对象或元素本身具有的事件

<script>
       //事件时元素本身就具有的特征,只不过,触发事件后,默认没有相关的一些处理。
       事件函数其实就是给元素的某个时间添加一个事件处理函数。
       //可以通过console.dir()把对象的所有属性和方法打印出来
       document.onclick = function(){
           console.log("事件的处理函数");
       };
       //当被触发后,判断到属于该事件类型,就触发该事件函数的处理函数
       if(typeof document.onclick == "function"){
         document.onclick();
       }
</script> 

结果: 事件的处理函数

3.函数传参

获取元素,最好从父级元素获取,全部从document中获取,可能会出现混乱。

  • 形参:形式上的参数——给函数声明一个参数;

    声明定义的时候,形参只是参数占位,

    在调用方法的时候,形参是一个变量

    相当于在方法中声明的局部变量(只有在方法内部可以使用,如果在方法外部使用,会报错)

  • 实参:实际的参数——在函数调用时给形参赋的值

    调用函数的时候,写在()里面的就是实参

    实参是实际参数,是真正存在的值

    调用的时候,尽量让实参和形参:顺序对应,数量对应,类型对应

    function func(形参1,形参2){ //函数执行代码 }

    func(实参1,实参2);//调用时传参

index.js:

function _id(idName){
    return document.getElementById(idName);
}
function _selector(parent,selector){
    return parent.querySelector(selector);
}
function _selectorAll(parent,selectors){
    return parent.querySelectorAll(selectors);
}

4.函数返回值

函数返回值即函数执行之后的返回结果。

  1. 所有函数都会有函数返回值即函数执行后一定会返回一个结果,如果没有定义默认返回undefined;

  2. 在函数中,return后定义返回值;

  3. 在函数中,return之后的代码就不会再执行了

  4. 只能用于函数中,用在其他地方会报错

    <script>
            function func1(){
               console.log("函数func1执行内容");
            } 
            function func2(){
               console.log("函数func2执行内容");
               return 1;
               let a = 2;
               console.log(a);
            } 
            //如果没有定义默认返回undefined
            console.log("func1返回结果:"+func1());//undefined
            console.log("func2返回结果"+func2());//1
    </script>
    函数功能的单一性:函数只做业务处理,并不会对结果进行处理
    它会将 结果返回,让调用者进行处理
     通过return关键字可以实现方法的返回值
    
    说明
    1.不是每个函数都都会手动返回值
    2.如果一个函数没有返回值,默认也会返回undefined,所以后期如果你调用一个函数,返回值是undefined,要么你手动返回了undefined,要么就是没有手动返回值
    3.默认情况下,函数只能返回一个值(变量),如果想返回多个值,一般可以使用一个结构(对象)进行包装,如果直接返回多个值,最终也会返回最后一个值
    4.return有两种常用的功能:返回值   结束当前函数
    5.return只能写在函数中,写在函数外部会报错: Illegal非法的 return返回 statement语句
    

    5.作用域

三种作用域 ​ 全局作用域:在script标签中声明的成员 ​ 函数作用域:局部作用域:在函数内部声明的成员 ​ 块级作用域:在{}中声明的成员

let ​ 它有块级作用域

作用域链:函数内部还可以创建函数,函数内部可以使用函数外部的成员

当函数内部需要一个变量的时候,自己有就使用自己的,如果没有就查找外部作用域,如果还没有,

再继续往外部找,直到全局作用域,如果全局也没有,就报错

// 一:全局作用域 -- 全局变量
// 如果没有声明这个变量,报错 age is not defined:age 没有定义
// Cannot access 'age' before initialization:不能在初始化之前访问age
// console.log(age)
//在scripts标签中直接声明的变量,就有全局作用域:因为它在整个script标签中都可以用
// let age = 20

// 二:局部作用域:也叫函数作用域 -- 局部变量
// 在函数内部声明的变量,在函数外部不能使用(形参相当于函数的局部变量)
// function test() {
//   let age = 20
// }
// test()
// console.log(age)

// 三:块级作用域 -- 块级变量
// 块:就是指{ }
// let 会有块级作用域:它的作用域是:
// 1.作用域:let变量所在的{}结构
// 2.有效作用域:从定义这个变量开始,到这个变量所在结构的}结束
// if (true) {
//   console.log(age) // Cannot access 'age' before initialization
//   let age = 20
//   // console.log(age) // 20
// }
// console.log(age) // age is not defined

// 如果一个就是没有使用let声明,而是直接使用,相当于定义一个真正意义的全局变量,
   它会将这个变量挂载到window全局,页面不关闭,变量不释放,严重的会造成全局污染
// let不会挂载到全局的window,循环执行完毕之后,会由js垃圾回收机制自动回收,节流性能