ES6常用知识点总结(二)

281 阅读5分钟

「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战」。

大家好,我是L同学,这是我的ES6总结的第二篇文章。本文主要总结了模板字符串函数的默认参数剩余参数展开运算符数值表示等这些知识点。

模板字符串的使用

在ES6之前,我们使用+来拼接字符串和其他变量,这会很麻烦,并且难以阅读。

const name = '哈哈哈'
const age = 18
const height = 1.80 

console.log('my name is ' + name + ', age is ' + age + ', height is ' + height); // my name is 哈哈哈, age is 18, height is 1.8

在ES6中,新增了模板字符串,可以很方便地拼接字符串和其他变量。

const message = `my name is ${name}, age is ${age}, height is ${height}` 
console.log(message); // my name is 哈哈哈, age is 18, height is 1.8

模板字符串允许换行,这对于输出html字符串是十分方便的。如果想要在模板字符串中使用``,可以通过\进行转义。

const str = `hello es2015,
this is a \`string\``
console.log(str);

image.png 另外,在模板字符串中,可以进行简单地计算函数调用

const info = `age double is ${age * 2}`
console.log(info); // age double is 36
function doubleAge() {
  return age * 2
}

const info2 = `double age is ${doubleAge()}`
console.log(info2); // double age is 36

模板字符串的另外一种用法是标签模板字符串。模板字符串的标签就是一个特殊的标签。使用这个标签就是调用这个函数

const str = console.log`hello world`;

image.png 使用标签函数首先要定义标签函数。

这个函数可以接受到一个数组参数,这个数组就是我们模板字符串当中的内容分割出来的结果。这是因为在模板字符串当中可能会有嵌入的表达式,所以这个数组是按照表达式分割过后那些静态的内容。

// 定义标签函数
const name = 'tom'
const gender = false
function myTagFunc(string) {
console.log(string);
}

// 使用标签函数
const result = myTagFunc`hey, ${name} is a ${gender}.`

我们来看下打印结果。

image.png 另外,这个函数除了接收到数组外,还接收到模板字符串中出现的所有表达式的返回值。

function myTagFunc(string, name, gender) {
  console.log(string, name, gender);
}

image.png 这个标签函数的返回值是这个带标签的模板字符串中所对应的返回值

function myTagFunc(string, name, gender) {
  // console.log(string, name, gender);
  return '123'
}

// 使用标签函数
const result = myTagFunc`hey, ${name} is a ${gender}.`
console.log(result);

我们可以看到result的值是标签函数中返回的字符串123。 image.png

function myTagFunc(string, name, gender) {
  // console.log(string, name, gender);
  // return '123'
  return string[0] + name + string[1] + gender + string[2]
}

// 使用标签函数
const result = myTagFunc`hey, ${name} is a ${gender}.`
console.log(result);

image.png 这个标签函数的作用实际上是对模板字符串进行加工,现在打印出来的gender是布尔值,我们在标签函数中对gender进行加工。

function myTagFunc(string, name, gender) {
  // console.log(string, name, gender);
  // return '123'
  // return string[0] + name + string[1] + gender + string[2]
  const sex = gender ? 'man' : 'women'
  return string[0] + name + string[1] + sex + string[2]
}

image.png 通过标签函数我们可以去实现例如文本的多语言化,翻译成中英文,或者检查模板字符串中是否存在不安全的字符,使用这个特性还可以实现小型的模板引擎。

总结一下:

通常我们调用函数通过以下方式👇

function foo(m, n, x) {
  console.log(m, n, x);
}

foo('hello', 'world')

如果我们使用标签模板字符串,并且在调用的时候插入其他的变量,那么得到的结果第一个元素是数组,数组中的元素是被模板字符串拆分的字符串,数组后面的元素是模板字符串传入的内容

const name = 'haha'
const age = 18
foo`hello${name}wo${age}rld` // [ 'hello', 'wo', 'rld' ] haha 18

函数的默认参数

在函数中,如果你不清楚传递过来的参数是否有值,并且你需要在函数中处理传递过来的参数,那么你可以给函数的参数提供默认值

在ES6之前,我们可以通过以下方式给函数的参数赋予默认👇。

function foo(m, n) {
  m = m || 'aaa'
  n = n || 'bbb'
  console.log(m, n);
}

foo('ccc', 'ddd')

这种方法的缺点是写起来比较麻烦,并且代码的阅读性比较差。另一方面,如果我们想要传递0或者是空的字符串'',那么结果不符合我们的预期,会取到默认值。

