ECMAScript 6

定义变量:

let

之前:var a = 12;
现在:let a = 12;
代码块:用{}包含起来的代码,比如if、for、while

  • let特点:只能在代码块里面使用
  • var 只有函数作用域
1
2
3
4
5
6
7
8
9
10
11
{
let a = 12;
alert(a); //弹出12;
}
alert(a); //报错,a is not defined
{
var a = 12;
alert(a); //弹出12;
}
alert(a); //弹出12
1
2
3
4
5
6
7
var a = 12;
var a = 5;
alert(a); //弹出12
let a = 12;
let a = 5;
alert(a); //报错,a已经被声明过了
  • let 具备块级作用域
  • 不能重复声明
    总结:其实let才是接近其他语言的变量

用处
封闭空间:

1
2
3
4
5
6
以前:(function(){
//code...
})();
现在:{
//code...
}
1
2
3
4
5
6
7
8
9
10
11
(function(){
var a = 12;
alert(a); //弹出12;
})();
alert(a); //报错,a is not defined
{
let a = 12;
alert(a); //弹出12;
}
alert(a); //报错,a is not defined

i值问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var aBtn = document.getElementsByTagName("input");
for(var i = 0;i<aBtn.length;i++){
aBtn[i].onclick = function(){
alert(i); //这肯定是错的,加入页面上有3个btn,那么总弹出3
}
}
解决办法:使用封闭空间
以前:
var aBtn = document.getElementsByTagName("input");
for(var i = 0;i<aBtn.length;i++){
(function(index){
aBtn[index].onclick = function(){
alert(index);
}
})(i);
}
现在:将var改为let
var aBtn = document.getElementsByTagName("input");
for(let i = 0;i<aBtn.length;i++){
aBtn[i].onclick = function(){
alert(i);
}
}

总结:块级作用域其实就是匿名函数立即调用

const

1
2
3
4
5
6
7
8
9
10
11
var a = "组件"
a = 12;
alert(a); //弹出12
let a = "大组件"
a = 12;
alert(a); //弹出12
如果定义一个常量,我们用const
const a = "大组件"
a = 5; //试图修改常量会报错

const用来定义常量,一旦赋值,以后再也修改bu不了了,而且必须一次性赋完值

const a; a = 12;这样是错的。

注意:const必须给初始值,因为以后再也无法赋值了。并且不能重复的声明。

字符串连接

之前:

“abc” + 变量名 + “ef”

1
2
3
var a = "a";
var e = 'e';
var str = a + "bcd" + e + "fg";

现在:

`abc${变量名}ef`

1
2
3
var a = "a";
var e = "e";
var str = `${a}bdc${e}fg`; //反单引号

解构赋值

1
2
3
4
5
6
7
8
9
var [a,b,c] = [12,5,101];
console.log(a,b,c); //12,5,101
var {a,b,c} = {a:12,b:5,c:101};
console.log(a,b,c); //12,5,101
var {a,b,c} = {b:5,a:12,c:101};
console.log(a,b,c); //12,5,101
我们可以发现,json解构跟顺序无关,因为json本身就是无序的

模式匹配

左侧的样子需要和右侧一样

1
2
3
4
匹配[12,[1,2],5]
var [a,[b,c],d] = [12,[1,2],5];
var [{a,e},[b,c],d] = [{e:"eee",a:"aaa"},[1,2],5];

交互:

[{“title”:””,”href”:””,”img”:””}];

解构赋值还可以给默认值:

var json = {};

var a = json.a || 12;

语法:

var {time=12,id=0} = {};

1
2
3
4
5
function getPos(){
return {left:100,top1:1000}
}
var {left,top1} = getPos();
console.log(left,top1); //100,1000

复制数组

  • 循环

    1
    2
    3
    4
    5
    6
    7
    var arr = [1,2,3];
    var arr2 = [];
    for(var i = 0;i<arr.length;i++){
    arr2[i] = arr[i];
    }
    arr2.pop();
    console.log(arr,arr2); //[1,2,3],[1,2]
  • Array.from

    1
    2
    3
    4
    var arr = [1,2,3];
    var arr2 = Array.from(arr);
    arr2.pop();
    console.log(arr,arr2); //[1,2,3],[1,2]
  • var arr2 = […arr];

    1
    2
    3
    4
    var arr = [1,2,3];
    var arr2 = [...arr];
    arr2.pop();
    console.log(arr,arr2); //[1,2,3],[1,2]
    • …的用法
    1
    2
    3
    4
    5
    function show (){
    arguments.push(4);
    console.log(arguments); //报错arguments.push is not a function
    }
    show(1,2,3);
    1
    2
    3
    4
    5
    function show (...args){
    args.push(4);
    console.log(args); //[1,2,3,4]
    }
    show(1,2,3);

