前端学习day36&day37:07-JS基础之函数

函数

        函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块。通俗的说,函数是利用特定语法,将一段代码打包在一起,每次调用函数就可以让这个代码块内的代码全部执行,复用代码。

        要注意的是,函数跟循环不相似,循环是重复一定次数地执行代码,函数虽然可以重复执行代码,但是它很灵活,可以任意决定它调用的时机。

1.声明函数

        声明函数有两种方式:

// 方式一
let fn1 = function () {
  // 代码块
}

// 方式二
function fn2 () {
  // 代码块
}

        fn1和fn2都是函数名字,这是两种不同的声明方式。

        函数体内的代码,在声明时是不会执行的。必须在调用函数后,这些代码才会执行。

2.调用函数

        函数调用只需要将函数名字加括号即可,一个函数可以被重复调用无数次。

let fn = function () {
  // 代码块
}

fn()

        调用后,函数内的代码块就会被执行。

        例如:计算1 + 2的值,并将值输出。

let add = function () {
  let res = 1 + 2
  console.log(res)
}

// 第一次调用
add() // 此时函数调用,函数体内的代码执行,输出3

// 还可以再次调用
add() // 此时再次调用,继续执行代码,输出3
...

        这样我们就可以得到一个能自动计算1+2值的函数。

3.函数参数

        为了不让函数内部的代码全部都固定死、每次执行都是固定结果,所以函数在调用时,可以从外部注入数据到内部使用,这种行为是通过函数参数完成的。

        想要使用函数参数功能,从外部注入数据,那么函数内就需要提前有占位的符号,这种符号就类似变量功能,称为形参,而注入的数据成为实参。

// 例如计算,1 + n的结果

// 此时函数内需要一个n作为占位符,那么n需要提前声明
let add = function (n) { // 这个n是声明函数内会使用n(n就是形参)
  let res = 1 + n // 这里使用n占位
  console.log(res)
}
// 调用时,可以传入不同的数据,作为此次调用n的实际数据,
add(5) // 此时n=5,则执行后,输出:6 (传入的5就是此次传入的实参)

add(10) // 输出:11

...
add(-10) // -9

        这样就得到一个能计算1+n的函数,如果需要的参数很多,依次写上占位符,将实参依次写在调用的括号内即可

        实参和形参的顺序是对应的,第一个形参接收第一个实参…以此类推
        形参需要遵守变量命名规范

let fn = function (a,b,c,d,e) {}

fn(1,2,3,4,5)

        虽然形参和实参可以让函数使用起来非常灵活,但是这样并不是万能的。

        例如,需要计算所有传入的实参的和。

let add = function (a, b, c){
  // 如果实参个数不确定,那么形参就不好写,因为写少了,多出来的实参就无法接收,写多了,可能又会没有值传入
  let res = a + b + c
}

add(1, 2) // 此时传入2个实参,形参3个,那么最后一个c就没有值就是undefined,此时进行运算会得到NaN

        通过上面例子,发现形参和实参通常是在个数确定的时候使用,如果数量不确定使用起来就很不方便。

4.Rest参数

        rest是剩余的意思,rest参数用于函数参数不确定的情况。每次传入的参数数量都不同,或者函数参数过多,但是又不想写那么多形参的情况,都可以用rest一次性全部接收。

// 例如,计算传入的所有数据
let add = function (...rest) {
  let res = 0
  for (let value of rest) {
    res += value
  }
  console.log(res)
}

add(1, 2) // 实参2个,此时rest接收到就是两个数据,  输出 3

add (3, 5, 4) // 实参3个,rest内就是3个数据。输出 12

        通过上面例子,可以看出,rest非常灵活,可以用于接收所有实参

        如果需要接收部分参数,也可以这么做

let add = function (a, b, ...rest) {}

add(1,2,3,4,5) // 此时 a = 1 b = 2 rest = [3,4,5]

        所以,rest是用于接收剩余的没有被形参所接收的全部参数的。如果一个形参都没有,只有rest,那么rest接收所有实参,如果rest前面有形参,则其他形参优先接收,剩下没有被接收的都在rest内。所以rest的名字非常形象【剩余参数】。

        需要注意的是,rest必须是最后一个参数,rest参数后面不能再写其他形参。下面的写法都是错误的

let fn = function (...rest, a){}

let fn1 = function (a, ...rest, b){}

let fn2 = function (...rest, ...rest2) {}
// 这三种都是错的。

5.返回值

        上面的所有函数,数据只能从外传入内,然后在内部使用。无法将函数内的运算结果返回出外部使用。这是因为函数没有设置返回值。

        函数设置返回值使用return命令,return的作用是停止函数执行,并立刻返回后面的值

let add = function () {
  let res = 1 + 3
  return res
}

add() // 4

        函数内一旦执行到return所在的行,就会立刻返回值。下一行以及之后的代码将永远不会执行。

