ES6 学问整顿一(es6疾速入门)

ES6 简介

ES6, 全称 ECMAScript 6.0 ,是 JavaScript 的下一个版本规范,2015.06 发版。

let 和 const

let 敕令

let 敕令,用来声明变量。它的用法相似于 var,区分在于 var 声明的变量全局有用,let 声明的变量只在它地点的代码块内有用。

// 变量i贮存的值是10,所以实行a[2]()后输出10
var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[2](); // 10


// 修改要领
// 闭包会使得函数中的变量都被保存在内存中,所以实行a[2]()后输出2
var a = [];
for (var i = 0; i < 10; i++) {
    (function (i) {
        a[i] = function () {
            console.log(i)
        }
    })(i);
}
a[2](); // 2

// es6
// let声明的i只在当前的代码块有用,所以每次for轮回相当于用let从新声明一次i
var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[2](); // 2

// 注:JavaScript 引擎内部会记住上一轮轮回的值,初始化本轮的变量i时,就在上一轮轮回的基础上举行盘算。

let 不存在变量提拔,必须先声明后运用,不然报错;var 存在变量提拔,未声明前运用输出 undefined。

let 存在暂时性死区,在代码块内,运用 let 敕令声明变量之前,该变量都是不可用的。

let 不许可反复声明。

const 敕令

const 声明一个只读的常量。一旦声明,常量的值就不能转变。不能只声明不赋值。

const a = 10;
a = 20; // 报错

const b; // 报错

const 的作用域与 let 雷同。

if(true) {
  const num = 5;
}
console.log(num); // 报错

const 声明对象,常量对象内存地点,因而对象本身可改,然则给常量从新赋值就会报错。

const obj = {};
obj.a = 'a';

obj = {}; // 报错

块级作用域和函数作用域

ES5 划定,函数只能在顶层作用域和函数作用域当中声明,不能在块级作用域声明。然则在 ES6 中,函数能够在块级作用域中声明。然则,市面上许多浏览器都不支撑 ES6,所以应当防备在块级作用与中声明函数。

ES6 声明变量的要领

  • var
  • function
  • let
  • const
  • import
  • class

变量的解构赋值

ES6 许可根据肯定情势,从数组和对象中提取值,对变量举行赋值,这被称为解构(Destructuring)。

数组的解构赋值

情势婚配赋值,假如解构不成功,变量的值就即是 undefined。

let [a, [[b], c]] = [1, [[2], 3]];
console.log(a,b,c); // 1, 2, 3

let [x, , y, z] = [1, 2, 3];
console.log(x); // 1
console.log(y); // 3
console.log(z); // undefined

不完整解构赋值,等号左侧的情势,只婚配一部份的等号右侧的数组。

let [x, [y], z] = [1, [2, 3], 4];
console.log(x); // 1
console.log(y); // 2
console.log(z); // 4

数组组织赋值右侧必须是数组,情势不婚配则报错。

let [a]  = {}; // 报错

解构赋值能够增加默许值,而且能够援用解构赋值的其他变量。

let [a = 1, b = 2] = [, 3];
console.log(a); // 1
console.log(b); // 3

let [x = 1, y = x] = [];  // x = 1; y = 1
let [x = 1, y = x] = [2]; // x = 1; y = 2

数组解构赋值可用于交流变量的值。

let [a, b] = [1, 2];
console.log(a, b); // 1, 2
[b, a] = [a, b];
console.log(a, b); // 2, 1

对象的解构赋值

变量必须与属性同名

let { a, b, c } = { a: 'aaa', b: 'bbb' };
console.log(a); // 'aaa'
console.log(b); // 'bbb'
console.log(c); // undefined

变量名与属性名不一致

let { a: x, b: y } = { a: 'aaa', b: 'bbb' };
console.log(x); // 'aaa'
console.log(y); // 'bbb'

嵌套赋值,假如子对象地点的父属性不存在,会报错,慎用。

