最近在閱讀《深刻當即ECMAScript6》這本書,打算把本身學到的、用到的和理解的來講一說。 我會基本按照書上的順序來講,大概會分爲三到四篇的樣子,不會所有都寫,我只會挑一些經常使用的,或者我以爲比較有意思的來寫。正則表達式
在ES6以前,JavaScript中是沒有塊級做用域的概念的,只有全局做用域和塊級做用域。也就是說在塊級做用域聲明與外部同名的變量,會覆蓋掉外部的變量。而沒有塊級做用域的話,主要會有如下兩個問題。編程
var i = 1;
console.log(i) // 1
for(var i =0;i<10;i++){
console.log(i); // 0...9
}
console.log(i) // 10
複製代碼
var funcs = [];
for(var i = 0;i < 10;i++){
funcs.push(function (){
console.log(i);
});
}
funcs.forEach(function(func){
func(); // 輸出10次數字10
});
複製代碼
上面兩個問題都是沒有塊級做用域致使的,可是ES6發生了改變,爲咱們引入了塊級做用域。數組
基本與var相同,可是它的生命週期在塊級做用域內部,一旦出去塊級做用域便會消失。同時不能重複聲明同名變量bash
基本用法函數
var i = 0;
if(true){
let i = 100000;
}
console.log(i); // 0
複製代碼
循環中的let聲明ui
var i = 1;
console.log(i) // 1
for(let i =0;i<10;i++){
console.log(i); // 0...9
}
console.log(i) // 1
複製代碼
其實let在每次建立的時候都會建立一個新的變量,並以以前迭代中同名變量的值將其初始化。簡而言之就是let每次都會建立值的副本,而不是像var同樣修改引用的值。編碼
當第一次執行for循環的時候,會新建一個變量i(在內存中開闢一塊空間),而後將0賦值給這個變量,繼續執行下面的語句;當第二次執行的時候,又會新建一個變量i(在內存中從新開闢一個區域),以後再將原來i的值賦值給新的i,繼續在執行下面的語句。循環往復,直到循環的條件不知足爲止。spa
與let的用法基本也是相同的,可是它一旦被定義就不能被修改。固然,說的是原始值,若是你使用的是引用,你能夠更改引用內部的值,可是你沒法更改對引用的綁定。並且const聲明必須被初始化,否則就會報錯。code
基本語法orm
const name; //錯誤,未初始化
const maxItems = 30;
maxItems = 100; //報錯,不能更改綁定
複製代碼
循環中的const聲明
var funcs = [];
//完成一次迭代以後會報錯
for(const i =0;i<10;i++){
funcs.push(function(){
console.log(i);
});
}
複製代碼
這裏會報錯的緣由是變量i被const聲明爲常量,當迭代到i++是,這條語句想要修改常量i的值,因此會報錯。還有神奇的地方,讓咱們來看看下面的例子
var funcs = [];
person = {
name : 'Godfrey',
age : 20,
sex : 'male'
};
for(const key in person){
funcs.push(function(){
console.log(key);
});
}
funcs.forEach(function(func){
func(); // 輸出name、age、sex
});
複製代碼
你會發現這裏和咱們上面說的有些不同了,不是說const是常量嗎,不能被修改嗎?爲何在這個for-in循環中能夠被正確執行。
彆着急,是這樣的,在for-in和for-of循環中,每次迭代不會修改已有的綁定,而是會建立一個新的綁定,就像我上面講的let在循環中的表現是同樣的。也就是說在某些狀況下,const會和let表現是徹底相同的。
在引入let聲明和const聲明的同時,也帶來了臨時死區的概念。
簡單的說,臨時死去就是在變量未初始化以前不能使用。下面咱們來看例子
if(true){
console.log(typeof a); // 引用錯誤
let a = 1;
}
複製代碼
JavaScript引擎在掃描到變量的時候,若是遇到的是var聲明的變量,就發生變量提高,若是是let、const聲明的變量,就加入「臨時死區」。
tips:在塊級做用域以外聲明的訪問let、const聲明的同名變量不會報錯,也就是說「臨時死區」只做用在當前塊級做用域。
ES6引入了一些有關字符串方面的新方法和新特性。主要有如下幾個方面,字符串、正則表達式、模板字面量
let test = "𠮷a"
console.log(test.charCodeAt(0)); // 55362
console.log(test.charCodeAt(1)) // 57271
console.log(test.charCodeAt(2)) // 97
console.log(test.codePointAt(0)); // 134071
console.log(test.codePointAt(1)) // 57271
console.log(test.codePointAt(2)) // 97
複製代碼
charCodeAt(0)返回的是位置0處的第一個編碼單元,可是這個每每不是咱們想要的結果,而codePointAt(0)返回的是第一個字的完整編碼單元。
複製代碼
console.log(String.fromCodePoint(134071)); //𠮷
複製代碼
let test = 'Hello world';
console.log(test.includes("Hello")); // true
console.log(test.includes("a")); // false
console.log(test.startsWith("Hello")); // true
console.log(test.startsWith("Hello",4)); // false
console.log(test.endsWith("d")); // true
console.log(test.startsWith("Hello")); // false
console.log(test.endsWith("o",8)); // true
複製代碼
以上三個方法都會接受兩個參數。第一個是要檢測的文本內容,第二個是一開始搜索的位置的索引。includes和startsWith都會從索引的位置開始搜索,而endsWith會從字符串長度減去這個索引值的位置開始匹配。
上面就是就是ES6字符串主要的新增方法。
ES6爲了更好的知足開發中對字符串的操做,同時也加強了正則表達式。
let test = "𠮷";
console.log(text.length); // 2
console.log(/^.$/.test(test)); // false
console.log(/^.$/u.test(test)); // true
複製代碼
var text = "kidd1 kidd2 kidd3";
var pattern = /kidd\d\s?/;
var result = pattern.exec(text);
var globalPattern = /kidd\d\s?/g;
var globalResult = globalPattern.exec(text);
var stickyPattern = /kidd\d\s?/y;
var stickReslut = stickyPattern.exec(text);
console.log(result[0]); // "kidd1 "
console.log(globalResult[0]); // "kidd1 "
console.log(stickReslut[0]); // "kidd1 "
pattern.lastIndex = 1;
globalPattern.lastIndex = 1;
stickyPattern.lastIndex = 1;
result = pattern.exec(text);
globalResult = globalPattern.exec(text);
stickReslut = stickyPattern.exec(text);
console.log(result[0]); // "kidd1 "
console.log(globalResult[0]); // "kidd2 "
console.log(stickReslut[0]); // null
複製代碼
tips:
var regex1 = /ab/g;
//在ES5中時會拋出錯誤的。但在ES6中就是正常的。
var regex2 = new Regex2(regex1,"i");
console.log(regex1.toString()); // "/ab/g"
console.log(regex2.toString()); // "/ab/i"
複製代碼
var regex = /ab/g;
console.log(regex.flags); // "g"
複製代碼
這是ES6引入的全新的語法。主要是爲了解決字符串多行模式、佔位符和提供更強大的字符串操做。
模板字面量基礎的使用方法看起來與字符串字面量沒有大的區別,無非是將字符串字面量的引號(單、雙均可以)換成了反撇號(`),最直觀的特色是能支持多行字符串。
var message = `123
456
789`;
console.log(message); //"123 // 456 // 789"
複製代碼
上面是模板字面量最基本的用法,看起來好像沒什麼特別強大的地方,ES5也徹底能作到,就是麻煩一點,須要手動拼接。好!接下來纔是模板字面量真正強大的地方(其實,是否強大與否主要仍是看應用,畢竟編程仍是偏向應用科學的)。
字符串佔位符的基礎語法是${},中間能夠包含任意的JavaScript表達式。字符串佔位符爲你提供了將「表示式」嵌入到字符串中的功能,而且她會計算計算出結果。話很少說,來看個簡單的例子。
let a = 123,
b = 456;
message = `Sum is ${a + b}`;
console.log(message); // "Sum is 579";
複製代碼
字符串佔位符也是支持嵌套的。
首先咱們要說明什麼是標籤,標籤就是在模板字面量第一個反撇號(`)以前標註的字符串。固然這個字符串不須要添加引號。固然,若是這個標籤僅僅是個字符串是沒什麼做用的,若是它能夠是一個函數對象的引用,那就很強大了,這樣的話,咱們在處理同類型字符串,直接在它們前面添加一個tag,就很方便了。
function tag(literals,...substitutions){
let result = "";
for(let i = 0;i< substitutions.length; i++){
result += literals[i];
result += substitutions[i];
};
result += literals[literals.length-1];
return result;
}
let a = 123,
b = 456,
message = tag `Sum is ${a+b}`;
console.log(message); // "Sum is 579";
複製代碼
上面咱們有tag標籤模擬了模板字面量默認的行。咱們能夠看到函數中有兩個參數,其實兩個都是數組。
上面是有關字符串、正則表達式的ES6新增或修改的內容。
本篇文章的內容都是我借鑑的書本上面的知識,再添加了一些本身的理解。可能會有錯誤的地方,若是您看到了,那請你指出來。若是對文章的內容哪裏有不明白的地方,能夠在下面留言,我會進行更加細緻的說明。