foo(0, '')

在ES6中,可以给函数的参数提供默认值,解决了之前方案存在的问题✌。

function foo(m = 'aaa', n = 'bbb') {
  console.log(m, n);
}

foo(0, '')

在函数中,默认参数也可以和解构一起使用。如果传递的参数是对象,可以给参数提供默认值并进行解构。

function printInfo({name, age} = {name: 'haha', age: 18}) {
  console.log(name, age);
}

printInfo({name: 'xixi', age: 20})

当然,你也可以在解构的时候提供默认值。

function printInfo1({name = 'hello', age = 18} = {}) {
  console.log(name, age);
}

printInfo1();

函数参数的默认值我们通常会放在最后,函数调用的时候会按照顺序来进行匹配。

function bar(x, y, z = 30) {
  console.log(x, y, z);
}

bar(10, 20)
bar(undefined, 10, 20)

我们可以通过函数名.length来获取参数的个数。要注意的是,函数参数的默认值会改变函数的length个数,默认值以及后面的参数都不计算在length之内了。

function baz(a, b, c) {
    console.log(a, b, c);
}

console.log(baz.length); // 3
function baz(a, b, c = 30) {
    console.log(a, b, c);
}

console.log(baz.length); // 2
function baz(a, b, c = 30, d) {
 console.log(a, b, c, d);
}

console.log(baz.length); // 2

函数的剩余参数

如果我们想要获取调用函数时传递过来的参数,我们可以使用arguments。需要注意的是,arguments是个伪数组

function foo() {
  console.log(arguments);
} 

foo(1, 2, 3, 4)

image.png

在ES6中,可以通过剩余参数来获得不定数量的参数。剩余参数得到的是一个数组。注意,剩余参数必须要放在最后,否则会报Rest parameter must be last formal parameter的错误。并且只能使用一次。

function foo(m, n, ...args) {
  console.log(m, n); // 1 2
  console.log(args);  // [ 3, 4, 5, 6 ]
  console.log(arguments);
}

foo(1, 2, 3, 4, 5, 6)

剩余参数和arguments的区别

  1. 剩余参数只包含那些没有对应形参的实参,而arguments对象包含了传给函数的所有实参。
  2. arguments对象不是一个真正的数组,而剩余参数是一个真正的数组,可以进行数组的所有操作。
  3. arguments是早期的ECMAScript中为了方便获取所有的参数提供的一种数据结构,而剩余参数是ES6中提供并且希望以此来替代arguments。

展开运算符

如果我们想要获取数组中的所有元素,在展开运算符之前,我们通过数组下标去一个个获取。

const arr = ['foo', 'bar', 'baz']
console.log(arr[0], arr[1], arr[2]);

那么如果数组的元素个数不确定呢?我们之前这样解决。

console.log.apply(console, arr)

有了展开运算符,我们可以解决上述问题。

console.log(...arr);

展开运算符还可以在函数调用时、数组构造时、对象字面量构建时使用(ES9添加的新特性)。

函数调用时展开

const names = ['abc', 'cba', 'nba']
const name = 'haha'
const info = {name: 'haha', age: 18}

function foo(x, y, z) {
  console.log(x, y, z);
}

foo(...names)
foo(...name)

构造数组时展开

展开字符串得到的结果是一个个字符。

const newNames = [...names, ...name]
console.log(newNames);

对象字面量构建时展开

const obj = {...info, address: '上海市', ...name}
console.log(obj);

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

const info = {
  name: 'haha',
  friend: {
    name: 'xixi'
  }
}

const obj = {...info, name: 'kaka'}
console.log(obj); // { name: 'kaka', friend: { name: 'xixi' } }

我们可以看到修改了obj对象中的friend中的name值,info对象中的friend中的name也会被修改。所以说,展开运算符其实是一种浅拷贝。

obj.friend.name = 'didi'
console.log(info.friend.name); // didi

数值的表示

const num1 = 100 // 十进制
// b => binary 
const num2 = 0b100 // 二进制
// o => octonary
const num3 = 0o100 // 八进制
// x => hexadecimal
const num4 = 0x100 // 十六进制

console.log(num1, num2, num3, num4); // 100 4 64 256

当数值特别大时,可以用_作为连接符(ES2021 ES12新增特性)

const num = 10_000_000_000_000
console.log(num);

往期文章 👇👇👇

ES6常用知识点总结(一)

一个刚入职的前端程序媛的2021年终总结