JS函数

129 阅读2分钟

1.定义一个函数(函数是一个对象)

1.具名函数

function  fn(a,b){return a+b}

2.匿名函数(也叫函数表达式)

let fn = function(a,b){return a+b}

3.箭头函数

let fn = (x,y) =>{return x+y}

let fn = (x,y) =>{name:x,age:y};这样直接返回对象有问题,需要加上小括号

let fn = (x,y) =>({name:x,age:y})

4.构造函数

let fn  = new Function('X','Y','return X + Y ')

基本没人用,但是要知道每一个函数都是Function构造出来的

2.函数调用

let fn  = () => console.log('hi')

let fn2 = fn

fn2()

理解:

  • fn保存了匿名函数的地址
  • 这个地址又给复制给fn2
  • fn2()调用了匿名函数
  • fn、fn2都是匿名函数的引用而已
  • 真正的函数既不是fn又不是fn2

3.函数的要素

每个函数都有这些东西:

  • 调用时机
  • 作用域
  • 闭包
  • 形式参数
  • 返回值
  • 调用栈
  • 函数提升
  • arguments(除了箭头函数)
  • this(除了箭头函数)

1.调用时机

时机不同,结果不同

(1)

let a = 1 

function fn(){console.log(a)}

fn()   //1

** (2)**

let a = 1

function fn(){console.log(a)}

a = 3

fn() //3

(3)

let a = 1

fuction fn (){

**    setTimeout(()=>{console.log(a)},0)**

}

fn()

a=2

输出2,因为setTimeout要等这些执行完再调用

2.作用域

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

function fn(){let a = 1}

fn()

console.log(a)

即使调用了也访问不到

3.闭包

一个函数用到的外部的变量,那他就是闭包

4.形式参数

就是非实际参数

形参可认为变量声明

function fn(a,b){return a+b}

相当于

function fn(){

   var a = arguments[0]

   var b = arguments[1]

   return a+b

}

5.返回值

  • 每一个函数都有返回值
  • 函数执行完了才会返回
  • 只有函数有返回值(数字相加的返回,叫做值,不叫返回值)

(1)

function(){

     console.log('hi')

}

fn()

没写return,所以返回值是undefined

(2)

function(){

return console.log('hi')

}

fn()

返回值还是undefined,返回的是console.log('hi')函数的值

6.调用栈

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

7.递归

求阶乘

function(n){

    return  n !== 1  ?  n*fn(n-1)  :  1

}

先递进,在回归

8.函数提升

不管把具名函数放在哪一行,它都会自动到第一行

let fn = function(){};这个不会提升,这是赋值

9.arguments和this

如何传arguments

调用fn函数,即可传arguments

fn(1,2,3),那么arguments就是[1,2,3]伪数组

如何传this

fn.call(xxx,1,2,3)

xxx会自动转换为对象

let perpon = {

  name : 'frank',

  sayHi(){

       console.log(我的名字是+this.name)

  }

}

perpon.sayHi.call(perpon);调用加上call,指向自己

即使没有用到this,也要写call,指向undefined,null也行