ES6学习记录

推荐:ES6 入门教程

let 和 const

let

  • let用于声明变量,声明的变量是局部的只在对应的代码块(代码块就是一对大括号内的代码)里有效,在代码块外使用会报错。var声明的变量全局有效
  • let不存在变量提升,定义了之后才可以使用,否则报错;var存在变量提升,可以在声明前使用,默认undefined
  • 在同一个作用域(代码块)里不允许重复声明同一个变量

const
const用于定义常量,常量定义后不允许修改,修改会报错。

解构赋值

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构

数组

let [a, b, c] = [1, 2, 3];
// a:1		b:2	c:3

对象

let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"

默认值

数组和对象的解构可以设置默认值

let [a,b=5]=[1]   // a:1,b:5
let {a,b=5}={a:1}  // a:1,b:5

字符串解构

字符串也具有length属性,可以以数组的形式使用,因此字符串也可以解构

let str="abc"
str[0]:'a'
let [a,b,c]=str

函数参数的解构

如果函数的参数是数组或对象时,参数也可以解构

function add([x, y]){
  return x + y;
}

add([1, 2]); // 3
[[1, 2], [3, 4]].map(([a, b]) => a + b);
// [ 3, 7 ]
function move({x = 0, y = 0} = {}) {
  return [x, y];
}

move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]

字符串新增方法

includes()

字符串中包含子串返回true,不包含返回false

"abc".includes('d')   //false

startsWith

字符串是否以指定字串开头,返回true或false

"abc".startsWith('a')  //true

endsWith

字符串是否以指定字串结尾,返回true或false

"abc".endsWith('a')    //false

repeat

repeat方法返回一个新字符串,表示将原字符串重复n次

'*'.repeat(5)    // '*****'
'*'.repeat()'*'.repeat(0)   // ''

padStart(),padEnd()

如果某个字符串不够指定长度,会在头部或尾部补全。padStart()用于头部补全,padEnd()用于尾部补全。默认以空格补全

''.padStart(5,'*')   // '*****'
''.padEnd(5)   // '     '

数值新增方法

isFinite()

判断数值是否是有限的,有限返回true

Number.isFinite(5)        //true

Number.isNaN()

判断数值是否是NaN

Number.parseInt()

取整

Number.parseInt(1.5)   //1
Number.parseInt('1.5')  // 1
Number.parseInt('1.5a')  //1

Number.parseFloat()

转实数类型

Number.isInteger()

判断是否是整数

Number.isInteger(1.2)    //false
Number.isInteger('a')  // false

Math.trunc()

去除一个数的小数部分,返回整数部分。对于非数值,Math.trunc内部使用Number方法将其先转为数值。对于空值和无法截取整数的值,返回NaN。

Math.trunc('1.2')    // 1
Math.trunc('1.2q')   //  NaN 

Math.sign()

判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值。
返回值:正数返回1,负数返回-1,0返回0,-0返回-0,其他值返回NaN

Math.sign(2)    //  1
Math.sign(-0)  // -0

Math.cbrt()

计算一个数的立方根

Math.cbrt(-8)    // -2

Math.hypot()

返回所有参数的平方和的平方根。

Math.hypot(3, 4);        // 5
Math.hypot(3, 4, 5);     // 7.0710678118654755

函数的扩展

尾调用
某个函数的最后一步是调用另一个函数,如下

function f(x){
  return g(x);
}

以下三种情况,都不属于尾调用。

// 情况一
function f(x){
  let y = g(x);
  return y;
}

// 情况二
function f(x){
  return g(x) + 1;
}

// 情况三
function f(x){
  g(x);
}

情况三等价于:

function f(x){
  g(x);
  return undefined
}

尾调用不一定出现在函数尾部,只要是最后一步操作即可。

function f(x) {
  if (x > 0) {
    return m(x)
  }
  return n(x);
}

尾递归

函数调用自身,称为递归。如果尾调用自身,就称为尾递归。递归非常耗费内存,因为需要同时保存成千上百个调用帧,很容易发生“栈溢出”错误(stack overflow)。但对于尾递归来说,由于只存在一个调用帧,所以永远不会发生“栈溢出”错误。

实例:递归求100的阶乘

//a.js
function factorial(n) {
  if (n == 1) return 1;
  return n * factorial(n - 1);
}

console.time("factorial");
let result = factorial(100);
console.log("结果:", result);
console.timeEnd("factorial");
//b.js
function factorial(n, total = 1) {
  if (n == 1) return total;
  return factorial(n - 1, n * total);
}

console.time("factorial");
let result = factorial(100);
console.log("结果:", result);
console.timeEnd("factorial");

在这里插入图片描述

数组的扩展

扩展运算符

  • 复制数组,使用扩展运算符是克隆一个全新的数组,而不是复制里对应的指针
let a=[1,2]
let b=[...a]
  • 合并数组
let a=[1,2]
let b=[3,4]
let c=[...a,...b]
  • 字符串,可以将字符串转为真正的数组
[...'hello']
// [ "h", "e", "l", "l", "o" ]
  • 与解构赋值结合
let [first, ...rest] = [1, 2, 3, 4, 5];

Array.from()

  • 将类数组对象转为数组
let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c'
};
let arr = Array.from(arrayLike); // ['a', 'b', 'c']
  • Array.from还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。
Array.from(arrayLike, x => x * x);
// 等同于
Array.from(arrayLike).map(x => x * x);
  • 转换本质特征只有一点,即必须有length属性。因此,任何有length属性的对象 ,都可以通过Array.from方法转为数组
