# 五.函数

  • 1.函数参数

以前

function spread(x, ...args) {
  sum.apply(null, args)
}
function sum(a, b, c, d) {
  console.log(a, b, c, d)
}
spread("x", 1, 2, 3, 4)
1
2
3
4
5
6
7

现在

function spread(x, ...args) {
  sum(...args)
}
function sum(a, b, c, d) {
  console.log(a, b, c, d)
}
spread("x", 1, 2, 3, 4)
1
2
3
4
5
6
7

# 1. 默认参数

# 2. 展开操作符

# 3. 剩余操作符

# 4. 解构参数

# 5. 函数的名称

# 6. 箭头函数

特点:箭头函数 es6 写起来简单 可以解决 this 问题

  • 1.箭头函数没有 function 的关键字

  • 2.小括号和大括号之间有个箭头

let fn1 = (a) => {
  return a
}
1
2
3
  • 3.如果参数是一个 可以省略小括号
let fn2 = (a) => a
1
  • 4.如果没有 return 可以不写大括号

以前的

function a(c) {
  return function (d) {
    return c + d
  }
}
1
2
3
4
5

现在的

let a = (c) => (d) => c + d
1
  • 5.如果直接返回的是对象类型,需要小括号包裹

以前的

function a(c) {
  return function (d) {
    return { a: c + d }
  }
}
1
2
3
4
5

现在的

let a = (c) => (d) => ({ a: c + d })
1
  • 可以解决 this 问题 看 this 指代的是谁 看前面的.是谁就是谁
let obj = {
  a: function () {
    console.log(this)
  },
}
console.log(obj.a())
1
2
3
4
5
6
  • this 指 obj 本身
let obj = {
  a: function () {
    console.log(this)
  },
}
let fn = obj.a
console.log(fn())
1
2
3
4
5
6
7
  • 指向 windows

  • 1.解决 this 问题 var that =this

let obj = {
  b: 1,
  a: function () {
    let that = this
    setTimeout(function () {
      console.log(that)
    }, 1000)
  },
}
console.log(obj.a())
1
2
3
4
5
6
7
8
9
10
  • 2.通过 bind 方式绑定 this(call,apply)
let obj = {
  b: 1,
  a: function () {
    setTimeout(
      function () {
        console.log(this)
      }.bind(this),
      1000
    )
  },
}
console.log(obj.a())
1
2
3
4
5
6
7
8
9
10
11
12
  • 3.箭头函数 箭头函数没有 this 会向上找
let obj = {
  b: 1,
  a: function () {
    setTimeout(() => {
      console.log(this)
    }, 1000)
  },
}
console.log(obj.a())
1
2
3
4
5
6
7
8
9
  • 指向 obj

  • 4.对象不是作用域 let 声明的也不会被声明到全局上

let obj = {
  b: 1,
  a: () => {
    setTimeout(() => {
      console.log(this)
    }, 1000)
  },
}
console.log(obj.a())
1
2
3
4
5
6
7
8
9
  • 5.let 没有预解释
let a = 1
let obj = {
  a: 2,
  b: () => {
    console.log(this.a)
  },
}
obj.b()
1
2
3
4
5
6
7
8
  • 6.箭头函数中没有 arguments

...叫剩余运算符,就是把多余的都放到数组中

let fn = (x, ...args) => {
  console.log(arguments)
}
fn("x", 1, 2, 3, 4, 5)
1
2
3
4

函数可以赋予默认参数

let fn = (a = 1, b = 2) => {
  console.log(a, b)
}
fn()
1
2
3
4

# 4.箭头函数

//箭头函数中没有arguments
//...叫剩余运算符,就是把多余的都放到数组中
let fn = (x, ...args) => {
  console.log(arguments)
}
fn("x", 1, 2, 3, 4, 5)

//函数可以赋予默认参数
let fn = (a = 1, b = 2) => {
  console.log(a, b)
}
fn()
1
2
3
4
5
6
7
8
9
10
11
12

# 5.展开运算符

//1.剩余运算符
//2.展开运算符
function spread(x, ...args) {
  // sum.apply(null,args)
  sum(...args)
}
function sum(a, b, c, d) {
  console.log(a, b, c, d)
}
spread("x", 1, 2, 3, 4)

// let arr =[1,2,3,4,5].concat([6,7,8])
let arr = [...[1, 2, 3, 4, 5], ...[5, 6, 7]]
console.log(arr)

// Math.min(1,2,3,4)
Math.min(...[1, 2, 3, 4])

//...是浅拷贝
let name = { name: "zpx" }
let age = { age: 9 }
let school = { ...name, ...age }
console.log(school)

//slice是浅拷贝 如果拷贝一层就是深拷贝
//...也是浅拷贝
let b = [1, 2, 3, 4]
let a = [b]
let c = a.slice(0)
b[0] = 100
console.log(c)

//深拷贝的实现
let obj = { a: 1 }
console.log(JSON.parse(JSON.stringify(obj)))
//只针对JSON如果不是,就不显示 function 正则不认

//实现深拷贝 保留继承关系 可以实现各种类型的拷贝 实现递归拷贝
function deepClone(obj) {
  if (typeof obj !== "object") return obj
  if (obj == null) return null
  if (obj instanceof Date) return new Date(obj)
  if (obj instanceof RegExp) return new RegExp(obj)
  Object.prototype.toString.call(obj) === "[object Array]"
  let o = new obj.constructor() //保留类的继承关系
  for (let key in obj) {
    o[key] = typeof obj[key] === "object" ? deepClone(obj[key]) : obj[key]
  }
}
let o = { a: { a: 1 } }
let newObj = deepClone(o)
o.a.a = 2
console.log(newObj)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53