函数默认值的补充
◼ 默认值也可以和解构一起来使用:
◼ 另外参数的默认值我们通常会将其放到最后(在很多语言中,如果不放到最后其实会报错的):
但是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>