ECMAScript 6
ES6 全稱ECMAScript 6 也叫ECMAScript2015
ES6的主要技術(shù)
1、變量、常量
2、取值賦值、解構(gòu)
3、運(yùn)算符的擴(kuò)展、展開運(yùn)算符、指數(shù)運(yùn)算符
4、字符串的擴(kuò)展
5、數(shù)組的擴(kuò)展
6、函數(shù)的擴(kuò)展
7、Set單值集合
8、Map鍵值對集合
9、對象的擴(kuò)展
10、生成器和迭代器與迭代器接口
11、反射Reflect
12、代理Proxy
13、Promise異步處理、async與await(ES7)
14、ES6的模塊化開發(fā)ESModule
15、CommonJS模塊化
let定義變量
之前我們在ES5里面,我們定義變量使用的是var關(guān)鍵字,這個關(guān)鍵字有幾個特點(diǎn)
1、var 沒有數(shù)據(jù)類型
2、var 是有一個建立階段
3、var 是沒有作用域的,它要通過函數(shù)才能形成作用域
var a = 1; //沒有數(shù)據(jù)類型的,所以任何類型的數(shù)據(jù)都可以賦值
//var沒有作用域
{
var a = "哈哈"
}
console.log(a);
//var有一個建立階段
console.log(c);
var c = 123;
var定義的變量是不夠嚴(yán)謹(jǐn)?shù)?/p>
ES6推出了let用于定義變量
1、let定義的變量也沒有數(shù)據(jù)類型
2、let沒有建立階段,必須先定義再使用
3、let定義的變量是有作用域的,以大括號作為作用域
暫時性死區(qū)
let定義變量是有作用域的,并且不能再定義之前調(diào)用
let a = "hello";
{
console.log(a); //這里是沒有問題的,因?yàn)閮?nèi)部的可以調(diào)用外部的變量
}
let b = "world";
{
console.log(b); //這里就形成了一個暫時性死區(qū),b變量調(diào)不出來
let b = "hello";
}
const常量
常量里面的數(shù)據(jù)是不能改變的,比如,Math.PI
const關(guān)鍵字聲明常量,它具備上面的let的所有特點(diǎn),同時不能改變值
const a = "hahaha";
a = "hehehehe"; //報錯
const聲明的常量鎖棧不鎖堆
首先,我們先要知道內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)分為 棧、堆、表、鏈
如果const聲明的常量里面保存的是一個引用數(shù)據(jù),那么根據(jù)鎖棧不鎖堆的原則,我們是可以改變數(shù)據(jù)中的屬性值的,但是無法覆蓋之前的整個數(shù)據(jù)
const常量定義的時候一定記得初始化,不然沒有任何意義
let與const的閉包特性
var btn = document.querySelectorAll("button");
for(var i = 0; i < btn.length;i++){
btn[i].addEventListener("click",function(){
console.log(i);
})
}
ES5閉包解決
for(var i = 0; i < btn.length;i++){
btn[i].addEventListener("click",(function(j){
var j = i;
return function(){
console.log(j)
}
})(i))
}
ES6閉包解決
var btn = document.querySelectorAll("button");
for(let i = 0; i < btn.length;i++){
btn[i].addEventListener("click",function(){
console.log(i);
})
}
解構(gòu)
一種特殊的取值賦值的方式
解構(gòu)取值:
1、數(shù)組解構(gòu)取值
var arr = ["張三","李四"];
// arr[0];
// arr[1];
let [a,b] = arr;
console.log(a);
console.log(b);
對于復(fù)雜的數(shù)組可以實(shí)現(xiàn)深度解構(gòu)
var arr = ["張三","李四",["王五","趙六"]];
// arr[0];
// arr[1];
let [a,b,[c,d]] = arr;
console.log(a);
console.log(b);
console.log(c);
console.log(d);
解構(gòu)實(shí)現(xiàn)變量置換
let a = 10;
let b = 20;
[a,b] = [b,a];
console.log(a,b);
對象的解構(gòu)取值
var userInfo = {
userName:"張三",
age:19,
sex:"男"
}
let {userName,age,sex} = userInfo;
解構(gòu)賦值
let userName = "張三";
let age = 18;
let userInfo = {
userName,
age
}
展開運(yùn)算符
在ES6里面,新增了展開運(yùn)算符,所有實(shí)現(xiàn)了Iterable接口的都可以使用展開運(yùn)算符,目前來講在系統(tǒng)中ES里面實(shí)現(xiàn)了這個接口的數(shù)據(jù)如下
1、數(shù)組
2、NodeList
3、HTMLCollection
4、Set
5、Map
6、arguments
7、字符串
展開運(yùn)算符使用 … 來完成運(yùn)算
var arr = [1,2,3,4,5,6,7];
console.log(...arr);
//展開運(yùn)算獲取最多的數(shù)字
var max1 = Math.max(...arr);
console.log(max1);
//數(shù)組的深拷貝
var a = 1;
var b;
b = a;
var newArr = [...arr];
//實(shí)現(xiàn)數(shù)組的合并
var arr1 = ["A","b","c","d"];
var arr2 = [...arr,...arr1];
let obj = {
userName:"張三",
age:18
}
let obj1 = {
hobby:"sleep"
}
//Object.assgin()
//實(shí)現(xiàn)對象的合并
let obj2 = {
...obj,
...obj1
}
字符串?dāng)U展
模板字符串,模板字符串自帶格式,你格式什么樣子打印出來就是什么樣子
var str = `親愛的張三:
你好!
恭喜你,已中本公司大獎,價值9999元的大禮包直接抗回家!
你只需要繳納1999元的保證金就可以領(lǐng)取大獎
電話:1234566789
聯(lián)系人:李四
XXX公司
XXXX年XX月XX日`
console.log(str);
模板字符串另外一個特點(diǎn)可以快速實(shí)現(xiàn)字符串拼接
let nickName = "張三";
let tel = 110;
let connectPerson = "李四"
let company = "畫大餅公司"
var str = `親愛的${nickName}:
你好!
恭喜你,已中本公司大獎,價值9999元的大禮包直接抗回家!
你只需要繳納1999元的保證金就可以領(lǐng)取大獎
電話:${tel}
聯(lián)系人:${connectPerson}
${company}公司
XXXX年XX月XX日`
console.log(str);
模板字符串內(nèi)部可以使用 ${ } 在大括號里面可以寫任意的JS代碼
function abc(){
console.log("haha")
}
abc`` //可以替代函數(shù)調(diào)用時使用的()
字符串?dāng)U展方法
1、include() 判斷當(dāng)前字符串中是否包含某一個字符串,以前可以使用indexOf方法
2、repeat() 生成一個重復(fù)字符串
3、trimStart() / trimEnd() 去除開始與結(jié)束的空格
數(shù)組的擴(kuò)展方法
1、Array.of()
聲明數(shù)組的方法,它可以解決一個問題 new Array() 所存在的問題
var arr = new Array(2); //代表這個數(shù)組的長度是2
var arr1 = Array.of(2);
2、Array.from() 把類數(shù)組轉(zhuǎn)成數(shù)組
var lis = document.querySelectorAll("li");
let arr = Array.from(lis);
3、fill() 填充數(shù)組的方法
參數(shù)1:需要填充的數(shù)據(jù)
參數(shù)2:需要從索引幾開始填充
參數(shù)3:填充到索引幾
4、flat(steps)拍平一個多維數(shù)組
以前我們需要通過遞歸+遍歷,現(xiàn)在有這個方法就簡單多了
參數(shù)steps:表示拍平到第幾個維度,也可以傳入Infinity,不管幾維都給拍平
5、find() 在數(shù)組中查找一個元素,如果找到返回找到的第一個元素,如果找不到返回undefined
let list = [
{
age:18
userName:"張三",
},
{
userName:"李四",
age:20
},
{
userName:"王五",
age:21
}
]
let obj = list.find(function(item,index,_arr){
//返回后面可以寫一個匹配條件
return item.userName == "張三"
})
6、findIndex() 查找某一個元素的索引,這個方法的用法和上面find一樣
for…of遍歷
of的遍歷與in的遍歷是相同的,但是for…in是一個有序遍歷(有索引的時候依靠索引遍歷),而for…of是一個無序遍歷(遍歷的時候不需要索引)
for(var i of list){
console.log(i);
}
注意:
for…of是基于屬性值來遍歷,所以并不是所有的對象都可以用它來遍歷,如果要使用for…of來遍歷,則這個對象必須要實(shí)現(xiàn)Iterable接口
Set單值集合
Set是ES6中新增的一種數(shù)據(jù)結(jié)構(gòu),它是一個單值集合,沒有屬性名(沒有索引,沒有key),并且是一個不重合的集合
Set創(chuàng)建
let s1 = new Set();
let s2 = new Set(["a","b","c","d"]);
let s3 = new Set(["a","b","a","c","d"])
Set集合方法
1、add() 給集合添加元素
s3.add("haha").add("hehe")
2、delete() 向Set集合中刪除一個元素,返回布爾值
3、has() 判斷set集合中有沒有這個元素,返回布爾值
4、size屬性,表示當(dāng)前set集合的元素個數(shù)
5、clear() 清空set集合
6、values() 它是一個生成器方法,返回當(dāng)前set集合中的迭代器
7、keys()和values方法一樣,但是set沒有鍵,所以返回的依然是values的結(jié)果
let arr1 = [1,2,3,4,5,5,6]
let s1 = new Set();
let s2 = new Set(["a","b","c","d"]);
let s3 = new Set(["a","b","a","c","d"])
let s4 = new Set(arr1)
for(let i of s3){
console.log(i);
}
//將set集合的數(shù)據(jù)轉(zhuǎn)換成數(shù)組的數(shù)據(jù),來進(jìn)行調(diào)用,同時還可以達(dá)到去重的操作
let arr = [...s1];
Map鍵值對集合
map是鍵值對形式的一個儲存,它結(jié)合set的特點(diǎn)(儲存速度快),也解決了set集合取值慢的特性
map集合當(dāng)中的鍵不允許重復(fù)的,但是值可以
let m1 = new Map([
["a","張三"],
["b","李四"],
["c","王五"],
[3,{
userName:"哈哈"
}],
[4,function(){
console.log("hello")
}]
])
1、鍵不能重復(fù),值可以
2、鍵與值可以是任意數(shù)據(jù)類型
Map方法
1、size屬性
2、set(key,value)向當(dāng)前map集合新增元素
3、get(key)通過一個鍵獲取map集合當(dāng)中的一個值
4、delete() 向Map集合中刪除一個元素,返回布爾值
5、clear() 清空Map集合
6、values() 它是一個生成器方法,返回當(dāng)前Map集合中的迭代器
7、keys()生成器方法,返回當(dāng)前map集合的key-value的集合
Map遍歷
for(let i [k,v] of m1){
console.log(k,v)
}
函數(shù)擴(kuò)展
之前在ES5中我們學(xué)習(xí)了哪些函數(shù)
- 遞歸函數(shù)
- 回調(diào)函數(shù)
- 閉包函數(shù)
- 匿名函數(shù)
- 構(gòu)造函數(shù)
- 普通函數(shù)
- 立即執(zhí)行函數(shù)
以上是我們在ES5中接觸和學(xué)習(xí)到函數(shù)形式,但是它們本質(zhì)上來講沒有區(qū)別,之所以有那么多種叫法完全出于調(diào)用方式的不同
無構(gòu)造函數(shù)的函數(shù)
官方叫法成員函數(shù),屬性函數(shù)
在之前的ES5當(dāng)中,所有通過function定義的東西都叫函數(shù),而所以通過function聲明的函數(shù)都具備構(gòu)造函數(shù)的特點(diǎn),也就是可以被new調(diào)用
let obj = {
name:"haha",
sayHello:function(){
console.log("hello")
}
}
obj.sayHello(); //普通調(diào)用
new obj.sayHello(); //構(gòu)造函數(shù)調(diào)用
在上面的代碼中,我們可以看到sayHello方法本是obj對象的,它就應(yīng)該通過obj.sayHello() 來調(diào)用,而不應(yīng)該用new來調(diào)用
上面這種情況就會產(chǎn)生一些不必要的歧義,ES6就改變了這種函數(shù)的定義方式,直接拋棄了關(guān)鍵字function
let obj = {
name:"haha",
sayHello(){
console.log("hello")
}
}
obj.sayHello(); //普通調(diào)用
new obj.sayHello(); //報錯
箭頭函數(shù)
拋棄了function關(guān)鍵字來聲明的一個函數(shù)聲明方式
//無參箭頭函數(shù)
const sayHello1 = () => {
console.log("hello");
}
//有一個參數(shù)的箭頭函數(shù)
const sayHello2 = userName => {
console.log(userName);
}
//有多個參數(shù)的箭頭函數(shù)
const sayHello2 = (userName,age) => {
console.log(userName,age);
}
//箭頭函數(shù)的返回值
const a = () => {
return "hello"
}
//如果只有一句話要執(zhí)行,可以省略大括號
const sayHello2 = (userName,age) => console.log(userName,age);
//省略return關(guān)鍵字返回數(shù)據(jù)
const b = (x,y) => x + y
省略return,舉例:
let newArr = arr.filter(item => item % 2 == 0)
箭頭函數(shù)的注意事項:
1、箭頭函數(shù)不具備構(gòu)造函數(shù)的特點(diǎn),不能用new調(diào)用
2、箭頭函數(shù)是沒有arguments
3、箭頭函數(shù)內(nèi)部沒有this,如果寫了this它綁定的是外邊的this
ES6的函數(shù)參數(shù)
函數(shù)參數(shù)的默認(rèn)值
之前我們聲明函數(shù)可以放置參數(shù)
function sayHello(userName,age){
age = age || 18;
console.log(age);
}
在上面的代碼種,我們可以看到,如果要設(shè)置一個參數(shù)的默認(rèn)值,我們需要使用邏輯運(yùn)算在函數(shù)內(nèi)部進(jìn)行一個計算才行,但是ES6可以直接設(shè)置參數(shù)的默認(rèn)值
function sayHello(userName,age=18){
console.log(age);
}
多個參數(shù)也行
const sayHello = (userName="張三",age=18) => {
console.log(age);
}
函數(shù)的剩余參數(shù)
在ES6里面,我們的箭頭函數(shù)沒有arguments,但是我們向?qū)崿F(xiàn)類似于實(shí)參列表的功能怎么辦?
const sayHello = (userName,hobby) => {
console.log(`大家好,我叫${userName}`);
console.log(`我的愛好是${hobby}`)
}
sayHello("張三","看書","睡覺")
代碼分析:
上面的代碼我們實(shí)現(xiàn)了打印用戶愛好的功能,但是如果有多個愛好怎么辦?
這里使用剩余參數(shù)
const sayHello = (userName,...hobby) => {
console.log(`大家好,我叫${userName}`);
console.log(`我的愛好是${hobby.join("-")}`)
}
sayHello("張三","看書","睡覺","打游戲","吃飯")
簡單來說,剩余參數(shù)就是利用展開運(yùn)算符在參數(shù)中聲明了一個沒有長度的數(shù)組
class關(guān)鍵字
在上面的函數(shù)擴(kuò)展當(dāng)中,無論是新增的成員函數(shù)還是箭頭函數(shù),都不能使用構(gòu)造函數(shù)的new去調(diào)用了,那么如果我們要在ES6的新語法中定義一個構(gòu)造函數(shù)怎么辦?ES6推出了class關(guān)鍵字
class Student{
//constructor是在new調(diào)用的一瞬間,自動執(zhí)行
constructor(userName,age,sex){
this.userName = userName;
this.age = age;
this.sex = sex;
}
sayHello(){
console.log(this.userName)
}
}
let stu1 = new Student("張三",20,"男");
let stu2 = new Student("李四",18,"女")
class里面的訪問器屬性
在ES6中訪問器屬性的功能得到的了擴(kuò)展
class Person {
constructor(firstName,lastName){
this.firstName = firstName;
this.lastName = lastName;
}
userName(){
return this.firstName + this.lastName;
}
}
let p1 = new Person("張","三");
console.log(p1.userName())
上面的代碼,有個問題,我們的userName表現(xiàn)出來的還是一個方法,不是一個屬性
class Person {
constructor(firstName,lastName){
this.firstName = firstName;
this.lastName = lastName;
}
get userName(){
return this.firstName + this.lastName;
}
set userName(v){
this.firstName = v[0];
this.lastName = v.slice(1)
}
}
let p1 = new Person("張","三");
分析:
get / set 共同修改了訪問器屬性,get在取值的時候自動調(diào)用,set在賦值的時候自動調(diào)用,set的參數(shù)就賦的值
let obj = {
firstName:"張",
lastName:"三",
get userName(){
return this.firstName + this.lastName;
}
set userName(v){
this.firstName = v[0];
this.lastName = v.slice(1)
}
}
class里面的關(guān)鍵static
class Student{
//constructor是在new調(diào)用的一瞬間,自動執(zhí)行
constructor(userName,age,sex){
this.userName = userName;
this.age = age;
this.sex = sex;
}
static sayHello(){
console.log(this.userName)
}
}
代碼分析:
對于class里面的普通方法,我們需要先new一個對象出來,然后通過這個對象來調(diào)用里面的方法
對于class里面的靜態(tài)方法,我們可以直接使用構(gòu)造函數(shù)名來調(diào)用
靜態(tài)的方法不能使用非靜態(tài)的屬性和方法
extends關(guān)鍵字
這個是通過extends關(guān)鍵字來直接實(shí)現(xiàn)class的繼承
class Person{
sayHello(){
console.log("我是一個人")
}
}
class Student extends Person {
study(){
console.log("我在學(xué)習(xí)")
}
}
let s1 = new Student();
分析:
上面的代碼中,我們讓Student繼承自Person,同時兩個構(gòu)造函數(shù)內(nèi)部都沒有參數(shù),所以可以把構(gòu)造器省略掉
class Person{
constructor(userName,age){
this.userName = userName;
this.age = age;
}
sayHello(){
console.log("我是一個人")
}
}
class Student extends Person {
constructor(userName,age,sex){
super(userName,age);
this.sex = sex;
}
study(){
console.log("我在學(xué)習(xí)")
}
}
let s1 = new Student("張三",20,"男");
代碼分析:
如果要構(gòu)造函數(shù)接收參數(shù),則構(gòu)造器一定要手寫,寫的時候注意,super一定要先寫出來,this要在super后面
靜態(tài)繼承
之前我們說過,class里面除了普通屬性和方法之外,還有static靜態(tài)屬性和方法,靜態(tài)的是否可以被繼承?
class Person{
constructor(userName,age){
this.userName = userName;
this.age = age;
}
static hobby = "睡覺";
static sayHello(){
console.log("我是一個人")
}
}
class Student extends Person {
constructor(userName,age,sex){
super(userName,age);
this.sex = sex;
}
study(){
console.log("我在學(xué)習(xí)")
}
}
let s1 = new Student("張三",20,"男");
代碼分析:
1、靜態(tài)方法和屬性是可以被繼承的
2、靜態(tài)與非靜態(tài)之間還是隔離的,就算被繼承了也是隔離的
3、靜態(tài)方法可以調(diào)用靜態(tài)屬性
方法的重載override
class Person{
constructor(userName,age){
this.userName = userName;
this.age = age;
}
static hobby = "睡覺";
static sayHello(){
console.log("我是一個人")
}
abc(){
console.log("Person")
}
}
class Student extends Person {
constructor(userName,age,sex){
super(userName,age);
this.sex = sex;
}
study(){
console.log("我在學(xué)習(xí)")
}
abc(){
console.log("Student");
}
parentAbc(){
super.abc();
}
}
let s1 = new Student("張三",20,"男");
代碼分析:
1、當(dāng)父級類的方法滿足不了子類的要求的時候,我們可以考慮重寫方法
2、重寫只需要在子類當(dāng)中建立一個同名的方法即可文章來源:http://www.zghlxwxcb.cn/news/detail-792710.html
3、在重寫子方法的時候,如果要調(diào)用父級的同名方法可以使用super指向父級調(diào)用文章來源地址http://www.zghlxwxcb.cn/news/detail-792710.html
到了這里,關(guān)于ECMAScript 6的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!