函数默认值的补充,剩余参数,箭头函数,展开语法,深拷贝浅拷贝

96 阅读3分钟

函数默认值的补充

默认值也可以和解构一起来使用:

另外参数的默认值我们通常会将其放到最后(在很多语言中,如果不放到最后其实会报错的):

 但是JavaScript允许不将其放到最后,但是意味着还是会按照顺序来匹配;

另外默认值会改变函数的length的个数,默认值以及后面的参数都不计算在length之内了。

函数的剩余参数(已经学习)

ES6中引用了rest parameter,可以将不定数量的参数放入到一个数组中:

 如果最后一个参数是 ... 为前缀的,那么它会将剩余的参数放到该参数中,并且作为一个数组;

那么剩余参数和arguments有什么区别呢?

 剩余参数只包含那些没有对应形参的实参,而 arguments 对象包含了传给函数的所有实参;

 arguments对象不是一个真正的数组,而rest参数是一个真正的数组,可以进行数组的所有操作;

 arguments是早期的ECMAScript中为了方便去获取所有的参数提供的一个数据结构,而rest参数是ES6中提供并且希望以此

来替代arguments的;

注意:剩余参数必须放到最后一个位置,否则会报错。

<script>


    // 1.解构的回顾
    // const obj = { name: "why" }
    // const { name = "kobe", age = 18 } = obj


    // 2.函数的默认值是一个对象
    // function foo(obj = { name: "why", age: 18 }) {
    //   console.log(obj.name, obj.age)
    // }


    function foo({ name, age } = { name: "why", age: 18 }) {
      console.log(name, age)
    }


    function foo({ name = "why", age = 18 } = {}) {
      console.log(name, age)
    }


    foo()


  </script>

函数箭头函数的补充

在前面我们已经学习了箭头函数的用法,这里进行一些补充:

 箭头函数是没有显式原型prototype的,所以不能作为构造函数,使用new来创建对象;

 箭头函数也不绑定this、arguments、super参数;

<script>


    // 1.function定义的函数是有两个原型的:
    // function foo() {}
    // console.log(foo.prototype) // new foo() -> f.__proto__ = foo.prototype
    // console.log(foo.__proto__) // -> Function.prototype


    // 2.箭头函数是没有显式原型
    // 在ES6之后, 定义一个类要使用class定义
    var bar = () => {}
    // console.log(bar.__proto__ === Function.prototype)
    // 没有显式原型
    // console.log(bar.prototype)
    // var b = new bar()


  </script>

箭头函数没有显示原型的

展开语法

展开语法(Spread syntax)

 可以在函数调用/数组构造时,将数组表达式或者string在语法层面展开;

 还可以在构造字面量对象时, 将对象表达式按key-value的方式展开;

展开语法的场景:

 在函数调用时使用;

 在数组构造时使用;

 在构建对象字面量时,也可以使用展开运算符,这个是在ES2018(ES9)中添加的新特性;

注意:展开运算符其实是一种浅拷贝;

<script>


    // 1.基本演练
    // ES6
    const names = ["abc", "cba", "nba", "mba"]
    const str = "Hello"


    // const newNames = [...names, "aaa", "bbb"]
    // console.log(newNames)


    function foo(name1, name2, ...args) {
      console.log(name1, name2, args)
    }


    foo(...names)
    foo(...str)


    // ES9(ES2018)
    const obj = {
      name: "why",
      age: 18
    }
    // 不可以这样来使用
    // foo(...obj) // 在函数的调用时, 用展开运算符, 将对应的展开数据, 进行迭代
    // 可迭代对象: 数组/string/arguments


    const info = {
      ...obj,
      height: 1.88,
      address: "广州市"
    }
    console.log(info)


  </script>

浅拷贝深拷贝

<script>


    const obj = {
      name: "why",
      age: 18,
      height: 1.88,
      friend: {
        name: "curry"
      }
    }


    // 1.引用赋值
    // const info1 = obj


    
    // 2.浅拷贝
    // const info2 = {
    //   ...obj
    // }
    // info2.name = "kobe"
    // console.log(obj.name)
    // console.log(info2.name)
    // info2.friend.name = "james"
    // console.log(obj.friend.name)



    // 3.深拷贝
    // 方式一: 第三方库
    // 方式二: 自己实现
    // function deepCopy(obj) {}
    // 方式三: 利用先有的js机制, 实现深拷贝JSON
    const info3 = JSON.parse(JSON.stringify(obj))
    console.log(info3.friend.name)
    info3.friend.name = "james"
    console.log("info3.friend.name:", info3.friend.name)
    console.log(obj.friend.name)


  </script>

数值的表示

◼ 在ES6中规范了二进制和八进制的写法:

◼ 另外在ES2021新增特性:数字过长时,可以使用_作为连接符

<script>


    // 1.进制
    console.log(100)
    console.log(0b100)
    console.log(0o100)
    console.log(0x100)


    // 2.长数字的表示
    const money = 100_00_00_0000_00_00


  </script>