ES6

一 ES6简介
1.ES6是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言
2.ES6 与 ECMAScript 2015 的关系
ES6 既是一个历史名词,也是一个泛指,含义是 5.1 版以后的 JavaScript 的下一代标准,涵盖了 ES2015、ES2016、ES2017 等等,而 ES2015 则是正式名称,特指该年发布的正式版本的语言标准。
3.Babel 转码器
Babel 是一个广泛使用的 ES6 转码器,可以将 ES6 代码转为 ES5 代码,从而在老版本的浏览器执行。这意味着,你可以用 ES6 的方式编写程序,又不用担心现有环境是否支持

// 转码前
input.map(item => item + 1);

// 转码后
input.map(function (item) {
  return item + 1;
});

二 let 和 const 命令
1.ES6 新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。

{
  let a = 10;
  var b = 1;
  console.log(a);  //10
}
 console.log(a);  //undefined
console.log(b);  // 1 

2.let 不存在变量提升,let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。

console.log(a); // 输出undefined
var a = 2;
// let 的情况
console.log(b); // 报错ReferenceError
let b = 2;

3.暂时性死区
只要块级作用域内存在let命令,它所声明的变量就“绑定”这个区域,不再受外部的影响。
在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。

var num = 111;
if(num<122){
	num = 122;
	let num;
	console.log(num); // Cannot access 'num' before initialization
}

4.不允许重复声明

function creat() {
  let a = 10;
  var a = 1;
  console.log(a); // 报错'a' has already been declared
}

function creat() {
  let a = 10;
  let a = 1;
  console.log(a); // 报错'a' has already been declared
} 
// 不能在函数内部重新声明参数。
function creat(a ) {
  let a = 10;
  console.log(a); // 报错'a' has already been declared
}
creat();
//正确写法
function creat(a) {
  console.log(a);  //6
  {
    let a =5;
	// console.log(a);  //5
  }
}
creat(6);

5.const 命令
const声明一个只读的常量。一旦声明,常量的值就不能改变。

const a = 323;
console.log(a);  //323
//声明的常量不能 修改
a = 500;
console.log(a);  //TypeError: Assignment to constant variable.

const的作用域与let命令相同:只在声明所在的块级作用域内有效。
const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。

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

//不能重复声明
let name = 'rose';
let age  = 25;

const name = 'lisa';
const age  = 23;

三 变量的解构赋值
1.变量赋值

 //以前的写法 
  let a = 1;
  let b = 2;
  let c = 3;
// ES6 允许写成下面这样。
  let [a, b, c] = [1, 2, 3];

2.数组解构

 let [a, [[b], c]] = [1, [[2], 3]]; 
	a //1
	b //2 
	c //3
  
  let [ , , 1] = ["a", "b", "c"];  
  c //1
 
  let [x, , y] = [1, 2, 3];
  x // 1
  y // 3
  
  let [head, ...tail] = [1, 2, 3, 4];
  head // 1
  tail // [2, 3, 4]
  
  let [x, y, ...z] = ['a'];
  x // "a"
  y // undefined
  z // [] 

如果解构不成功,变量的值就等于undefined。

  let [a] = []; // undefined
  let [a, b] = [1]; // undefined

2.对象的解构赋值

let { a, b} = { a: 'aaa', b: 'bbb' };
a// "aaa"
b// "bbb"

3.字符串的解构赋值

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

4.函数参数的解构赋值

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

add([1, 2]); // 3

5.扩展运算符

 ...扩展运算符
  function foo(a,b,c,d,e,f){
 	 console.log(a+b+c+d+e+f);
 }
 let arr=[1,2,3,4,5,6];
 foo(...arr);

6.rest 剩余参数

  function foo(a,b,...rest){
	 console.log(rest)  //345
  }
 foo(1,2,3,4,5);

四 字符串的扩展
1.字符串的遍历器接口

  for (let ele of 'hello') {
    console.log(ele)
  }
// h
//e
//l
//l
//o

2.JSON.stringify() 的改造
根据标准,JSON 数据必须是 UTF-8 编码。但是,现在的JSON.stringify()方法有可能返回不符合 UTF-8 标准的字符串
为了确保返回的是合法的 UTF-8 字符,ES2019 改变了JSON.stringify()的行为。如果遇到0xD800到0xDFFF之间的单个码点,或者不存在的配对形式,它会返回转义字符串,留给应用自己决定下一步的处理。

JSON.stringify('\u{D834}') // ""\\uD834""
JSON.stringify('\uDF06\uD834') // ""\\udf06\\ud834""

3.模板字符串
模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。

// 字符串中嵌入变量
	let name = "lisa", time = "today";
