基础知识点
let a=function fn(x,y){return x+y}
// undefined
a(1,2)
// 3
fn(2,4) 会报错
若函数是在等于号右边,则函数作用域就只有函数右边,相当于函数名字没有生效
箭头函数:
let f1 =(输入参数)=>(输出参数)
let f1=x=>x*x
f1(5)
// 25
let f2=(x,y)=>x*y
f2(2,3)
// 6
let f3=(x,y)=>{
console.log('hi')
return x+y
}
f3(8,9)
// hi
// 17
let f4=x=>({name:x })
f4('frank')
// {name: 'frank'}
所有的函数都是由Function构造出来的,包括 Object、Array、Function
只写fn不会调用函数,相当于一个变量名,要用fn()才会被调用
let fn = () => console.log('hi')
fn
// () => console.log('hi')
fn()
// hi
代码
let fn = () => console.log('hi')
let fn2 = fn
fn2()
// hi
该函数会被调用,因为
- fn 保存了匿名函数的地址
- 这个地址被复制给了 fn2
- fn2() 调用了匿名函数
- fn 和 fn2 都是匿名函数的引用而已
- 真正的函数既不是 fn 也不是 fn2
setTimeout做完手头的事情之后立刻做这个事情。
作用域
let的作用域就是相近的{}里面,出来这个空间就没有了
- 作用域规则
- 如果多个作用域有同名变量 a,那么查找 a 的声明时,就向上取最近的作用域,简称「就近原则」
- 查找 a 的过程与函数执行无关
- 但 a 的值与函数执行有关
闭包
定义
返回值
每个函数都有返回值
function hi(){ console.log('hi') }
hi()
没写 return,所以返回值是 undefined
function hi(){ return console.log('hi') }
hi()
返回值为 console.log('hi') 的值,即 undefined
- 函数执行完了后才会返回
- 只有函数有返回值
- 1+2 返回值为 3 错的
- 1+2 值为 3 对
调用栈:
类似于打游戏存档
- 递归函数 eg. 阶乘
function f(n){
return n !== 1 ? n* f(n-1) : 1
}
arguments 和 this
- arguments 是一个伪数组,包含所有参数的伪数组
- 每次调用函数时,都会对应产生一个 arguments
- arguments 是一个包含所有普通参数的伪数组
- 我们应该尽量不对 arguments 内的元素进行修改,修改 arguments 会让代码变得令人疑惑
- this 谁调用该函数,this就指向谁
call 传的是什么,this就是啥
关于 this(假设arrow()是箭头函数)
- 在 new fn() 调用中,fn 里的 this 指向新生成的对象,这是 new 决定的
- 在 fn() 调用中, this 默认指向 window,这是浏览器决定的
- 在 obj.fn() 调用中, this 默认指向 obj,这是 JS 的隐式传 this
- 在 fn.call(xxx) 调用中,this 就是 xxx,这是开发者通过 call 显式指定的 this
- 在 arrow() 调用中,arrow 里面的 this 就是 arrow 外面的 this,因为箭头函数里面没有自己的 this
- 在 arrow.call(xxx) 调用中,arrow 里面的 this 还是 arrow 外面的 this,因为箭头函数里面没有自己的 this 箭头函数没有arguments 和 this