摘要:返回布爾值,表示參數(shù)字符串是否在源字符串的尾部。我們可以往里面添加刪除查詢數(shù)據(jù)先聲明一個(gè)對(duì)象往這個(gè)集合對(duì)象中添加元素判斷集合中是否存在一個(gè)元素返回一個(gè)布爾值,表示該值在中存在與否。
一、 ES6 基本語法 1.1 let
作用域就是一個(gè)變量的有效的范圍,就是你聲明一個(gè)變量以后,這個(gè)變量在什么場(chǎng)合可以使用它。以前JavaScript只有全局作用域和函數(shù)作用域,現(xiàn)在JavaScript也有了塊級(jí)作用域(block scope)
1.1.1 let 語法let var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]];1.1.2 參數(shù)解釋
var1, var2, …, varN 變量名。可以是任意合法的標(biāo)識(shí)符。1.1.2 let 描述
value1, value2, …, valueN 變量的初始值??梢允侨我夂戏ǖ谋磉_(dá)式。
let允許你聲明一個(gè)作用域被限制在塊級(jí)中的變量、語句或者表達(dá)式。與var關(guān)鍵字不同的是,它聲明的變量只能是全局或者整個(gè)函數(shù)塊的。
1.1.3 let 作用域規(guī)則let聲明的變量只在其聲明的塊或子塊中可用,這一點(diǎn),與var相似。二者之間最主要的區(qū)別在于var聲明的變量的作用域是整個(gè)封閉函數(shù)。
看下面的例子:
function varTest() { var x = 1; if (true) { var x = 2; // 同樣的變量! console.log(x); // 2 } console.log(x); // 2 } function letTest() { let x = 1; if (true) { let x = 2; // 不同的變量 console.log(x); // 2 } console.log(x); // 1 }1.2 const 1.2.1 const 語法
const name1 = value1 [, name2 = value2 [, ... [, nameN = valueN]]];1.2.2 參數(shù)解釋
nameN1.2.3 const描述
常量名稱,可以是任意合法的標(biāo)識(shí)符。valueN
常量值,可以是任意合法的表達(dá)式。
此聲明創(chuàng)建一個(gè)常量,其作用域可以是全局或本地聲明的塊。 與var變量不同,全局常量不會(huì)變?yōu)榇翱趯?duì)象的屬性。需要一個(gè)常數(shù)的初始化器;也就是說,您必須在聲明的同一語句中指定它的值(這是有道理的,因?yàn)橐院蟛荒芨模?br>const聲明創(chuàng)建一個(gè)值的只讀引用。但這并不意味著它所持有的值是不可變的,只是變量標(biāo)識(shí)符不能重新分配。例如,在引用內(nèi)容是對(duì)象的情況下,這意味著可以改變對(duì)象的內(nèi)容(例如,其參數(shù))。1.2.4 實(shí)例
1.2.5 小結(jié)
如果const后面的變量是普通變量,改變值報(bào)錯(cuò)。如果后面存儲(chǔ)的是數(shù)組或者對(duì)象,那么改變它的指向也會(huì)報(bào)錯(cuò),但是如果改變數(shù)組或者對(duì)象的值是不會(huì)發(fā)生錯(cuò)誤的1.3 解構(gòu)賦值
ES6允許按照一定模式,從數(shù)組和對(duì)象中提取值,對(duì)變量進(jìn)行賦值,這被稱為解構(gòu)1.3.1 數(shù)組的解構(gòu)賦值
ES5 中的變量賦值,只能直接指定值
var a = 1; var b = 2; var c = 3;
ES6 可以這樣寫
var [a, b, c] = [1, 2, 3]; console.log(a,b,c);// 1 2 3
上面代碼表示,可以從數(shù)組中提取值,按照對(duì)應(yīng)位置,對(duì)變量賦值。這種寫法屬于“模式匹配”,只要等號(hào)兩邊的模式相同,左邊的變量就會(huì)被賦予對(duì)應(yīng)的值
1.3.2 允許使用默認(rèn)值var [a=1] = [] console.log(a);// 1 var [a,b=2] = [3]; console.log(a,b);//3 2 var [a,b=4] = [5,undefined]; console.log(a,b);// 5 41.3.4 使用默認(rèn)值的注意事項(xiàng)
注意一:
ES6內(nèi)部使用嚴(yán)格相等運(yùn)算符(===),判斷一個(gè)位置是否有值。 所以,如果一個(gè)數(shù)組成員不嚴(yán)格等于undefined,默認(rèn)值是不會(huì)生效的。
var [d=8] = [undefined]; console.log(d);// 8 var [a=9] = [null]; console.log(a);// null
上面代碼中,如果一個(gè)數(shù)組成員是null,默認(rèn)值就不會(huì)生效,因?yàn)閚ull不嚴(yán)格等于undefined。
注意二:
如果默認(rèn)值是一個(gè)表達(dá)式,那么這個(gè)表達(dá)式是惰性求值的,即只有在用到的時(shí)候,才會(huì)求值。
function getNumber(){ console.log("只有用到我的時(shí)候我才出現(xiàn)"); } var [a=getNumber()] = ["我先來"]; console.log(a);// 會(huì)輸出 我先來
上面代碼中,因?yàn)閍能取到值,所以函數(shù)f根本不會(huì)執(zhí)行。上面的代碼其實(shí)等價(jià)于下面的代碼。
function getNumber(){ console.log("只有用到我的時(shí)候我才出現(xiàn)"); } let a; if(["我先來"][0]===undefined){ a = getNumber(); }else{ a = ["我先來"][0]; } console.log(a);// 會(huì)輸出 我先來
注意三:
默認(rèn)值可以引用解構(gòu)賦值的其他變量,但該變量必須已經(jīng)聲明
let [a,b=a]=[1]; console.log(a,b);// a = 1 b = 1 let [x=2,y=x]=[]; console.log(x,y);// x = 2 y = 2 let [c=1,d=c]=[12,3]; console.log(c,d);// c =12 d = 3 let [e=f,f=1]=[]; console.log(e,f);// 報(bào)錯(cuò) f is not defined
上面最后一個(gè)表達(dá)式之所以會(huì)報(bào)錯(cuò),是因?yàn)閑用到默認(rèn)值f時(shí),f還沒有聲明
1.3.5 對(duì)象的解構(gòu)賦值解構(gòu)賦值不僅可以用于數(shù)組,還可以用于對(duì)象.
eg:
let {name,age} = {name:"wxk",age:20}; console.log(name); // wxk
注意:對(duì)象的解構(gòu)與數(shù)組有一個(gè)重要的不同
- 數(shù)組的元素是按次序排列的,變量的取值由它的位置決定 - 對(duì)象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值
小編總結(jié):等號(hào)左邊的變量的次序,與等號(hào)右邊兩個(gè)同名屬性的次序不一致,但是對(duì)取值完全沒有影響。但是如果變量沒有對(duì)應(yīng)的同名屬性,則會(huì)導(dǎo)致取不到值,最后等于undefined1.4 函數(shù) 1.4.1 為函數(shù)的參數(shù)設(shè)置默認(rèn)值
在es6里面我們可以給定義的函數(shù)接收的參數(shù)設(shè)置默認(rèn)的值,如果不去指定這個(gè)函數(shù)的參數(shù)的值的話,就會(huì)使用這些參數(shù)的默認(rèn)的值
function Person(name="Tom",age=12){ console.log(name);//Tom console.log(age);// 12 } Person();
如果在調(diào)用函數(shù)的時(shí)候傳入實(shí)參,則會(huì)改變默認(rèn)參數(shù)的值。eg:
function Person(name="Tom",age=12){ console.log(name);//Jack console.log(age);// 20 } Person("Jack",20);1.4.2 ... 操作符
...是es6中新添加的一種操作符,可以叫做spread(擴(kuò)展)或則rest(剩余)
具體用法如下:
rest (剩余操作符)
剩余操作符一般會(huì)用在函數(shù)的參數(shù)里面。比如:
想讓一個(gè)函數(shù)支持更多的參數(shù),參數(shù)的數(shù)量不受限制,這個(gè)時(shí)候就可以 使用剩余操作符。
eg:
剩余操作符后面的變量會(huì)變成一個(gè)數(shù)組,多余的參數(shù)會(huì)被放入這個(gè)數(shù)組中
spread(擴(kuò)展運(yùn)算符)
...操作符如果用在數(shù)組的前面,作用就是將這個(gè)數(shù)組展開,因此稱為擴(kuò)展操作符。相當(dāng)于rest操作符的逆運(yùn)算
eg:
這里呢把數(shù)組arr1 和 數(shù)組 arr2 用 ... 操作符進(jìn)行了擴(kuò)展,所有他們變成了字符串,不信你們可以嘗試一下,直接輸出 console.log(...arr1)
1.4.3 函數(shù)的 name 屬性es6給函數(shù)添加了一個(gè)name屬性,使用這個(gè)屬性我們可以得到函數(shù)的名字
eg:
1.4.4 箭頭函數(shù)(重點(diǎn)) 箭頭函數(shù)的語法
不引入?yún)?shù)
2. 引入單個(gè)參數(shù)
3. 引入多個(gè)參數(shù),則應(yīng)加上小括號(hào)
// ES5 語法 function sum(num1,num2){ return num1 + num2; } // 等同于 // ES6 語法 var sum = (num1,num2)=> num1 + num2; console.log(sum(5,9));//14
4. 若你想使用標(biāo)準(zhǔn)的函數(shù)體,或者函數(shù)體內(nèi)可能有更多的語句要執(zhí)行,則要用大括號(hào)將函數(shù)體括起來,并明確定義返回值。
// ES6 語法 var sum = (num1, num2) => { return num1 + num2; } //等同于: // ES5 語法 var sum = function(num1, num2) { return num1 + num2; };
5. 箭頭函數(shù)若要返回自定義對(duì)象的話,就必須用小括號(hào)把該對(duì)象括起來先
1.4.5 箭頭函數(shù)的 this 指向
箭頭函數(shù)本身是沒有this和arguments的,在箭頭函數(shù)中引用this實(shí)際上是調(diào)用的是定義時(shí)的上一層作用域的this。
這里強(qiáng)調(diào)的是上一層作用域,是因?yàn)閷?duì)象是不能形成獨(dú)立的作用域的。
看下面的小例子更容易明白:
eg1
eg2:
var ojb = { pro: { getPro: ()=>{ console.log(this); } } } ojb.pro.getPro();//this指向的是window,因?yàn)榧^函數(shù)定義時(shí),getPro的上一級(jí)是pro,是一個(gè)對(duì)象,不能形成多帶帶的作用域,故指向window。
總結(jié)箭頭函數(shù)的this指向:箭頭的this,向上找,找到非箭頭函數(shù),看一下這個(gè)非箭頭函數(shù)的this是誰,那么箭頭函數(shù)的this就是這個(gè)非箭頭函數(shù)的this。
1.5 字符串 1.5.1 includes(), startsWith(), endsWith()傳統(tǒng)上,JavaScript只有indexOf方法,可以用來確定一個(gè)字符串是否包含在另一個(gè)字符串中。ES6又提供了三種新方法。
includes():返回布爾值,表示是否找到了參數(shù)字符串。
startsWith():返回布爾值,表示參數(shù)字符串是否在源字符串的頭部。
endsWith():返回布爾值,表示參數(shù)字符串是否在源字符串的尾部。
舉例說明三個(gè)方法怎么用:
注意:這三個(gè)方法都支持第二個(gè)參數(shù),表示開始搜索的位置
1.5.2 模板字符串模板字符串中所有的空格、新行、縮進(jìn),都會(huì)原樣輸出在生成的字符串中
注意:模板字符串(template string)是增強(qiáng)版的字符串,用反引號(hào)(`),標(biāo)識(shí),嵌入的變量名寫在${}之中
1.6 對(duì)象 Object 1.6.1 屬性的簡潔表示法ES6為我們提供了一種簡寫方法,就是在對(duì)象里面直接加上這屬性,不需要再指定值
1.6.2 對(duì)象新增函數(shù)Object.is()ES5比較兩個(gè)值是否相等,只有兩個(gè)運(yùn)算符:相等運(yùn)算符(==)和嚴(yán)格相等運(yùn)算符(===)。它們都有缺點(diǎn),前者會(huì)自動(dòng)轉(zhuǎn)換數(shù)據(jù)類型,后者的NaN不等于自身,以及+0等于-0。JavaScript缺乏一種運(yùn)算,在所有環(huán)境中,只要兩個(gè)值是一樣的,它們就應(yīng)該相等。
ES6提出“Same-value equality”算法,用來解決這個(gè)問題。Object.is就是部署這個(gè)算法的新方法。它用來比較兩個(gè)值是否嚴(yán)格相等,與嚴(yán)格比較運(yùn)算符(===)的行為基本一致。
見下面的例子:
1.6.3 對(duì)象新增函數(shù)Object.assign()
Object.assign方法用于對(duì)象的合并,將源對(duì)象(source)的所有可枚舉屬性,復(fù)制到目標(biāo)對(duì)象(target)
1. 注意:如果目標(biāo)對(duì)象與源對(duì)象有同名屬性,或多個(gè)源對(duì)象有同名屬性,則后 面的屬性會(huì)覆蓋前面的屬性
2. 如果只有一個(gè)參數(shù),Object.assign會(huì)直接返回該參數(shù)
var cat = { height:50 } var str = {} Object.assign(str,cat); console.log(str);//{height: 50}
3. 如果該參數(shù)不是對(duì)象,則會(huì)先轉(zhuǎn)成對(duì)象,然后返回
console.log(Object.assign(2));// Number?{2}
4. 由于undefined和null無法轉(zhuǎn)成對(duì)象,所以如果它們作為參數(shù),就會(huì)報(bào)錯(cuò)。
1.7 集合對(duì)象 1.7.1 Set 對(duì)象Set對(duì)象是一組值的集合,這些值是不重復(fù)的,無序的,與我們?cè)跀?shù)學(xué)中學(xué)到的集合是一樣的。我們可以往里面添加、刪除、查詢數(shù)據(jù)
1. 先聲明一個(gè)Set對(duì)象
var mySet = new Set();
2. 往這個(gè)集合對(duì)象中添加元素
mySet.add(1);
mySet.add("some text");
3. 判斷集合中是否存在一個(gè)元素1
mySet.has(1); // true 返回一個(gè)布爾值,表示該值在Set中存在與否。
4. 刪除集合中的字符串
mySet.delete("foo");//移除Set的中與這個(gè)值相等的元素
5. 獲取集合中元素的數(shù)量
mySet.size; // 返回Set對(duì)象的值的個(gè)數(shù)。
6. 刪除集合中所有的元素
mySet.clear();//移除Set對(duì)象內(nèi)的所有元素。
1.7.2 Map對(duì)象
如果你需要一個(gè)鍵值對(duì)的數(shù)據(jù)結(jié)構(gòu),我們可以聲明一個(gè)Map對(duì)象,這個(gè)對(duì)象里面可以包含多個(gè)項(xiàng)目,每個(gè)項(xiàng)目都有一個(gè)名字,還有一個(gè)跟它對(duì)應(yīng)的值
1. 創(chuàng)建Map對(duì)象的方法是使用new操作符去聲明這個(gè)對(duì)象
var myMap = new Map();
2. 向Map對(duì)象里面添加鍵值對(duì),其中鍵和值可以是任意值(對(duì)象或者原 始值)
var obj = {};
var fun = function(){}; var str = “HelloWorld”; myMap.set(obj, “我是對(duì)象”); myMap.set(fun, “我是函數(shù)”); myMap.set(str, “我是字符串”);
3. 查看集合中元素的數(shù)量
myMap.size
4. 獲取相應(yīng)的鍵值
myMap.get(obj);
5. 刪除一個(gè)鍵值對(duì),然后再判斷該鍵值對(duì)是否存在
myMap.delete(fun);
myMap.has(fun);
6. 刪除Map集合中所有的鍵值對(duì)
myMap.clear();
eg:
其余的方法就不演示了,和上面的Set方法一樣
1.7.3 Class (重點(diǎn))ES6提供了更接近傳統(tǒng)語言的寫法,引入了Class(類)這個(gè)概念,作為對(duì)象的模板。通過class關(guān)鍵字,可以定義類?;旧希珽S6的class可以看作只是一個(gè)語法糖,它的絕大部分功能,ES5都可以做到,新的class寫法只是讓對(duì)象原型的寫法更加清晰、更像面向?qū)ο缶幊痰恼Z法而已。上面的代碼就可以這樣改
class person { constructor(name,age){ this.name = name; this.age = age; } run(){ console.log("每天堅(jiān)持鍛煉"); } } var student = new person("Jack",15); student.run();
小編分析:上面代碼定義了一個(gè)“類”,可以看到里面有一個(gè)constructor方法, 這就是構(gòu)造方法,而this關(guān)鍵字則代表實(shí)例對(duì)象。也就是說,ES5的構(gòu)造函數(shù)person,對(duì)應(yīng)ES6的person類的構(gòu)造方法。person類除了構(gòu)造方法,還定義了一個(gè)run方法。注意,定義“類”方法的時(shí)候,前面不需要加上function這個(gè)關(guān)鍵字,直接把函數(shù)定義放進(jìn)去了就可以了。另外,方法之間不需要逗號(hào)分隔,加了會(huì)報(bào)錯(cuò)。構(gòu)造函數(shù)的prototype屬性,在ES6的“類”上面繼續(xù)存在。事實(shí)上,類的所有方法都定義在類的prototype屬性上面
1.7.4 class繼承 (重點(diǎn))extends關(guān)鍵字用于實(shí)現(xiàn)類之間的繼承。子類繼承父類,就繼承了父類的所有屬性和方法,使用super可以調(diào)用父類的方法
1.8 Promise對(duì)象 1.8.1 什么是Promise對(duì)象一個(gè) Promise 對(duì)象可以理解為一次將要執(zhí)行的操作(常常被用于異步操作),使用了 Promise 對(duì)象之后可以用一種鏈?zhǔn)秸{(diào)用的方式來組織代碼,讓代碼更加直觀。而且由于 Promise.all 這樣的方法存在,可以讓同時(shí)執(zhí)行多個(gè)操作變得簡單
下面簡單介紹Promise 對(duì)象,如下代碼:
上面的代碼實(shí)現(xiàn)的功能非常簡單,helloWord 函數(shù)接受一個(gè)參數(shù),如果為 true 就打印 "Hello World!",如果為 false 就打印錯(cuò)誤的信息。helloWord 函數(shù)返回的是一個(gè) Promise 對(duì)象。1.8.2 Promise的三種狀態(tài)在 Promise 對(duì)象當(dāng)中有兩個(gè)重要方法————resolve 和 reject。
resolve 方法可以使 Promise 對(duì)象的狀態(tài)改變成成功,同時(shí)傳遞一個(gè)參數(shù)用于后續(xù)成功后的操作,在這個(gè)例子當(dāng)中就是 Hello World!字符串
reject 方法則是將 Promise 對(duì)象的狀態(tài)改變?yōu)槭。瑫r(shí)將錯(cuò)誤的信息傳遞到后續(xù)錯(cuò)誤處理的操作
resolved 可以理解為成功的狀態(tài)
rejected 可以理解為失敗的狀
pending promise對(duì)象實(shí)例創(chuàng)建時(shí)候的初始狀態(tài)
helloWorld 的例子中的 then 方法就是根據(jù) Promise 對(duì)象的狀態(tài)來確定執(zhí)行的操作,resolve 時(shí)執(zhí)行第一個(gè)函數(shù)(onFulfilled),reject 時(shí)執(zhí)行第二個(gè)函數(shù)(onRejected)
如何查看Promise對(duì)象的方法,在控制臺(tái)輸出 new Promise(function(){})
見下圖:
### 1.8.3 使用Promise處理多任務(wù)
看下面的例子:
function HelloWorld(ready){ return new Promise(function(resolve,reject){ if(ready){ resolve("HelloWorld"); }else{ reject("GoodBay"); } }); } HelloWorld(true).then(function(message){ console.log(message); },function(error){ console.log(error); }).then(function(){ console.log("你好,世界!"); }).then(function(){ console.log("講真的"); });
解析:可以看到后面的方法用了鏈?zhǔn)降姆绞竭M(jìn)行編程,這是因?yàn)?,then返回的還是一個(gè) Promise 對(duì)象,因此返回的對(duì)象依然具有 then 方法,并且返回的對(duì)象狀態(tài)是 resolved, 所以后面的 then方法全部是執(zhí)行then 方法中的第一個(gè)函數(shù)參數(shù)1.8.4 catch方法
catch 方法是 then(onFulfilled, onRejected) 方法當(dāng)中 onRejected 函數(shù)的一個(gè)簡單的寫法,也就是說可以寫成then(fn).catch(fn),相當(dāng)于 then(fn).then(null, fn)。使用 catch 的寫法比一般的寫法更加清晰明確1.8.5 all和race方法
console.time(); var p1 = new Promise(function(resolve) { setTimeout(function() { resolve("Hello"); }, 3000); }); var p2 = new Promise(function(resolve) { setTimeout(function() { resolve("world"); }, 3000); }) Promise.all([p1, p2]).then(function(result) { console.log(result); console.timeEnd(); });
上面的例子模擬了傳輸兩個(gè)數(shù)據(jù)需要不同的時(shí)長,雖然 p2 的速度比 p1 要快,但是 Promise.all 方法會(huì)按照數(shù)組里面的順序?qū)⒔Y(jié)果返回
日常開發(fā)中經(jīng)常會(huì)遇到這樣的需求,在不同的接口請(qǐng)求數(shù)據(jù)然后拼合成自己所需的數(shù)據(jù),通常這些接口之間沒有關(guān)聯(lián)(例如不需要前一個(gè)接口的數(shù)據(jù)作為后一個(gè)接口的參數(shù)),這個(gè)時(shí)候 Promise.all 方法就可以派上用場(chǎng)了
還有一個(gè)和 Promise.all 相類似的方法 Promise.race,它同樣接收一個(gè)數(shù)組,不同的是只要該數(shù)組中的 Promise 對(duì)象的狀態(tài)發(fā)生變化(無論是 resolve 還是 reject)該方法都會(huì)返回1.9 fetch網(wǎng)絡(luò)請(qǐng)求
與ajax 請(qǐng)求的對(duì)比見下面的代碼:
如果有需要可以按照上面的方式進(jìn)行編寫
二、ES6之Module系統(tǒng) 2.1 為什么要進(jìn)行模塊化?可維護(hù)性的需要
可測(cè)性的需要
性能的需要
架構(gòu)的需求
代碼復(fù)用
多人協(xié)作的需要
2.2 導(dǎo)入導(dǎo)出小編這里只說步驟:
第一步:在你需要導(dǎo)出的 js 文件中某個(gè)方法或?qū)ο髸r(shí),前面加上 export 關(guān)鍵字
第二步: 在另一個(gè)js文件中導(dǎo)入你要導(dǎo)出的js文件,import 對(duì)象/方法 from ×××.js
第三步: 在html中引入入口js 文件,就是第二步中的另一個(gè)js文件。