console.log(`Hello ${name}, how are you ${time}?`)  //Hello lisa, how are you today?

模板字符串,都是用反引号表示。如果在模板字符串中需要使用反引号,则前面要用反斜杠转义。

let hi = `\`hello\` World!`;
console.log(hi);

所有模板字符串的空格和换行,都是被保留的,比如

  • 标签前面会有一个换行。如果你不想要这个换行,可以使用trim方法

$('#list').html(`
<ul>
  <li>first</li>
  <li>second</li>
</ul>
`.trim());

五 字符串的新增方法
1.实例方法 :normalize()
ES6 提供字符串实例的normalize()方法,用来将字符的不同表示方法统一为同样的形式,这称为 Unicode 正规化。

'\u01D1'.normalize() === '\u004F\u030C'.normalize()
// true

2.实例方法:includes(), startsWith(), endsWith()
传统上,JavaScript 只有indexOf方法,可以用来确定一个字符串是否包含在另一个字符串中。ES6 又提供了三种新方法。
includes():返回布尔值,表示是否找到了参数字符串。
startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。

let s = 'Hello world!';
s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true

六 函数的扩展
ES6 允许使用“箭头”(=>)定义函数。
1.箭头函数的创建以及使用

var f = v => v;

// 等同于
var f = function (v) {
  return v;
};

function foo(){
 	console.log('hello');
 }
 foo();

// 使用箭头函数
 let foo=()=>{
 	console.log('hello');
 }
foo();

使用注意点
箭头函数有几个使用注意点。
(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
2.箭头函数 循环遍历 数组中的数据

 let arr=[123,456,789];
 arr.forEach(function(ele,index){
  console.log(ele,index);
 })

3.rest 参数
ES6 引入 rest 参数(形式为…变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

function add(...values) {
  let sum = 0;
  for (var val of values) {
    sum += val;
  }
  return sum;
}
add(2, 5, 3)      // 10

七 Set 和 Map 数据结构
1.Set本身是一个构造函数,用来生成 Set 数据结构。

const s = new Set();
[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));
for (let i of s) {
  console.log(i);   // 2 3 5 4
}

2.ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。如果你需要“键值对”的数据结构,Map 比 Object 更合适。

const m = new Map();
const o = {p: 'Hello World'};

m.set(o, 'content')
m.get(o) // "content"

m.has(o) // true
m.delete(o) // true
m.has(o) // false

与其他数据结构的互相转换
(1)Map 转为数组

new Map([
  [true, 7],
  [{foo: 3}, ['abc']]
])

(2)数组 转为 Map

function strMapToObj(strMap) {
  let obj = Object.create(null);
  for (let [k,v] of strMap) {
    obj[k] = v;
  }
  return obj;
}

const myMap = new Map()
  .set('yes', true)
  .set('no', false);
strMapToObj(myMap)

(3)Map 转为对象

let obj = {"a":1, "b":2};
let map = new Map(Object.entries(obj));

八 Class 的基本语法
1.JavaScript 语言中,生成实例对象的传统方法是通过构造函数

构造函数
function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function () {
  return '(' + this.x + ', ' + this.y + ')';
};

var p = new Point(1, 2);

2.新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。上面的代码用 ES6 的class改写

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

3.constructor 方法
constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。

class Point {
}

// 等同于
class Point {
  constructor() {}
}

九 Class 的继承
1.Class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。

class Point {
}
class ColorPoint extends Point {
}
//ColorPoint类,该类通过extends关键字,继承了Point类的所有属性和方法
class ColorPoint extends Point {
  constructor(x, y, color) {
    super(x, y); // 调用父类的constructor(x, y)
    this.color = color;
  }
  toString() {
    return this.color + ' ' + super.toString(); // 调用父类的toString()
  }
}

注意:只有调用super之后,才可以使用this关键字,否则会报错。这是因为子类实例的构建,基于父类实例,只有super方法才能调用父类实例。
2.super 关键字
super这个关键字,既可以当作函数使用,也可以当作对象使用。在这两种情况下,它的用法完全不同。
第一种情况,super作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次super函数。

class A {
  constructor() {
    console.log(new.target.name);
  }
}
class B extends A {
  constructor() {
    super();
  }
}
new A() // A
new B() // B

3.类的 prototype 属性和__proto__属性
大多数浏览器的 ES5 实现之中,每一个对象都有__proto__属性,指向对应的构造函数的prototype属性。Class 作为构造函数的语法糖,同时有prototype属性和__proto__属性,因此同时存在两条继承链。
(1)子类的__proto__属性,表示构造函数的继承,总是指向父类。
(2)子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值