es6特性总结(一)

本文详细总结了ES6的20个主要特性,包括let、const的块级作用域,数组和对象解构,模板字符串,字符串扩展方法,函数参数默认值,Proxy和Reflect用于对象操作,Promise解决异步编程问题,class和继承实现面向对象,以及Map、Set、Symbol等新数据结构,还有for...of循环和生成器Generator等。
摘要由CSDN通过智能技术生成

1.let、const

      es6之前只有全局作用域函数作用域,es6新增块级作用域。let、const 允许创建块级作用域。

      let关键词声明变量,特点:代码块内有效、不能重复声明、不存在变量提升

      const声明常量,其实 const 其实保证的不是变量的值不变,而是保证变量指向的内存地址所保存的数据不允许改动。对于复杂类型(对象 object,数组 array,函数 function),这个「常量」并非一成不变的,如:

var a = 2;
{
  let a = 3;
  console.log(a); // 3
}
console.log(a); // 2


const ARR = [5,6];
ARR.push(7);
console.log(ARR); // [5,6,7]
ARR = 10; // TypeError

2. 数组和对象解构

    解构可以避免在对象赋值时产生中间变量

// 数组结构
let [a, b, c] = [1, 2, 3];  // a=1,b=2,c=3
let [a, [[b], c]] = [1, [[2], 3]];  // a=1,b=2,c=3
let [, , d] = [1, 2, 3];  // d = 3
let [e, ...n] =[1, 2, 3];   // e = 1, n = [2,3]
let [a = 1, b] = []; // a = 1, b = undefined
let [a, b, c, d, e] = 'hello';  // a='h'  b='e'  c='l'  d='l'  e='o'
// 当解构模式有匹配结果,且匹配结果是 undefined 时,会触发默认值作为返回结果。
let [a = 3, b = a] = [];     // a = 3, b = 3
let [a = 3, b = a] = [1];    // a = 1, b = 1
let [a = 3, b = a] = [1, 2]; // a = 1, b = 2

const str = '/foo/sec/thr';
const [, first] = str.split('/');
console.log(first);  // foo

// 对象结构
let {name, age} = {name: 'vae', age: 18};  // name='vae'  age = 18
let {p: [x, {  }] } = {p: ['hello', {y: 'world'}] };  // x = 'hello'
let obj = {p: [{y: 'world'}] };
let {p: [{ y }, x ] } = {p: [{y: 'world'}] };  // x=undefined  y='world'
let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40};  // a=10  b=20  rest={c:30,d:40}
let {a = 10, b = 5} = {a: 3};   // a=3  b=5
let {a: aa = 10, b: bb = 5} = {a: 3};  // aa=3  bb=5

//重命名(命名冲突时解决方法)
const name = 'jack';
const { name: newName } = { name: 'vae', age: 18 };
console.log(name);  // jack
console.log(newName);  // vae

3.模板字符串

${ ... } 用来渲染一个变量

支持换行

const name = 'tom';
const str = `hello, this is ${name} ------- ${1+3}`;  // str = 'hello, this is tom ------- 4'

带标签的模板字符串(可用于调整字符串内顺序)

const name = 'tom';
const gender = true;

function myFunTag(strings, name1, gender1) {
    console.log(strings, name1, gender1);  // ['hello es2015 ', ' is a ', '']   tom  true

    return strings[2] + name1 + strings[0] + gender1 + strings[1];  // 可以对字符串顺序进行调整;
}

const str = myFunTag`hello es2015 ${name} is a ${gender}`;
console.log(str);  // tomhello es2015 true is a 

4.字符串的扩展方法

  •          includes()    是否包含某个字符串
  •          startsWith()  是否以某个字符串开头
  •          endsWith()    是否以某个字符串结尾
  •          repeat(param)    将字符串重复指定次数返回
  •          padStart()    用 参数字符串 从头部(左侧)补全原字符串
  •          padEnd()     用 参数字符串 从尾部(右侧)补全原字符串
const message = 'Error: this is start with arr';
console.log(message.includes(':'));  // true
console.log(message.startsWith('Error')); // true
console.log(message.endsWith('arr')); // true


