ES6

es6声明变量的方法:var、function、let、const、import、class。

顶层对象的属性全局变量挂钩,被认为是JavaScript语言最大的设计败笔之一。这样的设计带来了几个很大的问题,首先是没法在编译时就报出变量未声明的错误,只有运行时才能知道(因为全局变量可能是顶层对象的属性创造的,而属性的创造是动态的);其次程序员很容易不知不觉地就创造了全局变量;最后,顶层对象的属性是到处可以读写的,这非常不利于模块化编程。另一方面,window对象有实体含义,值的是浏览器的窗口对象,顶层对象是一个有实体含义的对象也是不合适的。

var、function命令声明的全局变量依旧是顶层对象的属性,let、const、class命令声明的全局变量不属于顶层对象的属性。也就是说,从es6开始,全局变量将逐步与顶层对象的属性脱钩(进行剥离)。

获取顶层对象

(typeof window !== 'undefined'
    ? window : 
        (typeof process === 'object' && 
        typeof require === 'function' && 
        typeof global === 'object')
        ? global : this)

function getGlobal(){
    if(typeof self !== 'undefined'){
        return self
    }
    if(typeof window !== 'undefined'){
        return window
    }
    if(typeof global !== 'undefined'){
        return global
    }
    throw new Error('unable to locate global object')
}

解构赋值报错:等号右边的值,要么转为对象以后不具备Iterator接口,要么本身就不具备Iterator接口。事实上,只要某种数据结构具有Iterator接口,都可以采用数组形式的解构赋值。

解构赋值允许指定认值。es6内部使用严格相等运算符(===),判断一个位置是否有值。只有当一个数组(对象中属性)成员的值严格等于undefined,认值才会生效。

对象的解构赋值是下面形式的简写。

let {foo:foo,bar:bar} = {foo:'aaa',bar:'bbb'}

也就是说,对象的解构赋值的内部机制是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。

let {foo:baz} = {foo:'aaa',bar:'bbb'}
baz //'aaa'
foo //error:foo is not defined  

前者是匹配模式。后者才是变量。

在模板字符串(template string)中使用反引号,需要在其前面用反斜杠转义。

使用模板字符串表示多行字符串,所有空格和缩进都会被保留在输出之中。

ES6 提供了二进制和八进制数值的新的写法,分别用前缀0b(或0B)和0o(或0O)表示。

函数参数制定了认值以后,函数的length属性将返回没有指定认值的参数的个数。

一旦设置了参数的认值,函数进行声明初始化时,参数会形成一个单独的作用域(context)。等初始化结束,这个作用于就会消失。这种语法行为,在不设置参数认值时,是不会出现的。

var x = 1
function fn(x,y = x){
    console.log(y)
}
fn(2) //2
fn() //undefined

利用参数认值,可以指定某个参数不得省略,如果省略就会抛出错误

function throwIfMiss(){
    throw new Error('Missing Parameter')
}
function fn(mustBeProvidedParam = throwIfMiss()){
    return mustBeProvidedParam
}
fn()

将参数认值设为undefined,表明这个参数是可以省略的。

函数的length属性,不包括rest参数(函数的多余参数)。

es6规定,只要函数参数使用了认值、解构赋值、扩展运算符,那么函数就不能显式设定为严格模式,否则报错。有两种方法可以规避这种限制:

第一种是设定全局性的严格模式

'use strict';
function doSomething(a, b = a) {
  // code
}

第二种是把函数包在一个无参数立即执行函数里面。

const doSomething = (function () {
  'use strict';
  return function(a,b = a) {
    // code 
  };
}());

箭头函数有几个使用注意点:

  • 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
  • 不可以当做构造函数,也就是说,不可以使用new命令,否则会抛出一个错误
  • 不可以使用arguments对象,该对象在函数体内不存在。如果要使用,可以使用rest参数代替。 
  • 不可以使用yield命令,因此箭头函数不能用作Generator函数

Array.from()方法可将类数组对象(array-like object)和可遍历(iterable)的对象转为真正的数组。

Array.of()方法用于将一组值转换为数组。

对象中属性名表达式如果是一个对象,认情况下会自动将对象转为字符串[object Object],而对象中只会有最后一个[object Object],前面的均会被覆盖掉。

isPrototypeOf()、getPrototypeOf()、setPrototype()用法示例:

如果Symbol的参数是一个对象,就会调用该对象的toString方法,将其转为字符串,然后再生成一个symbol值。

Symbol实例属性description,直接返回symbol的描述。

使用Set很容易实现并集(Union)、交集(Intersect)和差集(Difference)。

let s1 = new Set([1,2,3])
let s2 = new Set([3,4,5])

let union = new Set([...s1,...s2])
let intersect = new Set([...s1].filter(i => s2.has(i)))
let difference = new Set([...s1].filter(i => !s2.has(i)))

Proxy构造函数:let proxy = new Proxy(target,handler);

