JS函数笔记

定义函数

  • 具名函数
function 函数名(形参){
    语句
    return 返回值
}
函数名(实参)

例子:这种函数调用不能执行函数,因为如果函数写到等于号右边,函数的作用域只作用于等于号右边,在别的位置fn不存在

let a=function fn(x,y){
    return x+y
}
fn(1,2)

  • 匿名函数
let a=function(x,y){
    return x+y
}
  • 箭头函数
let fn2=(x,y)=>{
    return x*y
}

例子:

// 直接返回会出错,外面需要加一个圆括号
let f=(x)=>({name:x})
// 调用
f('frank')
  • 构造函数
let fn1=new Function('x','y','console.log(\'hi\'); return x+y')
// 调用
fn1(1,2)

函数的调用时机

函数什么时候调用,什么时候函数才会执行,不要管函数声明写到哪个位置。
举例:

let a=1;
function fn(){
    // 尽快将a打印出来
    setTimeout(()=>{
        console.log(a)
    },0)
}
fn()
a=2

//打印结果2

函数什么时候调用,才能证明这个函数什么时候有效,在哪里声明不影响执行。这也被称之为函数提升。注意,如果是函数赋值给某个变量,这个函数是不会提升的。

for循环配合setTimeout的代码题

情况一:

let i
for(i=0;i<6;i++){
    //等for循环忙完,再执行console.log(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
// 因为JS会在for和let一起用的时候会加东西,每次循环会多创建一个i

作用域

全局变量:顶级作用域声明的变量或者是挂载到window上面的属性,就是全局变量。
局部变量:如果在函数里面或者代码块里面,外面访问不到这个变量,这个变量就是局部变量。

作用域的规则

JS函数会寻找离他最近的作用域的变量,也称为就近原则。

闭包

概念:如果一个函数用到了外部的变量,这个函数加变量就是闭包。
举例:

function fn(){
    let a=1;
    function fn2(){
        console.log(a)
    }
    fn2()
}
fn()

函数的参数

函数的参数分为形式参数、实际参数,简称为形参和实参。它们可以完成函数的传参的过程。
例如:

function add(x,y){
	return x+y;
}
add(1,2)

这就相当于声明了x=1,y=2,且作用域是add函数内。

调用栈

什么是调用栈?
JS引擎在调用一个函数前,需要把函数所在的环境push到一个数组里面,这个数组叫做调用栈。等函数执行完毕,就把环境pop(弹出来),然后return到之前的环境,继续执行后续代码。

什么是爆栈?
如果调用栈中,压入的帧过多,程序就会崩溃。

this

arguments和this是JS中每个函数都要有的,箭头函数除外。arguments是伪数组。
如何传递arguments?

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

//调用
fn(1,2,3)
// arguments就是[1,2,3]的伪数组

如何传this?

fn.call(xxx,1,2,3)
// xxx就是被JS自动转化为对象,这个对象就是this

举例:

let person={
    name:'frank',
    sayHi(){
        console.log(`我是:${this.name}}`)
    }
}
// sayHi函数通过this,引用了person对象的地址,从而方便sayHi获取person对象
// 每个函数都能通过this获取到一个未知对象的地址引用

// 调用person里面的sayHi
person.sayHi()   =>   person.sayHi.call(person)

上面有两种调用函数的方式:

// 省略形式
person.sayHi()
// 完整形式
person.sayHi.call(person)

call是可以指定this指向的对象是谁,比如说:

// 下面我给this手动传1
let person={
    name:'frank',
    sayHi(){
        console.log(`我的名字是:${this.name}`)
    }
}
person.sayHi.call({name:1})
//打印结果是:我的名字是1

call只是其中一种调用函数的方式,调用函数的方式由三种,call、apply、bind。call和apply的区别就是,call接收多个参数,apply接收两个参数,第二参数是数组的形式。bind调用和call类似。

function fn1(p1,p2){
    console.log(this,p1,p2)
}
// 简略写法
fn1(1,2)
// call,undefined是为了占位,写其他的数也可以
fn1.call(undefined,1,2)
// apply
fn1.apply(undefined,[1,2])
//bind
fn1.bind(undefined,1,2)

箭头函数

箭头函数没有arguments和this,箭头函数的this指向window。
例如:

let a=(x)=>{
	console.log(x)
}

立即执行函数

语法:

!function(){}()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值