循环

普通for循环

for in循环

新增了for of循环:用来遍历(迭代、循环)整个对象,表现有点类似于for in

1
2
3
4
var arr = ["apple","banana","orange"];
for(var i in arr){
console.log(i); //0,1,2 是索引key
}
1
2
3
4
var arr = ["apple","banana","orange"];
for(var i of arr){
console.log(i); //apple,banana,orange 是值value
}

for of循化可以循环数组,不能循环json。而它真正的目的是为了循环 map对象

map对象

​ 和json相似,也是一种key-value形式。

​ map对象为了和for of循环配合而生的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var map = new Map();
//设置:map.set(name,value)
map.set("a","apple");
map.set("b","banana");
console.log(map); // {"a" => "apple", "b" => "banana"}
//获取:map.get(name)
console.log(map.a); //undefined 说明这样获取不对
console.log(map.get("a")); //apple,获取的正确姿势
//删除:map.delete(name)
delete map.a;
console.log(map); //{"a" => "apple", "b" => "banana"} 说明删除失败
map.delete("a"); //{"b" => "banana"}删除的正确姿势

注意:遍历map不能使用for in,使用for in没有效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var map = new Map();
map.set("a","apple");
map.set("b","banana");
map.set("c","orange");
for(var name of map){
//默认是键值对全有
console.log(name); //a,apple b,banana c,orange
}
for(var [key,value] of map){
console.log(key,value); //key value
}
for(var name of map.entries()){
console.log(name); //a,apple b,banana c,orange
}
for(var [key,value] of map.entries()){
console.log(key,value); //key value
}
//只循环key
for(var key in map.keys()){
console.log(key); //a,b,c
}
//只循环value
for(var value in map.values()){
console.log(value); //apple,banana,orange
}

for of 也可以循环数组

1
2
3
4
5
6
7
8
9
10
11
12
var arr = ["西游记","三国演义"];
for(var value of arr){
console.log(value); //"西游记","三国演义"
}
//只循环索引
for(var key of arr.keys()){
console.log(key); //0,1
}
//索引和值都循环
for(var some of arr.entries()){
console.log(some); [0, "西游记"] [1, "三国演义"]
}

箭头函数

函数:之前

1
2
3
4
function show(){
alert(1);
}
show();
1
2
3
4
function show(a){
return a;
}
show(12);
1
2
3
4
function show(a,b){
return a + b;
}
show(12,5);
1
2
3
4
5
6
对比:
var arr = [34,101,-100,90,98,77777];
arr.sort(function (a,b) {
return a - b;
});
console.log(arr); // [-100, 34, 90, 98, 101, 77777]
1
2
3
var arr = [34,101,-100,90,98,77777];
arr.sort((a,b)=>a-b);
console.log(arr); // [-100, 34, 90, 98, 101, 77777]
1
2
3
4
5
6
7
8
9
10
11
function show(a){ return a}
var show = a => a;
function show(a,b){ return a + b }
var show = (a,b) => a + b;
function show(){ return "welcome" }
var show = () => "welcome";
function show(){ alert(1) }
var show = () => { alert(1) }

注意:this的指向问题,this指向了window

1
2
3
4
5
6
7
8
9
var a = 101;
var json = {
a:1,
b:2,
show:() =>{
alert(this.a); //弹出结果是101
}
}
json.show(); //弹出结果是101,因为this指向了window

注意:arguments不能使用了

1
2
3
4
5
6
7
8
9
function show(){
console.log(arguments); // [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
}
show(1,2,3);
var show = () =>{
console.log(arguments); //报错:arguments is not defined
}
show(1,2,3);

对象

对象语法简洁化

单例模式:

1
2
3
4
5
6
7
8
9
10
11
var person = {
name:"Jack",
age:18,
showName: function(){
alert(this.name);
},
showAge:function(){
alert(this.age);
}
}
person.showName(); //弹出Jack
1
2
3
4
5
6
7
8
9
10
11
12
13
var name = "Jack";
var age = 18;
var person = {
name,
age,
showName(){
alert(this.name);
},
showAge(){
alert(this.age);
}
}
person.showName(); //Jack

面向对象

之前:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function Person(name,age){ //又是类,又是构造函数
this.name = name;
this.age = age;
}
Perosn.prototype.showName = function(){
return this.name;
};
Perosn.prototype.showAge = function(){
return this.age;
}
//Worker
function Worker(name,age,job){
Person.call(this.name,age);
this.job = job;
}
function F(){};
F.prototype = Person.prototype;
Worker.prototype = new F();
Worker.constructor = Worker;
var p = new Person("Jack",18);
var w = new Worker("Mary",16);
alert(p.showName); //弹出Jack
alert(w.showName); //弹出Mary