6.箭头函数

        箭头函数是function函数在某些情况下的特殊写法

let fn = function () {
  return 1 + 3
}

// 上面fn函数执行后,立刻返回1+3的值,对应的箭头函数写法
let fn = () => 1 + 3

        箭头函数=>之后的内容就相当于function函数return之后的内容。但是这种写法只适合上面的情况。

let fn = function () {
  let a = 3
  let b = 2
  let c = a ** b
  return c
}

// 上面的函数,函数体内有多条语句时,需要使用下面的写法
let fn = () => {
  let a = 3
  let b = 2
  let c = a ** b
  return c
}

        通过上面两个例子可以发现,如果箭头函数内有多条语句时,需要写花括号。没有花括号的箭头函数,其箭头后只能写一条语句,并且语句的结果会默认被return,有花括号时,如果需要返回值,需要明确写上return。

        如果需要传参时:

let add = function (a, b, ...rest) {
  let res = a + b
  for(let value of rest) {
    res += value
  }
  return res
}

// 以上函数等价于下面箭头函数
let fn = (a, b, ...rest) => {
  let res = a + b
  for(let value of rest) {
    res += value
  }
  return res
}

        所以箭头函数的参数写法跟function函数是完全一致的。

7.函数在对象内的简洁写法

        如果一个函数是对象内的某个属性的值时,可以有简洁的写法

let o = {
  fn: function () {
    
  }
}

// 以上是正常写法,跟下方写法完全等价
let o1 = {
  fn () {
    
  }
}

8.其他注意事项

        立即执行函数(定义时就立马使用):不是函数的一种,而是函数执行的一种。主要是创建一个单独的作用域,防止让变量成为全局变量,从而污染全局。

          (function(){}())
          (function(){})()
          +function(){}()
          -function(){}()
          ~function(){}()
          !function(){}()

        函数声明:函数可以先使用后声明(变量提升)且不会报错,不过最好还是先声明后使用。

        形参的命名: 见名知意。

        形参没有接收到实参的话则形参的值为undefined。

        关于形参个数和实参个数的几种情况:

        ①没有形参,只有实参
              不作反应,只运行
        ②有形参,不传实参
              形参接收undefined
        ③有形参,有实参
              Ⅰ.个数一致  按顺序接收
              Ⅱ.个数不一致
                        ⑴形参多于实参
                          先按顺序一一对应接收,没有接收到实参的就是undefined 

                        ⑵实参多于形参
                          先按顺序接收,多余的实参就不去管了

        一般需要多少形参和实参就写多少形参和实参

        ...rest接收剩余参数,其中rest可以自定义名字即 ...名字

        

        箭头函数:

        (形参) => {代码块}
        就算没有形参,括号也必须要写

        只有一个形参,括号可以不写  
        有多个形参,括号必须写
        只需要return一个数据时则可以省略{}和return

        箭头函数的this是固化的,或者说箭头函数根本就没有this,其this就是外层对象的this;如果外层对象也没有this,则其this指向window顶层对象

        形参的默认值: 

 function zhuque(val,val2 = 2){
          // 如果val2可以接受到 实参 则val2 = 实参值 如果接收不到 则val2 = 2 
        }

        例:如果val2可以接受到实参,则val2 == 实参值;如果接收不到,则val2 = 2。

        

        不需要声明形参:

        形参不需要声明,声明的话会报错:重复声明。

        修改this指向:

window.a = 0

    let obj1 = {
      a: 1
    }
    let obj2 = {
      a: 2
    }

    function fn(num1, num2, num3) {
      console.log(this.a); // 0
      console.log(num1, num2, num3);
    }

        call():第一个参数为this将要修改指向的对象,有其他参数时在后面用逗号 一一跟上即可,该函数可以主动执行。

fn.call(obj1, 1, 2, 3)

        apply():第一个参数为this将要修改指向的对象,有其他参数时需要用数组的[]符号包一下,该函数可以主动执行。

fn.apply(obj2, [1, 2, 3])

        bind():第一个参数为this将要修改指向的对象,有其他参数时在后面用逗号一一跟上即可,该函数不会主动执行,但会return函数本体,此时再加上一个括号即可执行。

fn.bind(obj1, 1, 2, 3)()

        返回值:如果没有手动给函数定义return的内容,那么函数执行完毕后默认return一个undefined;

                      return可以返回任意数据类型的值;

                      return后面用逗号表达式接上了几条数据时只会返回最后一条数据;

return 1, "ysc","ysc666";   //此时返回ysc666

                      如果要返回多条数据,可根据情况将数据放置在数组或者{}对象里;

                      return后可以接运算表达式,此时会将表达式运算到最简结果后再把结果返回出去。

        this:this就近指向调用函数的对象。如果没有调用函数的对象,则指向window对象。this指向与函数在哪声明无关,而是和调用环境以及调用者有关;事件函数里this指向事件触发者。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值