console.log("Hello,".repeat(2));  // 'Hello,Hello,'
/***参数是小数,向下取整***/
console.log("Hello,".repeat(3.2));  // "Hello,Hello,Hello," 
/***参数是 0 至 -1 之间的小数,会进行取整运算,0 至 -1 之间的小数取整得到 -0,等同于0***/
console.log("Hello,".repeat(-0.5));  // "" 
/***参数是 NaN,等同于0***/
console.log("Hello,".repeat(NaN));  // "" 
/***参数是负数或者 Infinity ,会报错***/
console.log("Hello,".repeat(-1));  // RangeError: Invalid count value
/***参数是字符串,则会先将字符串转化为数字***/
console.log("Hello,".repeat("hh")); // ""
console.log("Hello,".repeat("2"));  // "Hello,Hello,"

/***第一个参数是指定生成的字符串的最小长度,第二个参数是用来补全的字符串.默认用空格填充**/
console.log("h".padStart(5,"o"));  // "ooooh"
console.log("h".padEnd(5,"o"));    // "hoooo"
console.log("h".padStart(5));      // "    h"

/***指定的长度  小于或等于  原字符串的长度,则返回  原字符串**/
console.log("hello".padStart(5,"A"));  // "hello"
/***原字符串加上补全字符串长度 大于 指定长度,则截去超出位数的补全字符串**/
console.log("hello".padEnd(10,",world!"));  // "hello,worl"

5.函数参数默认值

function foo(enable = true, bar) {  // enable默认值true
    console.log(enable); 
    console.log(bar);
}
foo();             // true undefined
foo(false);        // false undefined
foo(false, 123);   // false 123

6.函数剩余参数、对象的新方法

  • Object.assign()   将多个源对象中的属性复制到一个目标对象当中(属于浅拷贝)

  • Object.is 判断值是否相等

function foo(bar, ...args) {  // ...args只允许放在最后
    console.log(bar); // 1
    console.log(args); // [2,3,4]
}
foo(1,2,3,4);

//展开数组
const arr = ['foo', 'bar', 'str'];
console.log(
    arr[0], arr[1], arr[2]
);
console.log.apply(console, arr);
console.log(...arr);  // foo bar str


const source = {a: 123,b: 234}
const target = {b: 456,c: 567}
const resut = Object.assign(target, source);  // 第一个参数为目标对象, 后边参数属性会覆盖前边的
console.log(target);
console.log(resut)  // {b: 234, c: 567, a: 123}
console.log(target === resut);  // true


console.log(Object.is(+0, -0));  // false
console.log(Object.is(NaN,NaN));  // true
NaN === NaN;   // false

7.对象词法扩展

  • 允许声明在对象字面量时使用简写语法,来初始化属性变量和函数的定义方法
  • 允许在对象属性中进行计算操作
const bar = '123';
const obj = {
    name: '1111',
    bar,   // 等同于bar: bar
    method() {   // 省略 `function` 关键词简写对象函数
        console.log('method');
    },
    [Math.random()]: '123' //属性可以使用表达式计算值
}

