ES6特性解释

let和const

  • let在块级作用域有效。不存在之前的var的作用域提升。
  • const意思是只读的变量。不可以在声明之后再改变值。
  • const指向对象的时候,对象可以改变属性,但是对象不能变。
{
    let a=1;
}
for(let i=0;i<10;i++){
}

变量的解构

1.数组的解构。

  • 左边的变量对等于右边的值。
  • 值的长度可变,不存在则等于undefined
  • 右边的结构要求实现Iterator ,数组、Set都算。
  • -可以在定义之前指定默认值,如果右边不存在则使用默认值,(null也算赋值)
let [a, b, c] = [1, 2, 3];
let [x, y, z] = new Set(['a', 'b', 'c']);
let [foo = true] = [];

2.对象的解构

  • 变量名等于属性名对应的值
  • 可以指定对象名对应的值
let { foo, bar } = { foo: "aaa", bar: "bbb" };
var { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"

3.字符串也可以解构

const [a, b, c, d, e] = 'hello';
let {length : len} = 'hello';

4.函数参数的解构

function add([x, y]){
  return x + y;
}
add([1, 2]); // 3

5.解构的表达式中不能使用圆括号’()’,一旦使用就会报错

字符串新方法

  • “\u{41}\u{42}\u{43}”表示法
  • codePointAt获取字符串的十进制
  • fromCodePoint从进制转字符串
  • for…of接口
  • at返回下标对应的字符
  • normalize
  • includes、startsWith、endsWith
  • repeat
  • padStart、padEnd补全
  • 模板字符串aaa${name}
  • 标签模板
  • String.rawHi\n${2+3}!

以上做一个备注

正则的扩展

  • new RegExp(/abc/ig, ‘i’)
  • String.prototype.match调用RegExp.prototype[Symbol.match]
  • u修饰符
var result = text.match(/[\s\S]/gu);
  return result ? result.length : 0;
  //返回中文字符串的正确长度
  • y修饰符
  • sticky
  • flags
  • s修饰符

数值扩展

  • 0b二进制和0o八进制表示法
  • Number.isFinite()和Number.isNaN()
  • Number.parseInt(), Number.parseFloat()
  • Number.isInteger()是否为整数
  • Number.EPSILON常量
  • Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER上下限
  • Math.trunc()去掉小数部分
  • Math.sign()正负数判断
  • Math.cbrt() 计算立方根
  • Math.clz32()
  • Math.imul()
  • Math.fround()
  • Math.hypot()
  • Math.expm1()
  • Math.log1p()
  • Math.log10()
  • Math.log2()
  • 指数运算符**

函数的扩展

  • 函数参数默认值,默认值在最后
  • length返回没有默认值的参数个数
  • rest 参数(形式为…变量名)
  • name返回函数名称
  • 箭头函数。
var f = () => 5;
// 等同于
var f = function () { return 5 };

var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
  return num1 + num2;
};
1.函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
2.不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
3.不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
4.不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
  • ::绑定 this
  • 尾调用,优化

数组的扩展

  • 扩展运算符…
  • Array.from将类似数组(包含length属性)和实现了Iterable的对象转为数组。第二个参数是处理方法
  • Array.of()将参数转为数组
  • copyWithin(开始位置,开始读取位置,结束读取位置)
  • find,findIndex
  • fill(填充值,开始位置,结束位置)
  • entries(),keys() 和 values()
  • includes(是否包含的值,开始查询的位置)

属性的扩展

  • 属性的简洁表示法
  • 字面量定义对象,不能同时使用简洁表示法
let propKey = 'foo';

let obj = {
  [propKey]: true,
  ['a' + 'bc']: 123
};
  • 方法的 name 属性
  • Object.is()
  • Object.assign()

    1.for…in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。
    2.Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)
    3.Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)。
    4.Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性。
    5.Reflect.ownKeys返回一个数组,包含对象自身的所有属性,不管属性名是 Symbol 或字符串,也不管是否可枚举。

  • Object.getOwnPropertyDescriptors()

  • Object.create
  • Object.setPrototypeOf()和Object.getPrototypeOf()
  • Object.keys(),Object.values(),Object.entries()
  • 对象的扩展运算符…

Symbol

ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。

let s = Symbol();
typeof s
// "symbol"

var mySymbol = Symbol();

// 第一种写法
var a = {};
a[mySymbol] = 'Hello!';

// 第二种写法
var a = {
  [mySymbol]: 'Hello!'
};

// 第三种写法
var a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });

// 以上写法都得到同样结果
a[mySymbol] // "Hello!"
  • Object.getOwnPropertySymbols可以获取到对象的Symbol属性
  • Symbol.for(),Symbol.keyFor()

Set和Map

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
  • Set.prototype.constructor:构造函数,默认就是Set函数。
  • Set.prototype.size:返回Set实例的成员总数。
  • add(value):添加某个值,返回Set结构本身。
  • delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
  • has(value):返回一个布尔值,表示该值是否为Set的成员。
  • clear():清除所有成员,没有返回值。
  • keys():返回键名的遍历器
  • values():返回键值的遍历器
  • entries():返回键值对的遍历器
  • forEach():使用回调函数遍历每个成员

WeakSet

1.WeakSet 的成员只能是对象,而不能是其他类型的值。
2.WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用

扫描二维码关注公众号,回复: 864957 查看本文章

Map

const map = new Map([
  ['name', '张三'],
  ['title', 'Author']
]);