let { a, a: {x}, b: y } = { a: {x: 'xxx',y: 'yyy'}, b: "bbb" };
console.log(a); // { x: 'xxx', y: 'yyy' }
console.log(x); // 'xxx'

let {c: {d: {e}}} = {c: 'ccc'}; // 报错
console.log(e)

变量解构赋值也和数组的解构赋值一样,能够赋默许值,变量解构赋值时,不能将大括号写在行首,否者 JavaScript 引擎将会按代码块实行。

let x;
{x} = {x: 1}; // 报错

// 准确写法
let x;
({x} = {x: 1});

字符串解构赋值

字符串解构赋值,将字符串转化成数组对象

const [a,b,c] = '123456789';
const {length} = '123456789';
console.log(a, b, c, length); // 1, 2, 3, 9

函数解构赋值

const arr = [[1, 2], [3, 4]].map(([a, b]) => a + b);
console.log(arr); // [ 3, 7 ]

解构赋值划定规矩

解构赋值的划定规矩是,只需等号右侧的值不是对象或数组,就先将其转为对象。由于 undefined 和 null 没法转为对象,所以对它们举行解构赋值,都邑报错。

let {toString: n} = 123;
n === Number.prototype.toString // true

let {toString: b} = true;
b === Boolean.prototype.toString // true

let { prop: u } = undefined; // 报错
let { prop: n } = null; // 报错

解构赋值的用处

  • 交流变量的值
  • 从对象、数组中取值(提取 JSON 数据),或从函数中返回多个值
  • 函数解构赋值传参,给定函数参数的默许值
  • 输入模块的指定要领
  • 遍历 Map 组织
const map = new Map();
map.set('first', 'hello');
map.set('second', 'world');

for (let [key, value] of map) {
  console.log(key + ' is ' + value);
}
// first is hello
// second is world

字符串扩大(不含编码)

for…of 遍历字符串

for(let codePoint of 'string'){
  console.log(codePoint)
}
// 's'
// 't'
// 'r'
// 'i'
// 'n'
// 'g'

includes(),startsWith(),endsWith()

三个要领都吸收两个参数,第一个参数为检索的值,第二个参数为检索的肇端位置,返回布尔值

let s = 'Hello world!';

const [a, b, c] = [
    s.startsWith('Hello', 2),
    s.endsWith('!'),
    s.includes('o w')
];

console.log(a, b, c); // false true true

repeat()

repeat 要领返回一个新字符串,示意将原字符串反复 n 次。

  • 参数为[-Infinity,-1]或许 Infinity,会报错;
  • 参数为(-1,1)时,相当于参数为 0;
  • 参数为小数时向下取整;
  • 参数 NaN 等同于 0;
  • 参数是字符串,则会先转换成数字。
'str'.repeat('3') // 'strstrstr'

padStart(), padEnd()

padStart(),padEnd()有两个参数,第一个参数为字符串补全见效的最大长度,第二个参数为补全的字符串。

第二个参数默以为空格,省略第二个参数时默许用空格补全。

第一个参数小于字符串原长度时,返回原字符串。

假如用来补全的字符串与原字符串,二者的长度之和超过了最大长度,则会截去超越位数的补全字符串。

罕见用处:补全指定位数,提醒字符串花样。

'123456'.padStart(10, '0') // "0000123456"
'09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"

模版字符串(“)

const str = 'world';
const template = `Hello ${str}`;
console.log(template); // Hello world

正则扩大(略)

数值扩大

二进制、八进制示意法

运用二进制示意法,前缀为 0b,运用八进制示意法,前缀为 0o,ES6 不支撑运用 00 前缀示意八进制。

进制转换运用 toString 要领,运用 Number 要领直接转十进制。

0b1100100 === 100; // true
0o144 === 100; // true

(0b1100100).toString(8); // 144
(0b1100100).toString(10); // 100
Number('0b1100100'); // 100

Number.isFinite(),Number.isNaN()

Number.isFinite()用来搜检一个数值是不是为有限的(finite),即不是 Infinity。参数范例不是数值,Number.isFinite 一概返回 false。