8.Proxy

  • Proxy 可以对目标对象的读取、函数调用等操作进行拦截,然后进行操作处理。即Proxy在目标对象之前添加一个‘拦截器’,任何对该对象的访问都必须先通过这个拦截,因此可以在拦截这对外界的访问进行过滤和改写。
  • 一个 Proxy 对象由两个部分组成: target 、 handler 。target 即目标对象, handler 是一个对象,用来定制拦截行为。

  • Proxy支持的拦截操作,共13种:(带?的参数为可选参数)

  1. get(target, propKey, receiver?):拦截对象属性的读取,比如proxy.fooproxy['foo']
    target-----目标对象    propKey-----属性名  receiver-----proxy实例本身(即操作行为所针对的对象)
  2. set(target, propKey, value, receiver?):拦截某个属性的赋值操作,比如proxy.foo = vproxy['foo'] = v,返回一个布尔值。
    target-----目标对象    propKey-----属性名     value----属性值     receiver-----proxy实例本身(即操作行为所针对的对象)
  3. has(target, propKey):拦截HasProperty操作,即判断是否具有某个属性,返回一个布尔值。
    target-----目标对象    propKey-----属性名
  4. deleteProperty(target, propKey):拦截delete proxy[propKey]的操作,返回一个布尔值(如果这个方法抛出错误或者返回false,当前属性就无法被delete命令删除)。
  5. ownKeys(target):拦截对象自身属性的读取操作,包含Object.getOwnPropertyNames(proxy)Object.getOwnPropertySymbols(proxy)Object.keys(proxy)for...in循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名。
    注意:
    使用Object.keys()时,目标对象上不存在的属性、属性名为 Symbol 值、不可遍历(enumerable)的属性  这三类属性会被ownKeys()自动过滤,不会返回。
  6. getOwnPropertyDescriptor(target, propKey):拦截Object.getOwnPropertyDescriptor(),返回属性的描述对象或undefined。
  7. defineProperty(target, propKey, propDesc):拦截Object.defineProperty,返回一个布尔值。0
    注:(1)如果目标对象不可扩展(non-extensible),则defineProperty()不能增加目标对象上不存在的属性,否则会报错。
           (2)如果目标对象的某个属性不可写(writable)或不可配置(configurable),则defineProperty()方法不得改变这两个设置。
  8. preventExtensions(target):拦截Object.preventExtensions(proxy),返回一个布尔值(只能返回布尔值,否则返回值会被自动转为布尔值)。
  9. getPrototypeOf(target):拦截用来拦截获取对象原型,返回一个对象。如:Object.getPrototypeOf(),Object.prototype.__proto__,Object.prototype.isPrototypeOf(),Reflect.getPrototypeOf(),instanceof。
  10. isExtensible(target):拦截Object.isExtensible(proxy),返回一个布尔值。
  11. setPrototypeOf(target, proto):拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。
  12. apply(target, object, args):拦截函数调用、callapply操作,比如proxy(...args)proxy.call(object, ...args)proxy.apply(...)
    target-----目标对象    object-----目标对象的上下文(this)    args------目标对象的参数数组
  13. construct(target, args,newTarget):拦截 Proxy 实例作为构造函数调用的操作(new命令),比如new proxy(...args)
    注:construct()方法返回的必须是一个对象;它的目标对象必须是函数;construct()方法中的this指向的是handler,而不是实例对象;
    target-----目标对象     args------鼓噪函数的参数数组    newTarget------创造实例对象时,new命令作用的构造函数
  • Proxy.revocable()方法返回一个可取消的 Proxy 实例。
    使用场景:目标对象不允许直接访问,必须通过代理访问,一旦访问结束,就收回代理权,不允许再次访问。
const person = {name: 'nick',age: 20}
const personProxy = new Proxy(person, {
    get(target, property) {
        return property in target ? target[property] : undefined;
    },
    set(target, property, value) {
        console.log(target);
        console.log(property);
        console.log(value);
        target[property] = value;
    }
})
console.log(personProxy.name);
personProxy.age = 200; // 赋值
personProxy.gender = 'aaa';


var target = function () { return 'I am the target'; };
var p = new Proxy(target, {
    apply: function () {
        return 'I am the proxy';
    }
});
p();  // 'I am the proxy'


var handler = {
    has(target, key) {
        if (key[0] === '_') {
            return false;
        }
        return key in target;
    }
};
var target = { _prop: 'foo', prop: 'foo' };
var proxy = new Proxy(target, handler);
'_prop' in proxy   // false
'prop' in proxy   // true

  阮一峰--ECMAScript6入门   ---   更多关于Proxy的信息

9.Reflect

Reflect也是为了操作对象而提供的新的API,共有13个静态方法,同Proxy.

作用:

  1. Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。未来新的方法只部署在Reflect对象上
  2. 修改某些Object方法的返回结果,让其变得更合理。比如,Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false
  3. Object操作都变成函数行为。某些Object操作是命令式,比如name in objdelete obj[name],而Reflect.has(obj, name)Reflect.deleteProperty(obj, name)让它们变成了函数行为。

10. promise

11. class类

// 传统写法
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);

// es6
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