Array.from({ length: 3 },()=>'a');
 ['a', 'a', 'a']

//取出dom节点的文本内容
let names = Array.from(spans, s => s.textContent)

Array.of()

返回参数值组成的数组。如果没有参数,就返回一个空数组。

Array.of() // []
Array.of(undefined) // [undefined]
Array.of(1) // [1]
Array.of(1, 2) // [1, 2]

数组实例的 fill()

['a', 'b', 'c'].fill(7)
// [7, 7, 7]

new Array(3).fill(7)
// [7, 7, 7]

fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。

['a', 'b', 'c'].fill(7, 1, 2)
// ['a', 7, 'c']

数组实例的 flat(),flatMap()

数组的成员有时还是数组,Array.prototype.flat()用于将嵌套的数组“拉平”,变成一维的数组。该方法返回一个新数组,对原数据没有影响。

//原数组的成员里面有一个数组
[1, 2, [3, [4, 5]]].flat()
// [1, 2, 3, [4, 5]]

//拉平两层
[1, 2, [3, [4, 5]]].flat(2)

//不确定多少层
[1, [2, [3]]].flat(Infinity)

flatMap()方法对原数组的每个成员执行一个函数(相当于执行Array.prototype.map()),然后对返回值组成的数组执行flat()方法。该方法返回一个新数组,不改变原数组。

[1,[2]].flatMap(x=>[x,x*x])
//[1,1,[2],4]

该方法只能展开一层

对象新增方法

Object.assign(a,b,c)

对象的合并,第一个参数是目标对象,后面的参数是源对象。会将源对象中所有可枚举属性复制到目标对象。
如果目标对象与源对象有同名的属性,则后面的属性会覆盖前面的属性。

实例:默认配置a={id:1,name:'aaa'} ,修改默认配置的某一个值

let c=Object.assign({id:1,name:'aaa'},{id:2})
//{id: 2, name: 'aaa'}

Object.keys()

返回一个数组,数组的元素是对象的键名

Object.values()

返回一个数组,数组的元素是对象的键值

**Object.entries() **

返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历属性的键值对数组。

const obj = { foo: 'bar', baz: 42 };
Object.entries(obj)
// [ ["foo", "bar"], ["baz", 42] ]

Object.fromEntries()
Object.entries()的逆操作,用于将一个键值对数组转为对象。

set 和 map

set 类似于数组,但是成员的值都是唯一的,没有重复值

let a = new Set([1,2,3,1])
//结果是类对象,可以通过扩展运算符或Array.form转成数组
[...a] 或 Array.from(a)  //[1,2,3]

该方法也可以用于去除字符串里的重复字符

[...new Set('ababbc')].join('')
// "abc"

实例方法:

  • size():返回set实例的成员总数
  • add(value):往set对象中添加某个值
  • delete(value):删除某个值,返回一个布尔值,标识删除是否成功
  • has(value):返回一个布尔值,表示该值是否为set的成员
  • clear(value):清除所有成员,没有返回值

遍历操作:

  • keys()
  • values()
  • entries()
  • forEach

map:类似于对象,也是键值对的集合,但是键的范围不限于字符串

  • 如果对同一个键多次赋值,后面的值会覆盖前面的值
  • map的构造函数可以接受数组作为参数
let form=new Map([['name','张三']])
form.get('name')    //张三
  • map对象可以使用set方法添加值,通过get方法获取值。size、has、delete、clear与set类似
  • 遍历方式与set相同

async和await

async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。

async function getStockPriceByName(name) {
  const symbol = await getStockSymbol(name);
  const stockPrice = await getStockPrice(symbol);
  return stockPrice;
}

getStockPriceByName('goog').then(function (result) {
  console.log(result);
});

async 函数有多种使用形式。

// 函数声明
async function foo() {}

// 函数表达式
const foo = async function () {};

// 对象的方法
let obj = { async foo() {} };
obj.foo().then(...)

// Class 的方法
class Storage {
  constructor() {
    this.cachePromise = caches.open('avatars');
  }

  async getAvatar(name) {
    const cache = await this.cachePromise;
    return cache.match(`/avatars/${name}.jpg`);
  }
}

const storage = new Storage();
storage.getAvatar('jake').then();

// 箭头函数
const foo = async () => {};

返回Promise对象

async函数返回一个 Promise 对象。
async函数内部return语句返回的值,会成为then方法回调函数的参数。

async function f() {
  return 'hello world';
}

f().then(v => console.log(v))
// "hello world"

await命令
正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。

async function f() {
  // 等同于
  // return 123;
  return await 123;
}

f().then(v => console.log(v))
// 123

注意:

  • 运行结果可能是rejected,最好把await命令放在try…catch代码块中。
async function myFunction() {
  try {
    await somethingThatReturnsAPromise();
  } catch (err) {
    console.log(err);
  }
}

// 另一种写法

async function myFunction() {
  await somethingThatReturnsAPromise()
  .catch(function (err) {
    console.log(err);
  });
}
  • 多个await命令后面的异步操作,如果不存在依赖关系,最好同时触发
// 写法一
let [foo, bar] = await Promise.all([getFoo(), getBar()]);

// 写法二
let fooPromise = getFoo();
let barPromise = getBar();
let foo = await fooPromise;
let bar = await barPromise;
  • await命令只能用在async函数之中,如果用在普通函数,就会报错。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无知的小菜鸡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值