ECMA6全部知识点大概笔记

ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现
初学者一开始学习JavaScript,其实就是在学3.0版的语法。
----------------------------------------------------
Node.js是JavaScript语言的服务器运行环境,对ES6的支持度比浏览器更高。经过Node,能够体验更多ES6的特性。建议使用版
本管理工具nvm,来安装Node,由于能够自由切换版本。不过, nvm 不支持Windows系统,若是你使用Windows系统,下面的
操做能够改用nvmw或nvm-windows代替。
----------------------------------------------------java

> Babel是一个普遍使用的ES6转码器,能够将ES6代码转为ES5代码,从而在现有环境执行

ES6新增了 let 命令,用来声明变量。它的用法相似于 var ,可是所声明的变量,只在 let 命令所在的代码块内有效es6

let 不像 var 那样会发生“变量提高”现象。因此,变量必定要在声明后使用,不然报错。算法

只要块级做用域内存在 let 命令,它所声明的变量就“绑定”(binding)这个区域,ES6明确规定,若是区块中存在 let 和 const 命令,这个区块对这些命令声明的变量,从一开始就造成了封闭做用域。凡是
在声明以前就使用这些变量,就会报错。编程

> let不容许在相同做用域内,重复声明同一个变量

为何须要块级做用域?ES5只有全局做用域和函数做用域,没有块级做用域,这带来不少不合理的场景
第一种场景,内层变量可能会覆盖外层变量
第二种场景,用来计数的循环变量泄露为全局变量。
let 实际上为JavaScript新增了块级做用域json

ES5存在函数提高,无论会
不会进入 if 代码块,函数声明都会提高到当前做用域的顶部,获得执行
而ES6支持块级做用域,无论会不会进入if代码
块,其内部声明的函数皆不会影响到做用域的外部。
-------------------------------------------------
const 声明一个只读的常量。一旦声明,常量的值就不能改变。
const声明的变量不得改变值,这意味着,const一旦声明变量,就必须当即初始化,不能留到之后赋值。
const的做用域与let命令相同:只在声明所在的块级做用域内有效,也是不提高,存在暂时性死区,不可重复声明
对于复合类型的变量(对象),变量名不指向数据,而是指向数据所在的地址,不可变的只是这个地址,但对象自己是可变的,因此依然能够为其添加新属性
------------------------------------------------------------
ES5只有两种声明变量的方法: var 命令和 function 命令。ES6除了添加 let 和 const 命令另外
两种声明变量的方法: import 命令和 class 命令。因此,ES6一共有6种声明变量的方法。
------------------------------------------------------------
全局对象是最顶层的对象,在浏览器环境指的是 window 对象,在Node.js指的是 global 对象
var 命令和 function 命令声明的全局变量,依旧是全局对象的属性;另外一方面规定,let 命令、 const 命令、 class 命令声明的全局变量,不属于全局对象的属性。
------------------------------------------------------------
数组解构的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
对象的解构赋值的内部机制,是先找到同名属性,而后再赋给对应的变量。真正被赋值的是后者,而不是前者。windows

解构赋值的规则是,只要等号右边的值不是对象,就先将其转为对象,因为 undefined 和 null 没法转为对象,因此对它们
进行解构赋值,都会报错。数组

> 解构赋值对提取JSON对象中的数据,函数参数的默认值,尤为有用。

