最近在阅读《深刻当即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新增或修改的内容。
本篇文章的内容都是我借鉴的书本上面的知识,再添加了一些本身的理解。可能会有错误的地方,若是您看到了,那请你指出来。若是对文章的内容哪里有不明白的地方,能够在下面留言,我会进行更加细致的说明。