JS中函数

一、函数的概念

  • 把可以重复使用的代码块,封装成独立的模块
  • 在JS中,函数就是把一段代码块放在一个盒子里面,在我想要让这段代码执行的时候,直接执行这个 盒子里面的代码就行
// 定义一个名字为fn的函数
 function fn(){
       console.log('函数里面的代码块');
}
// 通过函数名加()调用
fn()

二、函数的两个阶段

1. 定义阶段

函数的定义分为声明式和赋值式

1.1 声明式

  • 使用 function 这个关键字来声明一个函数
  • 语法:
function fn() {
  // 一段代码
}
// function: 声明函数的关键字,表示接下来是一个函数了
// fn: 函数的名字,我们自己定义的(遵循变量名的命名规则和命名规范)
// (): 必须写,是用来放参数的位置(一会我们再聊)
// {}: 就是我们用来放一段代码的位置(也就是我们刚才说的 “盒子”)

1.2 赋值式

  • 其实就是和我们使用 var 关键字是一个道理了

  • 首先使用 var 定义一个变量,把一个函数当作值直接赋值给这个变量就可以了

var fn = function () {
  // 一段代码
}
// 不需要在 function 后面书写函数的名字了,因为在前面已经有了

2. 调用阶段

  • 就是让 盒子里面 的代码执行一下
  • 让函数执行
  • 两种定义函数的方式不同,但是调用函数的方式都以一样的

2.1 调用接一个函数

  • 函数调用就是直接写 函数名() 就可以了
// 声明式函数
function fn() {
  console.log('我是 fn 函数')
}

// 调用函数
fn()

// 赋值式函数
var fn2 = function () {
  console.log('我是 fn2 函数')
}

// 调用函数
fn()
  • 注意: 定义完一个函数以后,如果没有函数调用,那么写在 {} 里面的代码没有意义,只有调用以后才会执行

2.2 调用上的区别

  • 虽然两种定义方式的调用都是一样的,但是还是有一些区别的
  • 声明式函数: 调用可以在 定义之前或者定义之后
// 可以调用
fn()

// 声明式函数
function fn() {
  console.log('我是 fn 函数')
}

// 可以调用
fn()
  • 赋值式函数: 调用只能在 定义之前
// 会报错
fn()

// 赋值式函数
var fn = function () {
  console.log('我是 fn 函数')
}

// 可以调用
fn()

三、函数的优点

  • 函数就是对一段代码的封装,在我们想调用的时候调用
  • 函数的几个优点
    1. 封装代码,使代码更加简洁
    2. 复用,在重复功能的时候直接调用就好
    3. 代码执行时机,随时可以在我们想要执行的时候执行

四、函数的参数

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

fn(实参写在这里)

// 赋值式函数
var fn = function (行参写在这里) {
  // 一段代码
}
fn(实参写在这里)

1. 形参和实参的作用

1.1 形参

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

var fn1 = function (num) {
	// 在函数内部就可以使用 num 这个变量
}

// 书写两个参数
function fun(num1, num2) {
  // 在函数内部就可以使用 num1 和 num2 这两个变量
}

var fun1 = function (num1, num2) {
  // 在函数内部就可以使用 num1 和 num2 这两个变量
}
  • 如果只有行参的话,那么在函数内部使用的值个变量是没有值的,也就是 undefined

  • 行参的值是在函数调用的时候由实参决定的

1.2 实参

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

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

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

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

2. 参数个数的关系

2.1 行参比实参少

  • 因为是按照顺序一一对应的
  • 行参少就会拿不到实参给的值,所以在函数内部就没有办法用到这个值
function fn(num1, num2) {
  // 函数内部可以使用 num1 和 num2
}

// 本次调用的时候,传递了两个实参,100 200 和 300
// 100 对应了 num1,200 对应了 num2,300 没有对应的变量
// 所以在函数内部就没有办法依靠变量来使用 300 这个值
fn(100, 200, 300)

2.2 行参比实参多

  • 因为是按照顺序一一对应的
  • 所以多出来的行参就是没有值的,就是 undefined
function fn(num1, num2, num3) {
  // 函数内部可以使用 num1 num2 和 num3
}

// 本次调用的时候,传递了两个实参,100 和 200
// 就分别对应了 num1 和 num2
// 而 num3 没有实参和其对应,那么 num3 的值就是 undefined
fn(100, 200)

五、函数的arguments

  • 每个函数都有一个arguments属性(除了箭头函数)
  • 是函数实参的集合,是一个伪数组(类数组)
  • 有一个length属性,可读写 arguments.length
  • 按照索引排列,可读写 arguments[索引]

