ECMA的历史:
- 早期的 ECMA版本是 ECMA-262 标准,可以俗称 1.0
- 后续好几年,不断提案不断改进,后来一直到2011年,版本其实到了 ECMA5.x了
- 后来为了统一版本,标准委员会最终决定,标准在每年的 6 月份正式发布一次,作为当年的正式版本
- 在2015年6月,ES6正式发布,后续的小版本可能是 6.1,6.2.... 也可以用年来标记
- 所以ES2015才是正规的 ES6的名称
- 而,2016年6月,也发布一个版本(这个版本新增了一个数组的 includes和幂运算符),其实是ES6.1,或者叫ES2016,有人也俗称ES7,其实这个称呼,不太对
- 2017年6月,发布了几个改动(async await), 名字应该叫 ES2017,有人说ES8,我的天。
- 2018年6月, 还是会发布几个改动,其实都应该叫ES6,或者以年份命名。
- 聪明的开发者,现在都不叫ES7 8了, 叫 ESnext, 特指,"下一代 JavaScript 语言"
总结:
2015年6月 ES6正式推出, 叫 ES2015
2016年6月 ES6.1推出, 叫ES2016
2017年6月 ES6.2推出, 叫ES2017
或者叫: ESnext
- 现在是开源的世界:
任何人都可以向标准委员会(又称 TC39 委员会)提案,要求修改语言标准
一种新的语法从提案到变成正式标准,需要经历五个阶段。每个阶段的变动都需要由 TC39 委员会批准。Stage 0 - Strawman(展示阶段) Stage 1 - Proposal(征求意见阶段) Stage 2 - Draft(草案阶段) Stage 3 - Candidate(候选人阶段) Stage 4 - Finished(定案阶段) 一个提案只要能进入 Stage 2,就差不多肯定会包括在以后的正式标准里面。ECMAScript 当前的所有提案,可以在 TC39 的官方网站Github.com/tc39/ecma262查看。
ES6环境搭建 (目前ES6的大部分属性已经被浏览器支持,所以可以不用babel)
现在不像以前了,IE可以忽略,像chrome等都是标准委员之一,定制好,基本浏览器下一个版本就逐渐支持,所以速度还是挺快的
webpack3.0 编译 babelrc 配置 Google 公司的Traceur转码器 cnpm install babel-cli -g 需要依赖包: babel-preset-es2015 babel-cli 安装 live-server 或者webpack3.0配置
let、 const、块级代码作用域
let、const 有块级代码作用域
之前var只有在函数里面才有作用域一说
ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。
- 块级作用域可以任意嵌套
{{{let a = 10}}} - // IIFE 写法
(function () {
var tmp = ...;
...
}());
// 块级作用域写法
{
let tmp = ...;
...
}
let注意的地方:
1. 没有预解析,不存在变量提升 但是有 TDZ,暂时性死区 ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。 let a=1; if(true){ //TDZ开始 (temporal dead zone,简称 TDZ) 暂时性死区 console.log(a); let a=12; //TDZ 结束 } 总结: 在代码块内,只要在let定义变量之前使用,都是有问题的 2. 不能重复定义 3. 特殊的for循环,for循环里面是父级作用域,里面又一个作用域 for(let i=0; i<3; i++){ let i='abc'; console.log(i); } 例子: 关于循环的 i, 选项卡索引 var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10 ----------------------------------- const和let差不多,只不过人家是常量,不能改变: const a =['a','b']; a.push('c'); console.log(a); ---------------------- const a = Object.freeze(['a','b']); a.push('c'); console.log(a);
- 解构赋值
非常有用,特别是数据交互的时候,后台传过来一堆数据,你需要挑选你想要的就好
注意: 两边结构需要一直
a). 数据解构赋值:
let [a='abc']=[] 解构默认值(里面填写undefined和null的区别)
let [a, b='banana'] = ['aaa', undefined]; 和 let [a, b='banana'] = ['aaa', null];
b). 对象解构赋值:
let {a,b} = {a:'apple', b:'banana'};一个小坑: let a; {a} = {a:'apple'} 需要写成这种 ({a} = {a:'apple'} ) 例子: 函数传参解构 let json={a:'111', b:'222'} function fn({a, b='Strive'}){ console.log(a,b); } fn(json); ------------------------------ 封装运动函数: 参数默认值 function doMove({x=0, y=0}={}){ console.log(x, y); } doMove({x:0, y:0}); doMove({x:10});
c). 字符串解构赋值:
const [a,b,c] = 'wel'; 平时工作用的不多解构赋值的用途:
- 交换两个数的位置
let x = 5;
let y = 12;
let [y,x] = [x, y];
console.log(x, y); - 函数返回多个值
- 提取 JSON 数据
let jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
};let { id, status, data: number } = jsonData; console.log(id, status, number); // 42, "OK", [867, 5309]
- import 模块的时候解构
- 封装框架的默认参数
function ajax(url,{
type='get',
fnSucc=function(){},
fnFail=function(){},
data={}
}){
console.log(
url,
type,
fnSucc,
fnFail,
data
)
}ajax('http://www.baidu.com',{type:'post'});
===================================================
- 交换两个数的位置
- 字符串模板
`` ${}
好处:
支持换行字符串查找:
ES5 -> str.indexOf()
ES6 -> str.includes(xx)str.startsWith(xx) 判断字符串开头 str.endsWith(xx) 判断字符串结尾 str.repeat(3) 字符串的复制 字符串填充:padStart和padEnd 'x'.padStart(指定字符串的最小长度, 补全的字符串); 'x'.padStart(5, 'ab') // 'ababx' 'xxx'.padStart(2, 'ab') // 'xxx
- 函数的变化 扩展运算符和rest运算符
- 函数参数的默认值
function fn(a='欢迎',b='mmr'){
console.log(a, b);
}
fn('welcome','牧码人');
fn('welcome','');
fn('welcome'); - 函数参数变量默认是声明的,不能再用let或者const声明
function foo(x = 5) {
let x = 1; // error
const x = 2; // error
} - 配合对象解构,如果不默认赋值会报错
function foo({x, y = 5} = {}) {
console.log(x, y);
}
foo() // undefined 5 - reset参数, (剩余参数), 必须放到最后
例子1: function fn(...args){ //求和,不用arguments了,为何,因为有箭头函数}
fn(1,2,3,4,5)
例子2: 排序
function fn(...numbers){
return numbers.sort();
}
fn(3,2,-10,90,100);
箭头函数:
=>
注意:- this问题,就是定义时所在的对象,而不是使用时所在的对象
之前有过开发js的经验,都知道this简直令人丧心病狂 - 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误
- 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
- this问题,就是定义时所在的对象,而不是使用时所在的对象
//函数传入数组
function fn(a,b,c){
console.log(a,b,c);
}
fn(...[1,2,3])例子: 复制数组
循环
Array.from()
[...arr1]rest运算符:
function fn(arg1,...args){}for of 循环
ES2017允许函数参数最后有尾逗号
function fn(a,b,){
console.log(a,b);
}
fn(1,2,) - 函数参数的默认值
参考资料: https://space.bilibili.com/52140273?spm_id_from=333.338.v_upinfo.2#/channel/detail?cid=32135