【学习】JS 函数

JS函数

定义一个函数

  • 具名函数
function 函数名(形式参数1,形式参数2){
  语句
  return 返回值
}
  • 匿名函数
    • 也叫函数表达式,比如说
      let a = function(x,y){return x+y}
  • 箭头函数
    • let f1 = x => x*x
    • let f2 = (x,y) => x+y 有两个参数时需要用圆括号括起来
    • let f3 = (x,y) => {return x+y} 当语句超过一句时,需要用花括号括起来
    • let f4 = (x,y) => ({name: x, age: y}) 当要返回对象时,需要在外面加个圆括号
  • 构造函数
    • let f = new Function('x','y','return x+y')
      所有函数都是Function构造出来的
let fn = () => console.log('hi')
//fn 保存了匿名函数的地址
fn()
//fn()调用了匿名函数

函数的要素

  • 以下是每个函数都有的要素
    • 调用时机
    • 作用域
    • 闭包
    • 形式参数
    • 返回值
    • 调用栈
    • 函数提升
    • arguments (除箭头函数)
    • this (除箭头函数)

调用时机

调用时机不同,会导致结果不同

let a = 1
function fn(){
  console.log(a)
}
fn()
a = 2
// 1
let a = 1
funciton fn(){
  setTimeout(()=>{
    console.log(a)
  },0)
}
fn()
a = 2
// 2
let i = 0
for(i; i<6; i++){
  setTimeout(()=>{
    console.log(i)
  },0)
}
// 6个6
for(let i = 0; i<6; i++){
  setTimeout(()=>{
    console.log(i)
  },0)
}
// 0 1 2 3 4 5

作用域

每个函数都会默认创建一个作用域

function fn(){
  let a = 1
}
console.log(a)
// a不存在
  • 全局变量和局部变量
    • 在顶级作用域声明的变量是全局变量
    • window 的属性是全局变量
    • 其余的都是局部变量

  • 作用域规则
    • 如果多个作用域有同名变量a
      • 查找a的声明时,向上去最近的作用域,即就近原则
      • 查找a的过程与函数执行无关,但a的值与函数执行有关

闭包

如果一个函数用到了外部的变量,那么这个函数加上这个变量,就叫做闭包

function f1(){
  let a = 1
  function f2(){
    let a = 2         //从这一行开始
    function f3(){
      console.log(a)  //这一部分为闭包
    }                 //到这一行结束
    f3()
  }
  console.log(a)
  a = 100
  f2()
}

形式参数

形式参数就是非实际参数,形参可以认为是变量声明

function add(x,y){ //x和y就是形参
  return x+y
}
add(1,2) //1和2是实际参数

上面代码等价于下面代码

function add(){
  var x = arguments[0]
  var y = arguments[1]
  return x+y
}

形参可多可少,不一定指定多少参数就设置多少参数

返回值

  • 每个函数都有返回值
  • 函数执行完了后才会返回
  • 只有函数有返回值

调用栈

JS 引擎在调用一个函数前,需要把函数所在的环境push到一个数组里,这个数组叫作调用栈

一开始,我们得到一个空空如也的调用栈。随后,每当有函数被调用都会自动地添加进调用栈,执行完函数体中的代码后,调用栈又会自动地移除这个函数。最后,我们又得到了一个空空如也的调用栈。

  • 爆栈
    如果调用栈中压入的帧过多,程序就会崩溃

函数提升

  • function fn(){} 不管具名函数声明在哪里,作用的时候都会跑到第一行
  • let fn = function(){} 这种是赋值,右边的匿名函数声明就不会提升

arguments、this

  • arguments
    • arguments 是一个对应于传递给函数的参数的类数组对象。
    • arguments对象是所有(非箭头)函数中都可用的局部变量。可以使用arguments对象在函数中引用函数的参数。此对象包含传递给函数的每个参数,第一个参数在索引0处。
    • arguments对象不是一个数组,是一个伪数组

  • this
    • 当this不指向对象时,默认指向window
    • 如果传的this不是对象,js会自动封装为对象

function fn(){
  console.log(arguments)
  console.log(this)
}
  • 传 arguments

    • 调用 fn 即可传arguments
      比如fn(1,2,3) arguments就是伪数组[1,2,3]
  • 传 this

    • 可以使用`fn.call(xxx,1,2,3)传this和arguments
    • xxx为this ,1,2,3为arguments
    • xxx会被自动转化为对象

调用函数时,使用fn.call(xxx,x,y)这种形式,xxx表示this,可以是任何形式,常用undefined占用,x和y是调用函数的参数


this的两种使用方法

  • 隐式传递
    • fn(1,2) 等价于 fn.call(undefined,1,2)
    • obj.child.fn(1) 等价于 obj.child.fn.call(obj,child,1)
  • 显示传递
    • fn.call(undefined,1,2)
    • fn.apply*undefined,[1,2])

箭头函数

  • 里面的this就是外面的this
console.log(this) //window
let fn = () => console.log(this)
fn() //window
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值