1. 什么是ES?
ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准。
2. let和const
在ES6以前,Javascript并不同有块级作用域的概念,有的是函数作用域,而let的出现就是为了打破局面,有点向后台语言发展的趋势。const是代表常量,必须在定义的时候初始化,不可改变。下面我举例子说明。
window.onload = function(){
var aInput = document.getElementsByTagName("input");
// 传统解决办法
for(var i=0;i<aInput.length;i++){
(function(i){
// 函数闭包自执行来解决i索引的问题
aInput[i].onclick = function(){
alert(i);
};
})(i);
}
// let变量的出现相当于给你加了一个封闭空间来极度简化了i值索引的问题
// let大家可以看成是匿名函数立即调用(IIFE)
for(let i=0;i<aInput.length;i++){
aInput[i].onclick = function(){
alert(i);
};
}
};
//对于let和const来说,变量不能重新声明,所以一旦赋值的变量以前声明过,就会报错,而以前var的时候并不会报错,只是覆盖定义
let a = 12;
let a = 13; //Identifier 'a' has already been declared
//const必须在初始化的时候同时赋初值,且不能更改
const b; //Uncaught SyntaxError: Missing initializer in const declaration
const b = 14;
b = 15; //Uncaught TypeError: Assignment to constant variable.
3. 字符串模板
//传统字符串拼接
var s1 = '快乐童年放飞希望^_^';
var s2 = '^_^';
var str = '2013年5月29日,'+s2+'北京市少年宫参加“'+s1+'”主题队日活动。这是在和孩子们谈对环保的认识和'+'理解。新华社记者李学仁摄';
document.write(str);
// 字符模板的写法
var s1 = '快乐童年放飞希望^_^';
var s2 = '^_^';
var str = `2013年5月29日,${s2}在北京市少年宫参加“${s1}”主题队日活动。这是在和孩子们谈对环保的认识和理解。 新华社记者李学仁摄`;
document.write(str);
4.解构赋值
// 以前我们给变量赋值,只能直接指定值
var a = 1;
var b = 2;
var c = 3;
console.log(a,b,c); // 1 2 3
// 现在用解构赋值的写法就变得简单了,只要模式匹配上了就行了,如下
// 注意数组是有顺序的
var [a,b,c] = [11,22,33];
console.log(a,b,c); // 11 22 33
var [b,a,c] = [11,22,33];
console.log(a,b,c); // 22 11 33
// 当然解构赋值还有嵌套比较复杂的写法,如下
let [foo,[[bar],[baz]]] = [111,[[222],[333]]];
console.log(foo,bar,baz); // 111 222 333
let [head,...foot] = [1,2,3,4];
console.log(head,foot); // 1 [2,3,4]
// 如果解构不成功,变量的值就等于undefined,如下
var [bar3,foo3] = [1000];
console.log(bar3,foo3); // 1000 undefined
// 另一种情况是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功
let [x,y] = [10000,20000,30000];
console.log(x,y); // 10000 20000
// 默认值可以引用解构赋值的其他变量,但该变量必须已经声明
let [a=1,b=a] = [2,3];
console.log(a,b); // 2 3
// 对象的解构也可以指定默认值
var {x,y=5} = {x:1};
console.log(x,y); // 1 5
//对象的解构赋值解构不仅可以用于数组,还可以用于对象(json)
//对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;
//而对象的属性没有次序,变量必须与属性同名,才能取到正确的值
var {a,b} = {a:'apple',b:'banana'};
console.log(a,b); // apple banana
var {b,a} = {a:'apple',b:'banana'};
console.log(a,b); // apple banana
// 如果变量名与属性名不一致,必须写成下面这样
let obj = {first:'hello',last:'world'};
// first ---> f,那么此时f就是first,而不是undefined了,有点类似别名的概念
let {first:f,last} = obj;
console.log(f,last); // hello world
//1.也就是说,对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。 真正被赋值的是后者,而不是前者
//2.v是匹配的模式,n才是变量。真正被赋值的是变量n,而不是模式v。
//注意,采用这种写法时,变量的声明和赋值是一体的
// v ---> n,那么此时n就是vue,而不是undefined了
var {v:n} = {v:'vue',r:'react'};
console.log(n); // vue
console.log(v); // Uncaught ReferenceError: v is not defined
console.log(r); // Uncaught ReferenceError: r is not defined
5.复制数组
// 数组的浅拷贝,引用之间的拷贝,没有实现数组的真正复制
var arr1 = [1, 2, 3];
var arr2 = arr1;
arr2.push(4);
console.log(arr1, arr2);
// 复制数组深拷贝,传统做法
var arr1 = [1,2,3];
var arr2 = [];
//通过for循环遍历之后将arr1数组的每一项赋值给arr2数组的每一项, 就实现了数组的深拷贝,这时候我再去操作arr2的数组的时候,arr1就不会受影响了
for(var i=0;i<arr1.length;i++){
arr2[i] = arr1[i];
}
// 数组尾部添加
arr2.push(4);
console.log(arr1,arr2);
// ES6实现的数组的深拷贝方法1
var arr1 = [1,2,3];
var arr2 = Array.from(arr1);
// 数组尾部添加
arr2.push(100);
console.log(arr1,arr2);
// ES6实现的数组的深拷贝方法2
var arr1 = [1,2,3];
// 超引用拷贝数组
var arr2 = [...arr1];
// 数组尾部添加
arr2.push(1000);
console.log(arr1,arr2);
function show(...args){
// 此时这个形势参数就是一个数组,我们可以直接push东西进来,如下
args.push(5);
console.log(args);
}
// 调用
show(1,2,3,4); // 1,2,3,4,5
6. Map
var map = new Map();
// 设置
// map.set(name,value);
map.set('a','apple');
map.set('b','banana');
// 获取
// map.get(name);
console.log(map.get('a') + ' ' + map.get('b'));
// 删除之前map对象
console.log(map);
// 删除
// map.delete(name);
map.delete('a');
// 删除之后map对象
console.log(map);
// 注意for..in是不能循环map对象的,不报错也无任何反应,稍微注意下
for(var name in map){
console.log(name);
}
// 实体 map=map.entries()
for(var name of map){
//循环出来的结果就是:a,apple b,banana 循环key,value
console.log(name);
}
//循环出来的结果就是: a,apple b,banana 循环key,value
for(var [key,value] of map.entries()){
console.log(key,value);
}
//只循环key
for(var key of map.keys()){
console.log(key);
}
//只循环value
for(var val of map.values()){
console.log(val);
}
7. 箭头函数
//箭头函数写法 function(){} 变为 ()=>{}
window.onload = () => {
var oBox = document.getElementById("box");
oBox.onclick = () => {
oBox.style.backgroundColor = '#ff0000';
};
};
//注意this指向会有问题
var json = {
a:1,
b:2,
showName:() => {
return this.a;
}
};
// 因为使用了箭头函数this指向了object window 所以result:undefined
console.log(json.showName());
//如果使用了箭头函数的写法,那么注意arguments将不能继续使用了
var show = () => {
console.log(arguments);
};
// Uncaught ReferenceError: arguments is not defined
show(1,2,3);
8. 对象的简洁语法
//传统对象_单体模式写法 key-value模式
var person = {
name:'jam',
age:28,
showName:function(){
return this.name;
},
showAge:function(){
return this.age;
}
};
// 调用
console.log(person.showName()); // jam
console.log(person.showAge()); // 28
//ES6_单体模式写法 不需要写key
var name = 'xiaokai';
var age = 2;
var person = {
name,
age,
showName(){
return this.name;
},
showAge(){
return this.age;
}
};
// 调用
console.log(person.showName()); // xiaokai
console.log(person.showAge()); // 2