六、函数的return

  • return 返回的意思,其实就是给函数一个 返回值终断函数

1. 终断函数

  • 当我开始执行函数以后,函数内部的代码就会从上到下的依次执行
  • 必须要等到函数内的代码执行完毕
  • return 关键字就是可以在函数中间的位置停掉,让后面的代码不在继续执行
function fn() {
  console.log(1)
  console.log(2)
  console.log(3)
  
  // 写了 return 以后,后面的 4 和 5 就不会继续执行了
  return
  console.log(4)
  console.log(5)
}

// 函数调用
fn()

2. 返回值

  • 函数调用本身也是一个表达式,表达式就应该有一个值出现
  • 现在的函数执行完毕之后,是不会有结果出现的
// 比如 1 + 2 是一个表达式,那么 这个表达式的结果就是 3
console.log(1 + 2) // 3

function fn() {
  // 执行代码
}

// fn() 也是一个表达式,这个表达式就没有结果出现
console.log(fn()) // undefined

return 关键字就是可以给函数执行完毕一个结果

function fn() {
  // 执行代码
  return 100
}

// 此时,fn() 这个表达式执行完毕之后就有结果出现了
console.log(fn()) // 100
  • 我们可以在函数内部使用 return 关键把任何内容当作这个函数运行后的结果

七、了解常见的事件(函数和事件的结合)

1. 鼠标事件

onclick:当用户单击鼠标按钮或按下回车键时触发
ondblclick:当用户双击主鼠标按钮时触发 - 连续点击两次
onmousedown:当用户按下了鼠标还未弹起时触发 - 弹窗测试最明显
onmouseup:当用户释放鼠标按钮时触发 - 鼠标抬起
onmouseover:当鼠标移到某个元素上方时触发
onmouseout:当鼠标移出某个元素上方时触发
onmouseenter:当鼠标移到某个元素上方时触发
onmouseleave:当鼠标移出某个元素上方时触发
onmousemove:当鼠标指针在元素上移动时触发

2.键盘事件

onkeydown:当用户按下键盘上任意键触发,如果按住不放,会重复触发
onkeyup:当用户释放键盘上的键触发 - 当按键抬起时触发
onkeypress:当用户按下键盘上的字符键触发,如果按住不放,会重复触发  不能触发 例如:ALT, CTRL, SHIFT, ESC

3.表单事件

onfocus:input聚焦时
onblur: input失去焦点时
onchange:input文本改变的时候
onselect:当用户选中文本框(input 或 textarea)中的一个或多个字符触发
onsubmit:当用户点击提交按钮在<form>元素上触发

4.浏览器事件

onload:当页面完全加载后在 window 上面触发,或当框架集加载完毕后在框架集上触发
onresize:当窗口或框架的大小变化时在 window 或框架上触发
onscroll:当用户滚动带滚动条的元素时触发

八、预解析(重点)

  • 预解析 其实就是聊聊 js 代码的编译和执行
  • js 是一个解释型语言,就是在代码执行之前,先对代码进行通读和解释,然后在执行代码
  • 也就是说,我们的 js 代码在运行的时候,会经历两个环节 解释代码执行代码

1.解释代码

  • 因为是在所有代码执行之前进行解释,所以叫做 预解析(预解释)

  • 需要解释的内容有两个

    • 声明式函数
      • 在内存中先声明有一个变量名是函数名,并且这个名字代表的内容是一个函数
    • var 关键字
      • 在内存中先声明有一个变量名
  • 看下面一段代码

    fn()
    console.log(num)
    
    function fn() {
      console.log('我是 fn 函数')
    }
    
    var num = 100
    
  • 经过预解析之后可以变形为

    function fn() {
      console.log('我是 fn 函数')
    }
    var num
    
    fn()
    console.log(num)
    num = 100
    
  • 赋值是函数会按照 var 关键字的规则进行预解析

    预解析的无节操

    1. 不管 if 条件是否成立,代码块里面的代码会进行预解析

    2. return 后面的代码虽然不执行,但是会进行预解析

    九、函数定义阶段和调用阶段

      函数定义阶段做的三件事情
          1. 开辟一个内存空间
          2. 把你写的代码一模一样的放在这个空间中(不解析变量)
          3. 把空间地址给到变量名(函数名)
       函数调用阶段的四个事情(熟读并背诵全文)
          1. 按照函数名内部存储的地址找到对应的函数存储空间
          2. 形参赋值
          3. 预解析
          4. 函数体内的代码执行(才开始解析变量)    
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

对卦卦上心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值