avaScript内部,字符以UTF-16的格式储存,每一个字符固定为2个字节,对于那些须要4个字节储存的字符(Unicode码点大于
0xFFFF的字符),JavaScript会认为它们是两个字符。
--------------------------------------------------------------
JavaScript只有 indexOf 方法,能够用来肯定一个字符串是否包含在另外一个字符串中,ES6又提供了三种新方法
includes():返回布尔值,表示是否找到了参数字符串
startsWith():返回布尔值,表示参数字符串是否在源字符串的头部
endsWith():返回布尔值,表示参数字符串是否在源字符串的尾部
这三个方法都支持第二个参数,表示开始搜索的位置
--------------------------------------------------------------
repeat 方法返回一个新字符串,表示将原字符串重复 n 次
padStart 和 padEnd 字符串补全长度的功能,一共接受两个参数,第一个参数用来指定字符串的最小长度,第二个参数是用来补全的
字符串。
--------------------------------------------------------------
模板字符串(template string)是加强版的字符串,用反引号(`)标识。它能够看成普通字符串使用,也能够用来定义多行字符
串,或者在字符串中嵌入变量。模板字符串中嵌入变量,须要将变量名写在 ${} 之中。
${}若是大括号中的值不是字符串,将按照通常的规则转为字符串。好比,大括号中是一个对象,将默认调用对象的 toString 方
法。大括号内部,就是执行JavaScript代码,所以若是大括号内部是一个字符串,将会原样输出promise

ES6还为原生的String对象,提供了一个 raw 方法。String.raw 方法,每每用来充当模板字符串的处理函数,返回一个斜杠都被转义(即斜杠前面再加一个斜杠)的字符串,对
应于替换变量后的模板字符串。
--------------------------------------------------------------
Number.isFinite()用来检查一个数值是否为有限的(finite),即不是Infinity。
Number.isNaN()用来检查一个值是否为NaN。
Number.isFinite()对于非数值一概返回false, Number.isNaN()只有对于NaN才返回true,非NaN一概返回false。
ES6 将全局方法parseInt()和parseFloat(),移植到Number对象上面
Number.isInteger()用来判断一个数值是否为整数。
Math.trunc方法用于去除一个数的小数部分,返回整数部分。
Math.sign方法用来判断一个数究竟是正数、负数、仍是零。对于非数值,会先将其转换为数值。
它会返回五种值。浏览器

  • ● 参数为正数,返回+1;
  • ● 参数为负数,返回-1;
  • ● 参数为 0,返回0;
  • ● 参数为-0,返回-0;
  • ● 其余值,返回NaN。

    ES6 容许为函数的参数设置默认值,即直接写在参数定义的后面function Point(x = 0, y = 0)
    参数变量是默认声明的,因此不能用let或const再次声明。参数默认值是惰性求值的
    undefined,结果触发了默认值,null,就没有触发默认值。

这是由于length属性的含义是,该函数预期传入的参数个数。某个参数指定默认值之后,预期传入的参数个数就不包括这个参数了。若是设置了默认值的参数不是尾参数,那么length属性也再也不计入后面的参数了。缓存

一旦设置了参数的默认值,函数进行声明初始化时,参数会造成一个单独的做用域

ES6 引入 rest

参数(形式为...变量名),用于获取函数的多余参数,这样就不须要使用arguments对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。
注意,rest 参数以后不能再有其余参数(即只能是最后一个参数),不然会报错。函数的length属性,不包括 rest 参数
--------------------------------------------------------------

> ES6 容许使用“箭头”(=>)定义函数。箭头函数和普通函数。前者的this绑定定义时所在的做用域,后者的this指向运行时所在的做用域。this指向的固定化,并非由于箭头函数内部有绑定this的机制,实际缘由是箭头函数根本没有本身的this,致使内部的this就是外层代码块的this。正是由于它没有this,因此也就不能用做构造函数。除了this,如下三个变量在箭头函数之中也是不存在的,指向外层函数的对应变量:arguments、super、new.target。

> ES6 中只要使用尾递归,就不会发生栈溢出,相对节省内存。这将大大节省内存。这就是“尾调用优化”的意义。ES6 的尾调用优化只在严格模式下开启,正常模式是无效的。

扩展运算符(spread)是三个点(...)。它比如 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。容易和rest混淆,两个不是一个东西。

function f(v, w, x, y, z) { }
const args = [0, 1];
f(-1, ...args, 2, ...[3]);

1.因为扩展运算符能够展开数组,因此再也不须要apply方法,将数组转为函数的参数了。

2.数组是复合的数据类型,直接复制的话,只是复制了指向底层数据结构的指针,而不是克隆一个全新的数组。扩展运算符提供了复制数组的简便写法。

const a1 = [1, 2];
// 写法一
const a2 = [...a1];
// 写法二
const [...a2] = a1;
3.合并数组
// ES5
[1, 2].concat(more)
// ES6
[1, 2, ...more]

4.扩展运算符能够与解构赋值结合起来,用于生成数组。若是将扩展运算符用于数组赋值,只能放在参数的最后一位,不然会报错。
const [...butLast, last] = [1, 2, 3, 4, 5];
// 报错

5.扩展运算符还能够将字符串转为真正的数组。
[...'hello']
// [ "h", "e", "l", "l", "o" ]

> 扩展运算符内部调用的是数据结构的 Iterator 接口,所以只要具备 Iterator 接口的对象,均可以使用扩展运算符,若是对没有 Iterator 接口的对象,使用扩展运算符,将会报错。

Array.from方法用于将两类对象转为真正的数组,扩展运算符背后调用的是遍历器接口(Symbol.iterator),若是一个对象没有部署这个接口,就没法转换。Array.from方法还支持相似数组的对象。所谓相似数组的对象,本质特征只有一点,即必须有length属性。所以,任何有length属性的对象,均可以经过Array.from方法转为数组,而此时扩展运算符就没法转换。

> Array.from还能够接受第二个参数,做用相似于数组的map方法,用来对每一个元素进行处理,将处理后的值放入返回的数组。第三个参数,用来绑定this。

Array.of方法用于将一组值,转换为数组。
Array.of(3, 11, 8) // [3,11,8]
Array.of基本上能够用来替代Array()或new Array(),而且不存在因为参数不一样而致使的重载。它的行为很是统一。
--------------------------------------------------------------
数组实例的copyWithin方法,在当前数组内部,将指定位置的成员复制到其余位置(会覆盖原有成员),而后返回当前数组。也就是说,使用这个方法,会修改当前数组。

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

> 上面代码表示将从 3 号位直到数组结束的成员(4 和 5),复制到从 0 号位开始的位置,结果覆盖了原来的 1 和 2。

数组实例的 find() 和 findIndex()

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

数组实例的findIndex方法的用法与find方法很是相似,返回第一个符合条件的数组成员的位置,若是全部成员都不符合条件,则返回-1。
这两个方法均可以发现NaN,弥补了数组的indexOf方法的不足。
--------------------------------------------------------------

> ES6 提供三个新的方法——entries(),keys()和values()——用于遍历数组。keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。

数组实例的 includes(),没有该方法以前,咱们一般使用数组的indexOf方法,检查是否包含某个值。indexOf方法有两个缺点,一是不够语义化,它的含义是找到参数值的第一个出现位置,因此要去比较是否不等于-1,表达起来不够直观。二是,它内部使用严格相等运算符(===)进行判断,这会致使对NaN的误判。

> ES6 明确将数组的空位转为undefined。

> ES5 比较两个值是否相等,只有两个运算符:相等运算符(==)和严格相等运算符(===)。它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0 用来解决这个问题。Object.is就是部署这个算法的新方法。它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。

Object.assign方法用于对象的合并,将源对象(source)的全部可枚举属性,复制到目标对象(target)。Object.assign拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性(enumerable: false)。
注意点(1)浅拷贝(2)同名属性的替换(3)数组的处理(4)取值函数的处理
常见用途(1)为对象添加属性(2)为对象添加方法(3)克隆对象(4)合并多个对象(5)为属性指定默认值
--------------------------------------------------------------
对象的每一个属性都有一个描述对象(Descriptor),用来控制该属性的行为。Object.getOwnPropertyDescriptor方法能够获取该属性的描述对象。描述对象的enumerable属性,称为”可枚举性“,若是该属性为false,就表示某些操做会忽略当前属性。

“可枚举”(enumerable)这个概念的最初目的,就是让某些属性能够规避掉for...in操做,否则全部内部属性和方法都会被遍历到。好比,对象原型的toString方法,以及数组的length属性,就经过“可枚举性”,从而避免被for...in遍历到。

Object.getOwnPropertyDescriptor(Object.prototype, 'toString').enumerable
// false

从兼容性的角度,都不要使__proto__
用这个属性,而是使用下面的 Object.setPrototypeOf() (写操做)、 Object.getPrototypeOf() (读操
做)、 Object.create() (生成操做)代替。
-------------------------------
Object.entries 的基本用途是遍历对象的属性,
Object.entries 方法的一个用处是,将对象转为真正的 Map 结构。var map = new Map(Object.entries(obj));
扩展运算符( ... )用于取出参数对象的全部可遍历属性,拷贝到当前对象之中。等同于使用 Object.assign 方法。

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

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

Symbol值经过 Symbol

函数生成。这就是说,对象的属性名如今能够有两种类型,一种是原来就有的字符串,另外一种就是新增
的Symbol类型。凡是属性名属于Symbol类型,就都是独一无二的,能够保证不会与其余属性名产生冲突。
在对象的内部,使用Symbol值定义属性时,Symbol值必须放在方括号之中。

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

Symbol值能够显式转为字符串。也能够转为布尔值,可是不能转为数值。

Symbol做为属性名,该属性不会出如今 for...in 、 for...of 循环中,也不会
被 Object.keys() 、 Object.getOwnPropertyNames() 返回,它也不是私有属性,有一
个 Object.getOwnPropertySymbols 方法,能够获取指定对象的全部Symbol属性名。这就形成了一种非私有的内部方法的效果。

Symbol.for() 与 Symbol() 这两种写法,都会生成新的Symbol。它们的区别是,前者会被登记在全局环境中供搜索,后者
不会。 Symbol.for() 不会每次调用就返回一个新的Symbol类型的值,而是会先检查给定的key是否已经存在,若是不存在才
会新建一个值。
-------------------------------
Proxy能够译为“代理器”,ES6原生提供Proxy构造函数,用来生成Proxy实例。

var proxy = new Proxy(target, handler);
Proxy对象的全部用法,都是上面这种形式,不一样的只是 handler 参数的写法。其中, new Proxy() 表示生成一个Proxy实
例,target参数表示所要拦截的目标对象, handler 参数也是一个对象,用来定制拦截行为。
Proxy.revocable方法返回一个可取消的Proxy实例
-------------------------------
Reflect 对象与 Proxy 对象同样,也是ES6为了操做对象而提供的新API。
将 Object 对象的一些明显属于语言内部的方法(好比 Object.defineProperty ),放到 Reflect 对象上。
-------------------------------
ES6提供了新的数据结构Set。它相似于数组,可是成员的值都是惟一的,没有重复的值。经过 add 方法向Set结构加入成员,结果代表Set结构不会添加剧复的值,一种去除数组重复成员的方法

// 去除数组的重复成员
[...new Set(array)] 或 Array.from(new Set(array));

操做:add(value),delete(value),has(value),clear()

遍历:keys(),values(),entries(),forEach()

WeakSet结构与Set相似,也是不重复的值的集合。可是,它与Set有两个区别。

首先,WeakSet的成员只能是对象,而不能是其余类型的值。

其次,WeakSet中的对象都是弱引用,即垃圾回收机制不考虑WeakSet对该对象的引用,也就是说,若是其余对象都再也不引用该
对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于WeakSet之中。这个特色意味着,没法引用
WeakSet的成员,所以WeakSet是不可遍历的。
-------------------------------
ES6提供了Map数据结构,Object结构提供了“字符串—值”的对应,Map结构提供了“值—值”的对应,是一种更
完善的Hash结构实现,Map的键其实是跟内存地址绑定的,只要内存地址不同,就视为两个键
Map原生提供三个遍历器生成函数keys(),values(),entries(),forEach()

与其余数据结构的互相转换

  • (1)Map转为数组:就是使用扩展运算符(...)。
  • (2)数组转为Map:将数组转入Map构造函数,就能够转为Map。
  • (3)Map转为对象:Object.create()
  • (4)对象转为Map:Object.keys(obj) strMap.set(k, obj[k]);
  • (5)Map转为JSON,JSON转MAP

    任何数据结构只要部署,Iterator接口,就能够完成遍历操做,引入了 for...of 循环,做为遍历全部数据结构的统一的方法。一个数据结构只要部署
    了 Symbol.iterator 属性,就被视为具备iterator接口,就能够用 for...of 循环遍历它的成员。也就是说, for...of 循环
    内部调用的是数据结构的 Symbol.iterator 方法。

与其余遍历语法的比较:

for循环:写法比较麻烦;

数组提供内置forEach:没法中途跳出
forEach 循环,break命令或return命令都不能奏效;

for...in循环有几个缺点:
数组的键名是数字,可是for...in循环是以字符串做为键名“0”、“1”、“2”等等。
for...in循环不只遍历数字键名,还会遍历手动添加的其余键,甚至包括原型链上的键。
某些状况下,for...in循环会以任意顺序遍历键名。
总之, for...in 循环主要是为遍历对象而设计的,不适用于遍历数组
----
for...of

循环相比上面几种作法:
有着同for...in同样的简洁语法,可是没有for...in那些缺点。
不一样用于forEach方法,它能够与break、continue和return配合使用。
提供了遍历全部数据结构的统一操做接口。
--------------------------------------------------------------
Promise 是异步编程的一种解决方案,原生提供了Promise对象,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败),一旦状态改变,就不会再变,任什么时候候均可以获得这个结果,Promise也有一些缺点。首先,没法取消Promise,一旦新建它就会当即执行,没法中途取消。其次,若是不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于pending状态时,没法得知目前进展到哪个阶段(刚刚开始仍是即将完成)。
resolve函数的做用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved)
reject函数的做用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected)

then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。所以能够采用链式写法

Promise 对象的错误具备“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误老是会被下一个catch语句捕获。通常来讲,不要在then方法里面定义 Reject 状态的回调函数(即then的第二个参数),老是使用catch方法。
const p = Promise.all([p1, p2, p3]);
Promise.all方法接受一个数组做为参数,p一、p二、p3都是 Promise 实例。
p的状态由p一、p二、p3决定,分红两种状况。
(1)只有p一、p二、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p一、p二、p3的返回值组成一个数组,传递给p的回调函数。
(2)只要p一、p二、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

Promise.race方法一样是将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.race([p1, p2, p3]);

上面代码中,只要p一、p二、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

将现有对象转为 Promise 对象,Promise.resolve方法就起到这个做用
Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))
--------------------------------------------------------------
async 函数是什么?一句话,它就是 Generator 函数的语法糖。async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await,仅此而已。
async函数对 Generator 函数的改进,体如今如下四点:
(1)内置执行器。(2)更好的语义。(3)更广的适用性。(4)返回值是 Promise。
只有async函数内部的异步操做执行完,才会执行外面的then方法指定的回调函数

// 函数声明
async function foo() {}
// 函数表达式
const foo = async function () {};
// 箭头函数
const foo = async () => {};

若是但愿多个请求并发执行,可使用Promise.all方法。
async 函数的实现原理,就是将 Generator 函数和自动执行器,包装在一个函数里。

> next方法必须是同步的,只要调用就必须马上返回值。也就是说,一旦执行next方法,就必须同步地获得value和done这两个属性。若是遍历指针正好指向同步操做,固然没有问题,但对于异步操做,就不太合适了。目前的解决方法是,Generator 函数里面的异步操做,返回一个 Thunk 函数或者 Promise 对象,即value属性是一个 Thunk 函数或者 Promise 对象,等待之后返回真正的值,而done属性则仍是同步产生的

for...of循环用于遍历同步的 Iterator 接口。新引入的for await...of循环,则是用于遍历异步的 Iterator 接口。
异步 Generator 函数出现之后,JavaScript 就有了四种函数形式:普通函数、async 函数、Generator 函数和异步 Generator 函数
--------------------------------------------------------------
Generator函数是ES6提供的一种异步编程解决方案,语法行为与传统函数彻底不一样,形式上,Generator函数是一个普通函数,可是有两个特征。一是, function 关键字与函数名之间有一个星号;二是,函数体
内部使用 yield 语句,定义不一样的内部状态.
Generator函数的调用方法与普通函数同样,也是在函数名后面加上一对圆括号。不一样的是,调用Generator函数后并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象,必须调用遍历器对象的next方法,使得指针移向下一个状态。也就是说,每次调用 next 方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个 yield 语句(或 return 语句)为止。

Generator函数是分段执行的, yield 语句是暂停执行的标记,而 next 方法能够恢复执行。

next方法返回值的value属性,是Generator函数向外输出数据;next方法还能够接受参数,这是向Generator函数体内输入数据,传入
Generator 函数,做为上个阶段异步任务的返回结果

Generator函数能够返回一系列的值,由于能够有任意多个 yield,yield后面的表达式 123 + 456 ,不会当即求值,只会在 next 方法将指针移到这一句时,才会求值,Generator函数能够不用 yield 语句,这时就变成了一个单纯的暂缓执行函数。

yield 句自己没有返回值,或者说老是返回 undefined 。 next 方法能够带一个参数,该参数就会被看成上一
个 yield 语句的返回值。

for...of 循环能够自动遍历Generator函数,且此时再也不须要调用 next 方法。

> yield* 语句,用来在一个Generator函数里面执行另外一个Generator函数。yield* 不过是 for...of 的一种简写形式,yield 命令后面若是不加星号,返回的是整个数组,加了星号就表示返回的是数组的遍历器对象。

Generator函数不能用NEW(会报错),又想在函数里面用THIS ?
首先,生成一个空对象,使用 bind 方法绑定Generator函数内部的 this 。这样,构造函数调用以
后,这个空对象就是Generator函数的实例对象了。

> Generator函数的一个重要实际意义就是用来处理异步操做,改写回调函数

async函数并不属于ES6,而是被列入了ES7,可是traceur、Babel.js、regenerator等转码器已经支持这个功能,转码后马上就
能使用。异步编程对JavaScript语言过重要。Javascript语言的执行环境是“单线程”的,若是没有异步编程,根本无法用,非卡死不可。
ES6诞生之前,异步编程的方法,大概有下面四种。
回调函数
事件监听
发布/订阅
Promise 对象
-------------------------------
类的数据类型就是函数,类自己就指向构造函数。

class Point{
// ...
}

typeof Point // "function"
constructor 方法是类的默认方法,经过 new 命令生成对象实例时,自动调用该方法。一个类必须有 constructor 方法,
若是没有显式定义,一个空的 constructor 方法会被默认添加。

实例的属性除非显式定义在其自己(即定义在 this 对象上),不然都是定义在原型上(即定义
在 class 上)。hasOwnProperty方法判断是自己属性仍是原型属性。
Class不存在变量提高(hoist),这一点与ES5彻底不一样。 Class之间能够经过extends关键字实现继承,这比ES5的经过修改原型链实现继承,要清晰和方便不少
子类必须在 constructor 方法中调用 super 方法,不然新建实例时会报错。这是由于子类没有本身的 this 对象,而是继
承父类的 this 对象,而后对其进行加工。若是不调用 super 方法,子类就得不到 this 对象。只有调用 super 以后,才可使用 this 关键字
类的继承是按照下面的模式实现的:Object.setPrototypeOf(B.prototype, A.prototype);
Object.getPrototypeOf 方法能够用来从子类上获取父类。所以,可使用这个方法判断,一个类是否继承了另外一个类。

若是在一个方法前,加上 static 关键字,就表示该方法不会被实例继承,而是直接经过类来调用,这就称为“静态方法”。
父类的静态方法,能够被子类继承

> 静态属性指的是Class自己的属性,即 Class.propname ,而不是定义在实例对象( this )上的属性。

> 修饰器(Decorator)是一个函数,用来修改类的行为。这是ES7的一个提案,目前Babel转码器已经支持。相似和类,方法,属性添加JAVA注解的功能

在ES6以前,社区制定了一些模块加载方案,最主要的有CommonJS和AMD两种。前者用于服务器,后者用于浏览器,ES6模块的设计思想,是尽可能的静态化,使得编译时就能肯定模块的依赖关系,以及输入和输出的变量。CommonJS和AMD模块,都只能在运行时肯定这些东西。
let { stat, exists, readFile } = require('fs') 这种加载称为“运行时加载”
import { stat, exists, readFile } from 'fs' 这种加载称为“编译时加载”
ES6的模块自动采用严格模式

模块功能主要由两个命令构成: export 和 import,export 命令用于规定模块的对外接口, import 命令用于输入其余
模块提供的功能,export 和 import 命令若是处于块级做用域内,就会报错。由于处于条件代码块之中,就无法作静态优化了,违背了ES6模块的设计初衷

模块的总体加载 import * as circle from './circle';
export default 命令,为模块指定默认输出,一个模块只能有一个默认输出,因此, import 命令后面才不用加大括号,由于只可能对应一个方法

> ES6模块是动态引用,而且不会缓存值,模块里面的变量绑定其所在的模块

编码规范:

(1)let取代var

(2)全局常量和线程安全:在 let 和 const 之间,建议优先使用 const ,尤为是在全局环境,不该该设置变量,只应设置常量。

..静态字符串一概使用单引号或反引号,不使用双引号。动态字符串使用反引号。

..使用数组成员对变量赋值时、函数返回多个值,优先使用解构赋值。

..单行定义的对象,最后一个成员不以逗号结尾。多行定义的对象,最后一个成员以逗号结尾。

..对象尽可能静态化,一旦定义,就不得随意添加新的属性。若是添加属性不可避免,要使用 Object.assign 方法
..使用扩展运算符(...)拷贝数组,使用Array.from方法,将相似数组的对象转为数组。

..当即执行函数能够写成箭头函数的形式,那些须要使用函数表达式的场合,尽可能用箭头函数代替。由于这样更简洁,并且绑定了this。

..不要在函数体内使用arguments变量,使用rest运算符(...)代替

..老是用Class,取代须要prototype的操做 ..Module语法是JavaScript模块的标准写法,坚持使用这种写法。使用 import 取代 require 。 -------------------------------

相关文章
相关标签/搜索