ES6里有类的概念了:

类 class

构造函数 constructor 生成完实例之后自己就执行的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Person{ //类
constructor(name="default",age=0){
this.name = name;
this.age = age;
}
showName(){
return this.name;
}
showAge(){
return this.age;
}
}
//继承
class Worker extends Person{
constructor(name,age,job="扫地的"){
super(name,age); //执行父级的constructor
this.job = job;
}
showJob(){
return this.job;
}
}
var p = new Person("Jack",18);
alert(p.showName()); //弹出”Jack“
var w = new Worker("Mary",19,"coder");
alert(w.showJob()); //弹出"coder"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Queue{
constructor(content = []){
this._queue = [...content];
}
shift(){
const vaule = this._queue[0];
this._queue.shift();
return value;
}
push(n){
this._queue.push(n);
return this._queue.length;
}
}
var q = new Queue([1234]);
q.shift();
q.push(5);
console.log(q._queue); //[2,3,4,5]

模块化

seajs、requirejs

ES6自带模块化

必须引入traceur和bootstrap,type必须写成module

如何定义(导出)模块:

1
2
const a = 12;
export default a;

如何使用(引用)模块

1
import modA from "a.js"
1
2
3
a.js:
const a = 12;
export default a;
1
2
3
b.js:
const a = 5;
export default b;
1
2
3
4
index.html:
import modA from "a.js";
import modB from "b.js";
console.log(modA + modB); //17

1
2
3
4
5
6
sum.js
import a from "a.js";
import b from "b.js";
export default function sum(){
return a + b;
}
1
2
3
index.html:
import sumMod from "sum.js";
console.log(sumMod()); //17

导出多个模块

1
2
3
4
c.js:
const a = 12;
const b = 5;
export default {a,b};
1
2
3
index.html:
import c from "c.js";
console.log(c.a + c.b);

Promise

promise—承诺

就是一个对象,用来传递异步操作的数据(消息)

三种状态:

  • pending:初始状态
  • fulfilled:成功的操作
  • rejected:失败的操作
1
2
3
4
5
6
7
8
9
var p = new Promise(function(resolve,reject){
if(异步处理成功了){
resolve(成功数据)
}else{
reject(失败原因)
}
});
p.then(onFilfulled,onRejected);
//接收两个函数作为参数,一个在fulfilled的时候被调用,一个在rejected的时候被调用,接收参数就是onFulfilled对应resolve,onRejected对应reject
1
2
3
4
5
6
7
8
var p = new Promise(function(resolve,reject){
resolve(1);
});
p.then(function(value){
alert("成功了:" + value); //弹出:"成功了:1"
},function(vaule){
alert("失败了:" + value);
})
1
2
3
4
5
6
7
8
9
var p = new Promise(function(resolve,reject){
//resolve(1);
reject(2);
});
p.then(function(value){
alert("成功了:" + value);
},function(vaule){
alert("失败了:" + value); //弹出:"失败了:2"
})
1
2
3
4
5
6
7
8
9
10
11
var p = new Promise(function(resolve,reject){
resolve(1);
});
p.then(function(value){
console.log(value); //1
return value + 1; //返回值,供下次使用
},function(vaule){
alert("失败了:" + value);
}).then(function(value){
console.log(value); //2
})

Generator

是一个函数,可以遍历,generator就是一个状态机

语法:

1
function show(){} //普通函数
1
2
3
function *show(){
yield xxx
} //generator函数

形式上:

  • 函数名字前面有*
  • 函数内部使用yield语句
1
2
3
4
5
6
7
8
9
10
11
function* show(){
yield "Hello";
yield "World";
yield "ES6";
}
var res = show();
console.log(res.next()); //{value:"Hello",done:false}
console.log(res.next()); //{value:"World",done:false}
console.log(res.next()); //{value:"ES6",done:false}
console.log(res.next()); //{value:undefined,done:true}
//最后一个为什么是undefined呢?因为函数没有返回值

总结:每次返回一个value的done的结果

value,每次yield后面的值

done,是一个布尔值,代表是否遍历结束

yield是否有返回值?

​ yield语句本身没有返回值,或者每次返回undefined

next可以带参数?

​ 给上一个yield值

for…of循环

​ 循环generator函数


本文结束,感谢阅读。

本文作者:melody0z
本文链接:https://melodyvoid/JavaScript/ecmascript-6.html
欢迎转载,转载请注明文本链接

坚持原创技术分享,您的支持将鼓励我继续创作!