构造方法constructor即对应ES5的构造函数Point。  

  • 类的数据类型就是函数,类本身就指向构造函数。
  • 构造函数的prototype属性,在 ES6 的“类”上面继续存在。事实上,类的所有方法都定义在类的prototype属性上面。
  • 类的内部所有定义的方法,都是不可枚举的(non-enumerable)。
  • 与 ES5 一样,实例的属性除非显式定义在其本身(即定义在this对象上),否则都是定义在原型上(即定义在class上)
  • 与 ES5 一样,类的所有实例共享一个原型对象。
  • 在“类”的内部可以使用getset关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。

12.类的继承

Class 通过extends关键字实现继承,

13.静态方法

14. Map(另:map与各类型的转换)

 Map 数据结构类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。

作为构造函数,Map 也可以接受一个数组作为参数。该数组的成员是一个个表示键值对的数组。

操作方法:

  • set(key, val) 设置key对应的值为val
  • get(key) 读取key对应的值
  • has(key) 某个键是否在当前 Map 对象之中
  • delete(key)  删除某个键,返回true。若删除失败返回false
  • clear()  清除所有成员,没有返回值

遍历方法:

  • Map.prototype.keys():返回键名的遍历器。
  • Map.prototype.values():返回键值的遍历器。
  • Map.prototype.entries():返回所有成员的遍历器。
  • Map.prototype.forEach():遍历 Map 的所有成员。

15.Set

Set本身是一个构造函数,用来生成 Set 数据结构。它类似于数组,但是成员的值都是唯一的,没有重复的值。

Array.from方法可以将 Set 结构转为数组。

操作方法:

  • Set.prototype.add(value):添加某个值,返回 Set 结构本身。
  • Set.prototype.delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
  • Set.prototype.has(value):返回一个布尔值,表示该值是否为Set的成员。
  • Set.prototype.clear():清除所有成员,没有返回值。

遍历方法:(Set的遍历顺序就是插入顺序)

  • Set.prototype.keys():返回键名的遍历器
  • Set.prototype.values():返回键值的遍历器
  • Set.prototype.entries():返回键值对的遍历器
  • Set.prototype.forEach():使用回调函数遍历每个成员
const set = new Set([1, 2, 3, 4, 4]);
console.log(set);  // Set{1,2,3,4}
console.log([...set])  // [1,2,3,4]
console.log(set.size);  // 4

// 去除字符串里面的重复字符
[...new Set('ababbc')].join('')   // "abc"

const array = Array.from(set);    //[1,2,3,4]

16. Symbol (js语言第七种数据类型)

Symbol 表示独一无二的值,最大的用法是用来定义对象的唯一属性名。   Symbol() === Symbol()  // false

  • Symbol函数的参数只是表示对当前 Symbol 值的描述,因此相同参数的Symbol函数的返回值是不相等的。  
    Symbol('foo')  === Symbol('foo')  // false
  • Symbol 值不能与其他类型的值进行运算,会报错
  • Symbol 值可以显式转为字符串。   Symbol('foo').toString()  // Symbol(foo)
  • Symbol 值也可以转为布尔值,但是不能转为数值。     !Symbol() === false   // true
  • Symbol 作为属性名,遍历对象的时候,该属性不会出现在for...infor...of循环中,也不会被Object.keys()Object.getOwnPropertyNames()JSON.stringify()返回。
  • Object.getOwnPropertySymbols()方法,可以获取指定对象的所有 Symbol 属性名。
  • Reflect.ownKeys()方法可以返回对象中所有类型的键名,包括常规键名和 Symbol 键名。
  • Symbol.for() 接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建一个以该字符串为名称的 Symbol 值,并将其注册到全局。
  • Symbol.keyFor() 方法返回一个已登记的 Symbol 类型值的key

17.for...of循环

for 遍历数组

for...in.. 遍历键值对

数组forEach

for...of  可以遍历任意数组结构数据(对象不可遍历)

(数组、Set、Map 内部都实现了Iterator方法)

18. Iterator迭代器

19.生成器Generator

目的: 在复杂的异步代码中减少回调函数嵌套产生的问题。提供更好的异步编程方案。

20. 模块module

 

 

 

  • 个人总结,如有错误请评论指正,共同学习提升。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爱吃肉的大熊猫

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

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

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

打赏作者

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

抵扣说明:

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

余额充值