函数是对象
具名函数
function 函数名(形式参数1,形式参数2){
语句
return 返回值
}
匿名函数
let a = fuction(x,y){return x+y} //=号后面也叫函数表达式
箭头函数
- 箭头函数简化函数表达式
const fn = name => 'Hello' + name
// 等价于
const fn = function( name ) {
return 'Hello' + name
}
// 多个参数 加括号括起来( )
const sum = ( a, b ) => a +b
const add = a =>b =>a+b
//等价于
const add = function(a){
return function(b){
return a+b
}
}
箭头函数和函数表达式有细微差异,体现在内部的this指代上
函数命名
• 动词、动宾
sum、hide、show
printName、sayHello
• 返回一个非布尔值
getData、getBooks
• 设置内容
setInfo、setData
• 返回一个布尔值
canClicked、hasMoney、isEnabled
构造函数
let fn1 = new Function ('x','y','console.log(\'hi\');return x+y')
函数本身
fn
代码:
let fn = () => console.log('hi')
fn
结果:
不会有结果
因为没有执行
调用函数
fn()
代码:
let fn = () => console.log('hi')
fn()
结果:
打印成hi
由圆括号才是调用
在进一步:
let fn = () =>console.log('hi')
let fn2 = fn
fn2()
结果
fn保存了匿名函数的地址
这个地址被复制给了fn2
fn2()调用了匿名函数
fn和fn2都是匿名函数的引用而已
真正的匿名函数不是fn也不是fn2
函数的要数
- 每个函数都有这些东西
- 调用时机
- 作用域
- 闭包
- 形式参数
- 返回值
- 调用栈
- 函数提升
- arguments(除了箭头函数)
- this(除了箭头函数)
作用域
- 每个函数都会默认创建一个作用域
例1
function fn(){ let a = 1 }
console.log(a) // a
问
是不是fn没有执行
答
就算fn执行了,也访问不到作用域例的a
全局变量vs局部变量
在顶级作用域里面声明的变量是全局变量
window的属性是全局变量
其他都是局部变量
函数可嵌套
作用域也可以嵌套
例2
function f1(){
let a = 1
function f2(){
let a = 2
console.log(a)
}
console.log(a)
a = 3 f2()
}
f1()
作用域规则
如果多个作用域有同名变量a
那么查找a的声明时,就向上取最近的作用域
简称就近原则
查找a的过程与函数的执行无关
但a的值与函数执行有关
闭包
let a = 2
function f3(){
console.log(a)
}
如果一个函数用到了外部的变量
那么这个函数加这个变量
就叫做闭包
左边的a和f3组成了闭包
函数提升
function fn(){}
不管吧具名函数放在哪里,他都会跑到第一行
let fn = function (){}
这是赋值,右边的匿名函数声明不会提升
arguments和this
- arguments 是伪数组
- 不给任何的条件,this默认指向window
- this如果传的时候不加 'use strict',就会把你传的变成对象
- this的用法加fn.call()