Number.isNaN()用来搜检一个值是不是为 NaN。参数范例不是 NaN,Number.isNaN 一概返回 false。

Number.isFinite(15); // true
Number.isFinite(-Infinity); // false

Number.isNaN(15) // false
Number.isNaN(9/0) // true

Number.parseInt(), Number.parseFloat()

ES6 将全局要领 parseInt()和 parseFloat(),移植到 Number 对象上面,行动完整坚持稳定。

Number.isInteger()

Number.isInteger()用来推断一个数值是不是为整数。

Number.isInteger(25) // true
Number.isInteger(25.0) // true
Number.isInteger(25.1) // false

ES6 新增 Number 常量

  • Number.EPSILON 极小常量,浮点数偏差小于这个值能够以为不存在偏差;
  • Number.MAX_SAFE_INTEGER 平安整数的最大局限;
  • Number.MIN_SAFE_INTEGER 平安整数的最小局限;

Number.isSafeInteger() 用来推断一个整数是不是落在平安整数局限以内。

Number.isSafeInteger(9007199254740993) // false
Number.isSafeInteger(990) // true
Number.isSafeInteger(9007199254740993 - 990) // true

Math 对象的扩大

Math.trunc() 撤除一个数的小数部份,返回整数部份。参数不是数值,内部会先挪用 Nunber()专为数值,关于空值和没法截取整数的值,返回 NaN。(Math 对象的扩大的要领关于非数值的处置惩罚要领都一样)

Math.trunc(5.9) // 5
Math.trunc(-4.9) // -4
Math.trunc(null) // 0
Math.trunc('foo'); // NaN

Math.sign() 推断一个数是正数、负数、照样零。

Math.sign(-5) // -1 负数
Math.sign(5) // +1 正数
Math.sign(0) // +0 零
Math.sign(-0) // -0 零
Math.sign(NaN) // NaN

Math.cbrt() 盘算一个数的立方根。

Math.cbrt(2)  // 1.2599210498948734

// Math.sqrt(x) 盘算平方根
Math.sqrt(2) // 1.4142135623730951

// 幂运算 Math.pow(x,y)
Math.pow(2, 3)

Math.hypot() 返回一切参数的平方和的平方根。

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

函数扩大

rest 参数

ES6 引入 rest 参数(情势为…变量名),用于猎取函数的过剩参数,rest 参数搭配的变量是一个数组,该变量将过剩的参数放入数组中。只能是末了一个参数,函数的 length 属性,不包括 rest 参数。

function sum1(x, y, ...args) {
    let sum = 0;

    for (let arg of args) {
        sum += arg;
    }

    return sum;
}

console.log(sum1(1, 2, 3, 4)) // 7

function sum2(...args) {
    return args.reduce((prev, curr) => {
        return prev + curr
    }, 0)
}

console.log(sum2(1, 2, 3)); // 6

name 属性

函数的 name 属性,返回该函数的函数名。关于匿名函数,ES5 返回”,ES6 返回变量名;
Function 组织函数返回的函数实例,name 属性的值为 anonymous;bind 返回的函数,name 属性值会加上 bound 前缀。

function fn() {}
fn.name // 'fn'

function foo() {};
foo.bind({}).name // 'bound foo'

(function(){}).bind({}).name // 'bound '

箭头函数

const fn = v => v;

// 等同于
const fn = function (v) {
  return v;
};

注重要点

  • 函数体内的 this 对象,就是定义时地点的对象,而不是运用时地点的对象;
  • 不能够看成组织函数,即不能够运用 new 敕令,不然会抛出一个毛病;
  • 不能够运用 arguments 对象,该对象在函数体内不存在。假如要用,能够用 rest 参数替代;
  • 不能够运用 yield 敕令,因而箭头函数不能用作 Generator 函数。

尾挪用优化

尾挪用指函数的末了一步是挪用另一个函数。

function f(x){
  'use strict';
  return g(x);
}

