博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
教你快速入门ES6
阅读量:7232 次
发布时间:2019-06-29

本文共 10918 字,大约阅读时间需要 36 分钟。

什么是ES6?

ECMAScript 6.0 (下面简称ES6)是继ECMAScript5.1之后,javascript语言的下一代标准,发布于2015年6月。它的目标,是使得javascript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。下面将介绍ES6的一些新语法,使其在开发中更加语法简洁,效率更高。

1、变量声明const和let

在ES6之前,我们都是用var关键字声明变量。无论声明在何处,因为函数变量的提升,都会被视为声明在函数的最顶部(不在函数内即在全局作用域的最顶部)。例如:

function f(){            var flag=""            if(flag){                var test = "hello,world";            }else{                console.log(test);              }        }        f();复制代码

以上代码实际是:

function f(){            var flag="";            var test;  //变量提升到函数最顶部            if(flag){                var test = "hello,world";            }else{                console.log(test); //这里访问的test,值为undefined             }        }        f();复制代码

所以不用关心flag是否为 true还是false。实际上,无论如何 test 都会被创建声明。

ES6出现后,我们一般用 letconst 来声明,let 表示变量、const 表示常量。letconst 都是块级作用域。怎么理解这个块级作用域?

说白了只要在{}花括号内的代码块即可以认为 let 和 const 的作用域。

看下面代码:

function f(){            var flag="";            if(flag){                let test = "hello,world";            }else{                console.log(test); //这里访问不到test,打印出test is not defined            }        }      f();复制代码

let 的作用域是在它所在当前代码块,但不会被提升到当前函数的最顶部。

const 声明的变量必须提供一个值,而且会被认为是常量,意思就是它的值被设置完成后就不能再修改了。

const a=1;a=2; //就会报这样的错误:Assignment to constant variable.复制代码

还有一点,如果 const的是一个对象,对象所包含的值是可以被修改的。也就是说,对象所指向的地址不能改变,而变量成员是可以修改的。如下面代码:

const obj = {name:"xiaoqinag"}obj.name = "wangcai"console.log(obj.name); //wangcai复制代码

2、解构赋值

按照一定模式,从数组和对象中提取,对变量进行赋值,称为解构。

2.1、数组的解构赋值

//一般赋值var a=1,b=2,c=3;var [a,b,c] = [1,2,3];console.log([a,b,c]);复制代码
//解构赋值var [a, b, c] = [1, 2, 3];console.log([a, b, c]);复制代码

当然不仅仅是var,let和const也可以

let arr = [1, 2, 3];const [a,b,c] = arr;console.log([a, b, c]);复制代码

解构赋值允许指定默认值

看下面代码:

let [a,b,c=666] = [1, 2, 3];console.log(a);  //1console.log(b);  //2console.log(c);  //3复制代码

也就是说解构赋值的值级别高于自身的值。

let [a=1,b,c=3] = [];console.log(a);  //1console.log(b);  //undefinedconsole.log(c);  //3复制代码

上面代码说明了:数组解构赋值时,会先找解构赋值的值,然后再找自身的值,如果前两者都没有,会返回undefined.

2.2对象的解构赋值

解构可以用于数组,同样也可以用于对象。对象的解构与数组有一个重要的不同,数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

// 变量名与属性名一致的情况下 let{name,age} = {name:"wangcai",age:25} console.log(name);  //wangcai console.log(age);   //25 //变量名与属性名不一致的情况下,必须这样写 let {a : name, b : age} = {a : 'xiaoqinag', b : 30}; console.log(name); //xiaoqinag console.log(age);  //30复制代码

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

let {a : name} = {a : 'xiaoqinag'}; console.log(name); //xiaoqinag console.log(a);  //a is not defined复制代码

上面代码中,a是匹配的模式,name才是变量。真正被赋值的是变量name,而不是模式a。

数组本质是特殊的对象,因此可以对数组进行对象属性的解构。

let arr=["laifu","wnagcai","xiaoqiang"]; let {0:first,1:center,[arr.length - 1]:last} = arr console.log(first); //laifu console.log(center); //wnagcai console.log(last);  //xiaoqiang复制代码

3、数组的扩展

3.1 Array.from()

Array.from方法用于将两类对象转为真正的数组:类似数组的对象和可遍历的对象。

let obj={           "name":"wangcai",           "age":34,           "sex":"man"       }       let arr=Array.from(obj)             console.log(Array.isArray(arr));  //true复制代码

3.2 Array.of()

作用:将一组值转换为数组。与Array.from功能相似,理解用来创建数组。主要目的是弥补构造器 Array()的不足。

之前使用new创建数组的痛点:

var arr1=[];var arr2 = new Array(3);var arr3 = new Array("3");console.log(arr1,arr2,arr3); //[] [empty × 3]  ["3"]复制代码

使用Array.of来改造,如下:

var arr1 = Array.of(3);var arr2 = Array.of("3");console.log(arr1,arr2); //[3]  ["3"]复制代码

3.3 find()和findIndex()

find:用于找出第一个符合条件的数组元素。找不到则是undefined。注意,它是不会返回多个,只找一个,找到了就返回。

findIndex:返回第一个符合条件的数组元素的索引。找不到则是-1;

let arr=[            {name:"xiaoqiang",age:23},            {name:"wangcai",age:25},            {name:"laifu",age:34}        ]        let rs = arr.find(function(item){            return item.name =="laifu";        })        console.log(rs);  //{name: "laifu", age: 34}                let res = arr.findIndex(function(item){            return item.name =="wangcai";        })        console.log(res);   //1复制代码

3.4 includes()

作用:判断元素是否在数组中存在。返回值是 true | false

代码如下:

let arr = [1, 2, 3];        console.log(arr.includes(3));  //true        console.log(arr.includes(6));  //false复制代码

indexOf也可以做类似的工作,如下:

let arr = [1, 2, 3];        console.log(arr.indexOf(3));  //2        console.log(arr.indexOf(6));  //-1复制代码

但是,indexOf 对 NaN的判断是错误的,如下:

let arr = [NaN, 2, 3];        console.log(arr.indexOf(NaN));  //-1复制代码

上面代码可以得到indexOf对NaN的判断是错误的,而includes()则没有这个问题。

3.5 fill()

作用:给数组填充指定值。fill方法用于空数组的初始化非常方便。已有数据会被覆盖。fill 方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。 代码如下:

let arr = new Array(5);        arr.fill("*");        console.log(arr); //["*", "*", "*", "*", "*"]  //["*", "*", "*", "*", "*"]复制代码

使用fill()会覆盖之前的元素,代码如下:

let arr =[1,2,3,4];        arr.fill("*");        console.log(arr); //["*", "*", "*", "*"]复制代码

fill()还可以指定填充位置,如下:

let arr = [1,2,3,4,5,6]        arr.fill("*",2,4);        console.log(arr); //[1, 2, "*", "*", 5, 6]复制代码

2 和 4表示下标,包括起点,不包括终点。

4、数组的扩展运算符

功能:把数据结构转成数组。

let arr = [1,2,3,4,5,6]        let arr2 = [...arr]        console.log(arr2); // [1, 2, 3, 4, 5, 6]复制代码

可以这样理解:

var arr2 = [ ...arr ];

  • [ ]表示一个数组。即 arr2 是一个数组。
  • ...arr :把数组 arr 展开。理解分解起一个一个的元素
  • 相当于实现了,数组的复制---这里是浅拷贝

还可以利用扩展运算符,把类数组转成数组,如下:

  • 1
  • 2
  • 3
  • 4
  • 5
复制代码

把一个类数组转成数组有如下几种方式:

  • Array.prototype.slice.call();
  • Array.from();
  • [...类数组对象]

把字符串转成数组,如下:

var str = "hello";    var arr =[...str];    console.log(arr); //["h", "e", "l", "l", "o"]复制代码

还可以利用扩展运算符来合并数组,如下:

var arr1 = [1,2];    var arr2 = [3,4];    var arr =[arr1,...arr2];    console.log(arr);  //复制代码

5、箭头函数

ES6可以使用“箭头”(=>)定义函数,注意是函数,不要使用这种方式定义类(构造器)。

5.1 语法

之前的函数写法:

function f(x){        return x*x;    }    let rs = f(2)    console.log(rs);  //4复制代码

箭头函数如下:

var f=(x)=>{        return x*x;    }    let rs = f(2)    console.log(rs);  //4复制代码

再改进,如果箭头函数中只有一个形参,那么()可以不写,如下:

var f=x=>{        return x*x;    }    let rs = f(2)    console.log(rs);  //4复制代码

如果函数体只有一条语句(非return语句),那么{}也可以不写,如下:

var f=()=>    console.log("hello world");  //hello world    f()复制代码

如果有return 语句,把{}和reutrn 都可以省略了,如下:

var f=x=>x*x;    console.log(f(2));  //4复制代码

5.2 注意点

1、this固定,不再善变

obj = {       data: ['wangcai', 'xiaoqiang'],       init: function () {           document.onclick = ev => {              console.log(this.data); // ['wangcai', 'xiaoqiang']           }           // 非箭头函数           // document.onclick = function(ev) {           //     console.log(this.data) // undefined           // }       }   }   obj.init()复制代码

2、箭头函数不能用new

var Person = (name, age) => {this.name = namethis.age = age}var p = new Person('wangcai', 33) //Person is not a constructor复制代码

3、不能使用argument

var func = () => {   console.log(arguments)}func(55) //arguments is not defined复制代码

4、instanceof也返回true,表明也是Function的实例

var func = () => {}console.log(func instanceof Function);  //true复制代码

6、模板字符串

ES5中采用 + 进行拼接,着实麻烦,ES6解决了ES5在字符串功能上的痛点,简直是开发者的福音。

1、基本的字符串格式化。将表达式嵌入字符串中进行拼接。用${}来界定。

//es5语法var name = "wangcai";console.log("hello"+name);  //hellowangcai//es6语法var  name = "xiaoqiang";console.log(`hello ${name}`); //hello xiaoqiang复制代码

2、如果使用模版字符串表示多行字符串,所有的空格和缩进都会被保存在输出中。

console.log(`It's       raining today`);//It's       raining // today复制代码

3、在${}中的大括号里可以放入任意的JavaScript表达式,还可以进行运算,以及引用对象属性。

let a = 12;let b = 22;let c = "";console.log(`c=a+b=${a+b}`); //c=a+b=34复制代码

4、更强大的是:模版字符串还可以调用函数。

function string(){    return "Learning ES6!!";}console.log(`你今天在做什么?             ${string()}`);  //你今天在做什么?             //Learning ES6!!复制代码

7、Set 和 Map 数据结构

7.1 Set

ES6 提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。 代码如下:

var arr=[1,2,3,1,5,2];var s = new Set(arr);console.log(s);   //{1, 2, 3, 5}复制代码

使用add()来添加,如下:

var s = new Set();s.add(1);s.add(2);s.add(3);s.add(4);console.log(s);  //{1, 2, 3, 4}复制代码

可以使用forEach遍历s,如下:

var s = new Set();s.add(1);s.add(2);s.add(3);s.add(4);s.forEach(item=>console.log(item)  //1  2  3  4)复制代码

set不是数组,是一个像对象的数组,是一个伪数组,使用Array.isArray测试如下:

var s = new Set();s.add(1);s.add(2);s.add(3);s.add(4);console.log(Array.isArray(s));  //false复制代码

删除set其中的一个元素,如下:

var s = new Set();s.add(1);s.add(2);s.add(3);s.add(4);s.delete(2)console.log(s); //{1, 3, 4}复制代码

可以使用Set实现数组的去重的问题,简洁明了,代码如下:

var arr = [1,2,7,9,2,7];var arr1 = [...(new Set(arr))];console.log(arr1);  //[1, 2, 7, 9]复制代码

7.2 Map

Map类似于对象,里面存放也是键值对,区别在于:对象中的键名只能是字符串,如果使用map,它里面的键可以是任意值。 创建Map,如下:

var m = new Map([    ["a","hello"],    ["1","123"]]);console.log(m);  //{
"a" => "hello", "1" => "123"}复制代码

使用set进行添加,如下:

var m = new Map([    ["a","hello"],    ["1","123"]]);m.set(false,"abc");m.set([1,2,3],{name:"wangcai"})console.log(m);  //{
"a" => "hello", "1" => "123", false => "abc", Array(3) => {…}}复制代码

还可以获取,通过get(键),如下:

var m = new Map([    ["a","hello"],    ["1","123"]]);m.set(false,"abc");m.set([1,2,3],{name:"wangcai"})console.log(m.get("a"));  //hello复制代码

但是,使用m.get([1,2,3]),获取不到值,原因是get()是要比较栈区中的地址,而不是堆区中的数据,可以使用下面这个方法使m.get([1,2,3]),获取到值。

var m = new Map([    ["a","hello"],    ["1","123"]]);m.set(false,"abc");console.log(m.get("a"));  //hellolet a=[1,2,3];m.set(a,{name:"wangcai"})console.log(m.get(a));  //{name: "wangcai"}复制代码

重复的键会覆盖,如下:

var m=new Map();m.set(1,"aaa");m.set(1,"bbb");console.log(m);  //Map(1){1 => "bbb"}复制代码

8、Class 的基本语法

ES6 提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。

8.1class创建对象

在ES6中,可以使用class来声明一个类了,如下:

class Person{        constructor(name,age,height){            this.name = name;            this.age = age;            this.height = height;        }        say(){            console.log(`我叫${this.name},今年${this.age}岁,身高为${this.height}`);          }    }    var p = new Person("旺财","23","187");    console.log(p.say());  //我叫旺财,今年23岁,身高为187复制代码

注意:

  • class 是关键字,后面紧跟类名,类名首字母大写,采取的是大驼峰命名法则。类名之后是{}。
  • 在{}中,不能直接写语句,只能写方法,方法不需要使用关键字
  • 方法和方法之间没有逗号,不是键值对。

8.2 类的静态方法 static

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

class Person{       static say(){            console.log("hello world");          }    }    var p = new Person();   Person.say()  //hello world   p.say();  //p.say is not a function复制代码

上面代码中,Person类的classMethod方法前有static关键字,表明该方法是一个静态方法,可以直接在Person类上调用(Person.classMethod()),而不是在Person类的实例上调用。如果在实例上调用静态方法,会出现一个错误,表示不存在该方法。

8.3 使用extends实现继承

使用ES6中的extends来实现继承,代码如下:

class Person{        constructor(name,age,height){            this.name = name;            this.age = age;            this.height = height;        }       say(){            console.log(`我叫${this.name},今年${this.age}岁,身高为${this.height}`);          }    }    class Student extends Person{        constructor(name,age,height,profession){            super(name,age,height)            this.profession = profession;        }        showProfession(){            console.log(`我叫${this.name},是一个${this.profession}`);                    }    }    var s = new Student("旺财","23","187","学生");    s.say()             //我叫旺财,今年23岁,身高为187    s.showProfession()  //我叫旺财,是一个学生复制代码

注意:

  • 使用 extends 关键字来实现继承。
  • 在子类中的构造器 constructor 中,必须要显式调用父类的 super。 方法,如果不调用,则 this 不可用。

总结

ES6新特性远不止于此,本文列举的是一些常见的特性,在日常开发中,能算得上是使用率较高的了,能够正确的使用这些新特性,可以使你的开发事半功倍。

转载于:https://juejin.im/post/5b6e3a1ee51d45190d55a436

你可能感兴趣的文章
C++和java中构造函数与析构函数的调用顺序
查看>>
第一届《FineUI 你写博客,我送书》活动开始了!
查看>>
超酷!纯CSS3烧烤动画实现教程
查看>>
看日记学git摘要~灰常用心的教程
查看>>
中山大学2016年数学分析高等代数考研试题参考解答及其讲解
查看>>
ASP.NET MVC 4 RC的JS/CSS打包压缩功能
查看>>
html5 css3构造的漂亮表格
查看>>
m2014_c->c语言容器类工具列
查看>>
spider-抓取网页内容
查看>>
HTML5翻页电子书
查看>>
Python 数据类型:列表
查看>>
在Ubuntu下安装和配置Rails 3详解 (LightTPD + FastCGI)
查看>>
DRBD试用手记
查看>>
argparse – Command line option and argument parsing.¶
查看>>
UML 图使用心得
查看>>
《肖申克的救赎》- 阅后小记
查看>>
Zookeeper系列五:Master选举、ZK高级特性:基本模型
查看>>
关于 DataRow 中为 DataRowState.Deleted 状态的 字段列值取值方法
查看>>
nginx配置解决vue单页面打包文件大,首次加载慢的问题
查看>>
win7方面API學習
查看>>