target参数表示所要拦截的目标对象,handler参数也是一个对象。

下面是 Proxy 支持拦截操作一览,一共 13 种。

  • get(target, propKey, receiver):拦截对象属性的读取,比如proxy.fooproxy['foo']

  • set(target, propKey, value, receiver):拦截对象属性的设置,比如proxy.foo = vproxy['foo'] = v,返回一个布尔值。

  • has(target, propKey):拦截propKey in proxy的操作,返回一个布尔值。

  • deleteProperty(target, propKey):拦截delete proxy[propKey]的操作,返回一个布尔值。

  • ownKeys(target):拦截Object.getownPropertyNames(proxy)Object.getownPropertySymbols(proxy)Object.keys(proxy)for...in循环,返回一个数组。该方法返回目标对象所有自身的属性属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性

  • getownPropertyDescriptor(target, propKey):拦截Object.getownPropertyDescriptor(proxy, propKey),返回属性的描述对象。

  • defineProperty(target, propKey, propDesc):拦截Object.defineProperty(proxy, propKey, propDesc)Object.defineProperties(proxy, propDescs),返回一个布尔值。

  • preventExtensions(target):拦截Object.preventExtensions(proxy),返回一个布尔值。

  • getPrototypeOf(target):拦截Object.getPrototypeOf(proxy),返回一个对象。

  • isExtensible(target):拦截Object.isExtensible(proxy),返回一个布尔值。

  • setPrototypeOf(target, proto):拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截

  • apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如proxy(...args)proxy.call(object, ...args)proxy.apply(...)

  • construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(...args)

Reflect对象一共有 13 个静态方法

  • Reflect.apply(target, thisArg, args) 用于绑定this对象后执行给定函数

  • Reflect.construct(target, args) 提供了一种不使用new,来调用构造函数方法

  • Reflect.get(target, name, receiver)

  • Reflect.set(target, name, value, receiver)

  • Reflect.defineProperty(target, name, desc) 用来为对象定义属性

  • Reflect.deleteProperty(target, name) 用于删除对象的属性

  • Reflect.has(target, name) 方法对应name in obj里面的in运算符。

  • Reflect.ownKeys(target) 用于返回对象的所有属性,基本等同于Object.getownPropertyNamesObject.getownPropertySymbols之和。

  • Reflect.isExtensible(target) 返回一个布尔值,表示当前对象是否可扩展。

  • Reflect.preventExtensions(target) 用于让一个对象变为不可扩展。

  • Reflect.getownPropertyDescriptor(target, name) 用于得到指定属性的描述对象,

  • Reflect.getPrototypeOf(target) 用于读取对象的__proto__属性

  • Reflect.setPrototypeOf(target, prototype) 用于设置目标对象的原型(prototype)

promise

实例的状态都变成fulfilled,或者其中有一个变为rejected,才会调用Promise.all方法后面的回调函数。 

一个实例率先改变状态,Promise.race()的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给Promise.rece()的回调函数

Promise.allSettled()方法只有等到所有这些参数实例都返回结果,不管是fulfilled还是rejected,包装实例才会结束。

Promise.any()只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态。

Promise.try()

原生具备Iterator接口的数据结构

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的arguments对象
  • NodeList对象

模拟迭代器

类相当于实例的原型,所有在类中定义的方法都会被实例继承。如果在一个方法前,加上static关键字,表示该方法不会被实例继承,而是直接通过类调用,这就成为静态方法

如果静态方法中包含this关键字,这个this指的是类,而不是实例。

class Foo{
    static bar(){
        this.baz()
    }
    static baz(){
        console.log('hello')
    }
    baz(){
        console.log('world')
    }
}
Foo.bar() // hello  

提案:私有属性方法,前面加# 

new.target 属性

new是从构造函数生成实例对象的命令。ES6 为new命令引入了一个new.target属性,该属性一般用在构造函数之中,返回new命令作用于的那个构造函数。如果构造函数不是通过new命令或Reflect.construct()调用的,new.target会返回undefined,因此这个属性可以用来确定构造函数是怎么调用

需要注意的是,子类继承父类时,new.target会返回子类,利用这个特点,可以写出不能独立使用,必须继承后才能使用的类。

class Father{
    constructor(){
        if(new.target === Father){
            throw new Error('本类不能实例化')
        }
    }
}
class Son extends Father{
    constructor(x,y){
        super()
        this.x = x;
        this.y = y
    }
}

  

 

 

 

未完待续...  

相关文章

原文连接:https://www.cnblogs.com/dupd/p/5951311.htmlES6...
以为Es6,javascript第一次支持了module。ES6的模块化分为导...
视频讲解关于异步处理,ES5的回调使我们陷入地狱,ES6的Prom...
TypeScript什么是TypeScript?TypeScript是由微软开发的一款开...
export class AppComponent { title = 'Tour of heroes...
用 async/await 来处理异步昨天看了一篇vue的教程,作者用as...