函数挪用会在内存构成一个“挪用纪录”,又称“挪用帧”(call frame),保存挪用位置和内部变量等信息。假如在函数 A 的内部挪用函数 B,那末在 A 的挪用帧上方,还会构成一个 B 的挪用帧。比及 B 运转完毕,将效果返回到 A,B 的挪用帧才会消逝。假如函数 B 内部还挪用函数 C,那就另有一个 C 的挪用帧,以此类推。一切的挪用帧,就构成一个“挪用栈”(call stack)。

尾挪用由于是函数的末了一步操纵,所以不需要保存外层函数的挪用帧,由于挪用位置、内部变量等信息都不会再用到了,只需直接用内层函数的挪用帧,庖代外层函数的挪用帧就能够了,如许能够防备内存溢出,杀青尾挪用优化。

ES6 的尾挪用优化只在严厉情势下开启,一般情势是无效的。

数组扩大

扩大运算符

扩大运算符(spread)是三个点(…)。它比如 rest 参数的逆运算,将一个数组转为用逗号分开的参数序列。

const arr = [1, 2, 3];
arr.push(...[4, 5, 6]);

扩大运算符的运用

  • 数组睁开
const arr = [1, 2, 3];
...arr // 1, 2, 3
  • 复制数组
const a1 = [1, 2];
// 写法一
const a2 = [...a1];
// 写法二
const [...a2] = a1;

// 相当于
const a1 = [1, 2];
const a2 = a1.concat();
  • 兼并数组。浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针举行拷贝,而且对指针指向的内容举行拷贝,经深拷贝后的指针是指向两个差别地点的指针。以下的两种要领属于浅拷贝,假如修改了原数组的成员,会同步反应到新数组。
const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];

// ES5 的兼并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]

// ES6 的兼并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]
  • 解构赋值,字符串转数组
const list = [1, 2, 3];
[a, ...b] = list;
console.log(a) // 1
console.log(b) // [2, 3]

[...'hello'] // ['h', 'e', 'l', 'l', 'o']

Array.from()

Array.from 要领用于将两类对象转为真正的数组:相似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据组织 Set 和 Map)。

罕见的相似数组的对象有 DOM 操纵返回的 NodeList 鸠合,以及函数内部的 arguments 对象。

let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
};

// ES5的写法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']

// ES6的写法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']

Array.from('hello');
// ['h', 'e', 'l', 'l', 'o']

let namesSet = new Set(['a', 'b']);
Array.from(namesSet); // ['a', 'b']

Array.from 还能够接收第二个参数,作用相似于数组的 map 要领,用来对每一个元素举行处置惩罚,将处置惩罚后的值放入返回的数组。

let arrayLike = {
    '0': 1,
    '1': 2,
    '2': 3,
    length: 3
};
Array.from(arrayLike, x => x * x); // [ 1, 4, 9 ]

Array.of()

Array.of 要领用于将一组值,转换为数组。这个要领的重要目的,是填补数组组织函数 Array()的不足。由于参数个数的差别,会致使 Array()的行动有差别。

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

copyWithin()

参数:

  • target(必须):从该位置最先替代数据。假如为负值,示意倒数。
  • start(可选):从该位置最先读取数据,默以为 0。假如为负值,示意倒数。
  • end(可选):到该位置前住手读取数据,默许即是数组长度。假如为负值,示意倒数。

这三个参数都应当是数值,假如不是,会自动转为数值。

[1, 2, 3, 4, 5].copyWithin(0, 3)

find() 和 findIndex()

数组实例的 find 要领,用于找出第一个相符前提的数组成员,假如没有相符前提的成员,则返回 undefined。

findIndex 要领返回第一个相符前提的数组成员的位置,假如一切成员都不相符前提,则返回-1。

[1, 4, -5, 10].find(n => n < 0); // -5
[1, 4, -5, 10].findIndex(n => n < 0); // 2

两个要领都能够接收第二个参数,用来绑定回调函数的 this 对象。

function f(v){
  return v > this.age;
}
let person = {name: 'John', age: 20};
[10, 12, 26, 15].find(f, person);  // 26