map.size // 2
map.has('name') // true
map.get('name') // "张三"
map.has('title') // true
map.get('title') // "Author"
  • keys():返回键名的遍历器。
  • values():返回键值的遍历器。
  • entries():返回所有成员的遍历器。
  • forEach():遍历 Map 的所有成员。

WeakMap

1.WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名。
2.WeakMap的键名所指向的对象,不计入垃圾回收机制。

WeakMap 与 Map 在 API 上的区别主要是两个,一是没有遍历操作(即没有key()、values()和entries()方法),也没有size属性。因为没有办法列出所有键名,某个键名是否存在完全不可预测,跟垃圾回收机制是否运行相关。这一刻可以取到键名,下一刻垃圾回收机制突然运行了,这个键名就没了,为了防止出现不确定性,就统一规定不能取到键名。二是无法清空,即不支持clear方法。因此,WeakMap只有四个方法可用:get()、set()、has()、delete()。

Proxy

1.get(target, propKey, receiver)
2.set(target, propKey, value, receiver)
3.has(target, propKey)
4.deleteProperty(target, propKey)。用于拦截delete操作
5.ownKeys(target)
6.getOwnPropertyDescriptor(target, propKey)
7.defineProperty(target, propKey, propDesc)。拦截了Object.defineProperty操作
8.preventExtensions(target)
9.getPrototypeOf(target)
10.isExtensible(target)
11.setPrototypeOf(target, proto)
12.apply(target, object, args)
13.construct(target, args)。方法用于拦截new命令

Reflect

1.将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect对象上。也就是说,从Reflect对象上可以拿到语言内部的方法。
2.修改某些Object方法的返回结果,让其变得更合理。比如,Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false。

  • Reflect.apply(target,thisArg,args)
  • Reflect.construct(target,args)
  • Reflect.get(target,name,receiver)
  • Reflect.set(target,name,value,receiver)
  • Reflect.defineProperty(target,name,desc)
  • Reflect.deleteProperty(target,name)
  • Reflect.has(target,name)
  • Reflect.ownKeys(target)
  • Reflect.isExtensible(target)
  • Reflect.preventExtensions(target)
  • Reflect.getOwnPropertyDescriptor(target, name)
  • Reflect.getPrototypeOf(target)
  • Reflect.setPrototypeOf(target, prototype)

Promise

var promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

Iterator(遍历器)

1.创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。
2.第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
3.第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
4.不断调用指针对象的next方法,直到它指向数据结构的结束位置。

const obj = {
  [Symbol.iterator] : function () {
    return {
      next: function () {
        return {
          value: 1,
          done: true
        };
      }
    };
  }
};

Generator

Generator 函数有多种理解角度。从语法上,首先可以把它理解成,Generator 函数是一个状态机,封装了多个内部状态。

执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。

形式上,Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)。

function* helloWorldGenerator() {
  yield 'hello';
  yield 'world';
  return 'ending';
}

var hw = helloWorldGenerator();

yield 表达式

(1)遇到yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。

(2)下一次调用next方法时,再继续往下执行,直到遇到下一个yield表达式。

(3)如果没有再遇到新的yield表达式,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的对象的value属性值。

(4)如果该函数没有return语句,则返回的对象的value属性值为undefined。

需要注意的是,yield表达式后面的表达式,只有当调用next方法、内部指针指向该语句时才会执行,因此等于为 JavaScript 提供了手动的“惰性求值”(Lazy Evaluation)的语法功能。

async

var fs = require('fs');

var readFile = function (fileName) {
  return new Promise(function (resolve, reject) {
    fs.readFile(fileName, function(error, data) {
      if (error) return reject(error);
      resolve(data);
    });
  });
};

var gen = function* () {
  var f1 = yield readFile('/etc/fstab');
  var f2 = yield readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};
//等同于
var asyncReadFile = async function () {
  var f1 = await readFile('/etc/fstab');
  var f2 = await readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};

Class

//定义类
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
   static classMethod() {
    return 'hello';
  }
}
//继承
class Point {
}

class ColorPoint extends Point {
}

类的修饰

@testable
class MyTestableClass {
  // ...
}

function testable(target) {
  target.isTestable = true;
}

MyTestableClass.isTestable // true

Module 的语法

import { stat, exists, readFile } from 'fs';

ES6 的模块自动采用严格模式,不管你有没有在模块头部加上”use strict”;。

严格模式主要有以下限制。

  • 变量必须声明后再使用
  • 函数的参数不能有同名属性,否则报错
  • 不能使用with语句
  • 不能对只读属性赋值,否则报错
  • 不能使用前缀0表示八进制数,否则报错
  • 不能删除不可删除的属性,否则报错
  • 不能删除变量delete prop,会报错,只能删除属性delete global[prop]
  • eval不会在它的外层作用域引入变量
  • eval和arguments不能被重新赋值
  • arguments不会自动反映函数参数的变化
  • 不能使用arguments.callee
  • 不能使用arguments.caller
  • 禁止this指向全局对象
  • 不能使用fn.caller和fn.arguments获取函数调用的堆栈
  • 增加了保留字(比如protected、static和interface)

上面这些限制,模块都必须遵守。由于严格模式是 ES5 引入的,不属于 ES6,所以请参阅相关 ES5 书籍

其中,尤其需要注意this的限制。ES6 模块之中,顶层的this指向undefined,即不应该在顶层代码使用this。

猜你喜欢

转载自blog.csdn.net/cuo9958/article/details/77446500