这两个要领都能够发明 NaN,填补了数组的 indexOf 要领的不足。

fill() 添补数组

fill 要领运用给定值,添补一个数组。fill 要领能够接收第二个和第三个参数,用于指定添补的肇端位置和完毕位置。假如添补的范例为对象,那末被赋值的是同一个内存地点的对象,而不是深拷贝对象,转变数组中的一项,则一切项都转变。

let arr = Array.of(1, 2, 3).fill({
    num: 20
});

console.log(arr); // [ { num: 20 }, { num: 20 }, { num: 20 } ]

arr[0].num = 10;
console.log(arr); // [ { num: 10 }, { num: 10 }, { num: 10 } ]

entries(),keys() 和 values() 遍历数组

for (let index of ['a', 'b'].keys()) {
  console.log(index);
}
// 0
// 1

for (let elem of ['a', 'b'].values()) {
  console.log(elem);
}
// 'a'
// 'b'

for (let [index, elem] of ['a', 'b'].entries()) {
  console.log(index, elem);
}
// 0 "a"
// 1 "b"

includes()

includes 要领返回一个布尔值,示意某个数组是不是包括给定的值,与字符串的 includes 要领相似。该要领的第二个参数示意搜刮的肇端位置,第二参数是负数,取它的倒数,第二参数大于数组长度,取 0。

[1, 2, 3].includes(3, -1); // true

flat(),flatMap()

flat()默许只会“拉平”一层,假如想要“拉平”多层的嵌套数组,能够将 flat()要领的参数写成一个整数,示意想要拉平的层数,默以为 1。

flat()的参数为 2,示意要“拉平”两层的嵌套数组。假如不论有若干层嵌套,都要转成一维数组,能够用 Infinity 关键字作为参数。

[1, [2, [3]]].flat(Infinity);
// [1, 2, 3]

flatMap()先遍历数组,再“拉平”一层,也只能拉平一层。参数鱼 map()要领相似。
ß

[2, 3, 4].flatMap(x => [x, x * 2]); // [2, 4, 3, 6, 4, 8]

// 相当于
[2, 3, 4].map(x => [x, x * 2]).flat(); // [2, 4, 3, 6, 4, 8]

对象扩大

属性简约示意法

const a = 1;
const b = 2;

const c = {a, b};
// 等同于
const c = {a: a, b: b};

const o = {
  method() {
    return "Hello!";
  }
};
// 等同于
const o = {
  method: function() {
    return "Hello!";
  }
};

function f(x, y) {
  return {x, y};
}
// 等同于
function f(x, y) {
  return {x: x, y: y};
}

对象的扩大运算符

对象扩大符相似数组扩大符,重要用于解构赋值。

let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 2
z // { a: 3, b: 4 }

let ab = { ...a, ...b };
// 等同于
let ab = Object.assign({}, a, b);

Object.is()

Object.is就是布置这个算法的新要领。它用来比较两个值是不是严厉相称,与严厉比较运算符(===)的行动基础一致。

Object.is('str', 'str'); // true
Object.is({}, {}); // false

差别之处只要两个:一是+0不即是-0,二是NaN即是本身。

+0 === -0 //true
NaN === NaN // false

Object.is(+0, -0) // false
Object.is(NaN, NaN) // true

Object.assign()

Object.assign要领用于对象的兼并,将源对象(source)的一切可罗列属性,复制到目的对象(target)。

Object.assign要领的第一个参数是目的对象,背面的参数都是源对象。假如目的对象与源对象有同名属性,或多个源对象有同名属性,则背面的属性会掩盖前面的属性。

由于undefined和null没法转成对象,所以假如它们作为首参数,就会报错。

const target = { a: 1, b: 1 };

const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };

Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

罕见用处:

  • 为对象增加属性和要领
  • 克隆或兼并对象
  • 给属性指定默许值

其他

本文参考《ECMAScript 6 入门》,相识更多请点击跳转点击跳转

    原文作者:欧西里斯的天秤
    原文地址: https://segmentfault.com/a/1190000018481000
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