网站目录管理模板下载,开源网站管理系统,空间站免费版下载,深圳南山 网站建设1 初识ES6
简单来说#xff0c;ECMAScript是JavaScript语言的国际标准#xff0c;JavaScript是实现ECMAScript标准的脚本语言。
2011年#xff0c;ECMA国际标准化组织在发布ECMAScript 5.1版本之后#xff0c;就开始着手制定第6版规范。
存在的问题#xff1a;这个版本…1 初识ES6
简单来说ECMAScript是JavaScript语言的国际标准JavaScript是实现ECMAScript标准的脚本语言。
2011年ECMA国际标准化组织在发布ECMAScript 5.1版本之后就开始着手制定第6版规范。
存在的问题这个版本引入的语法功能太多而且制定过程当中还有很多组织和个人不断提交新功能。很明显在一个版本中不可能包含所有的要引入的新功能这些功能要被发布在不同的版本中。
解决方法标准的制定者决定在每年的6月份发布一次新标准并且使用年份作为版本号。
年份版本简称2015年6月ECMAScript 2015ES62016年6月ECMAScript 2016ES72017年6月ECMAScript 2017ES82018年6月ECMAScript 2018ES92019年6月ECMAScript 2019ES102020年6月ECMAScript 2020ES11
2 let和const关键字
2.1 let关键字
let是ES6中新增的用于声明变量的关键字。在ES6之前我们使用var关键字来声明变量。与var关键字相比let关键字有一些新的特性。
let关键字的新的特性
块级作用域有效
let关键字声明的变量只在所处的块级作用域有效。防止代码块内层变量覆盖外层变量
scriptif (true) {let a 10;console.log(a); // 输出结果10}console.log(a); // 报错a未定义
/script防止循环变量变成全局变量
scriptfor (let i 0; i 2; i) { }console.log(i); // 报错i未定义
/script不存在变量提升
let关键字声明的变量不存在变量提升。在使用var关键字声明变量时变量可以先使用再声明这种现象就是变量提升。但一般的编程习惯变量应该在声明之后才可以使用。在ES6中变量的使用规范更加严格使用let关键字声明的变量只能在声明之后才可以使用否则就会报错。
script// 不存在变量提升console.log(a); // 报错a未初始化let a 10;
/script有暂时性死区特性
let关键字声明的变量具有暂时性死区特性。使用let关键字声明的变量具有暂时性死区特性。这是因为let关键字声明的变量不存在变量提升其作用域都是块级作用域在块级作用域内使用let关键字声明的变量会被整体绑定在这个块级作用域中形成封闭区域不再受外部代码影响。所以在块级作用域内使用let关键字声明变量之前该变量都是不可用的。这在语法上称为“暂时性死区”。
scriptvar num 10;if (true) {console.log(num); // 报错无法在初始化之前访问numlet num 20;}
/script2.2 const关键字
const是ES6中新增的用于声明常量的关键字。所谓常量就是值内存地址不能变化的量。
const关键字声明的常量的特点
块级作用域
const关键字声明的常量具有块级作用域。
scriptif (true) {const a 10;console.log(a); // 输出结果10}console.log(a); // 报错a未定义
/script必须赋值
const关键字声明常量时必须赋值。
scriptconst PI; // 报错常量PI未赋值
/script值不能修改
const关键字声明常量并赋值后常量的值不能修改。对于基本数据类型如数值、字符串一旦赋值值就不可修改。
scriptconst PI 3.14;PI 100; // 报错无法对常量赋值
/script对于复杂数据类型如数组、对象虽然不能重新赋值但是可以更改内部的值。
scriptconst ary [100, 200];ary[0] a;ary[1] b;console.log(ary); // 可以更改数组内部的值结果为[a, b]ary [a, b’]; // 报错无法对常量赋值
/script2.3 let、const、var关键字之间的区别
变量的作用域范围不同
使用var关键字声明的变量其作用域为该语句所在的函数内且存在变量提升现象。使用let关键字声明的变量和使用const关键字声明的常量都具有块级作用域。 变量提升
使用var关键字声明的变量存在变量提升可以先使用再声明。使用let关键字声明的变量和const关键字声明的常量不存在变量提升功能只能先声明再使用。 值是否可以更改
使用var关键字和let关键字声明的变量可以更改变量的值。但使用const关键字声明的常量不能更改常量值对应的内存地址。
在编写程序的过程中如果要存储的数据不需要更改建议使用const关键字如函数的定义、 π值或数学公式中一些恒定不变的值。
由于使用const声明的常量其值不能更改且JavaScript解析引擎不需要实时监控值的变化所以使用const关键字要比let关键字效率更高。
3 解构赋值
解构表示对数据结构进行分解赋值指变量的赋值。也就是拆解架构重新赋值。
在ES6中允许按照一一对应的方式从数组或对象中提取值然后将提取出来的值赋给变量。
解构赋值的优点是它可以让编写的代码简洁易读语义更加清晰并且可以方便地从数组或对象中提取值。
3.1 数组的解构赋值
数组的解构赋值就是将数组中的值提取出来然后赋值给另外的变量。
变量的数量和数组中值的数量相一致的情况
scriptlet [a, b, c] [1, 2, 3];console.log(a); // 输出结果1console.log(b); // 输出结果2console.log(c); // 输出结果3
/script变量的数量和数组中值的数量不一致的情况
scriptlet [a, b, c, d] [1, 2, 3];console.log(a); // 输出结果1console.log(b); // 输出结果2console.log(c); // 输出结果3console.log(d); // 输出结果undefined
/script3.2 对象的解构赋值
对象解构允许使用变量的名字匹配对象中属性如果匹配成功就将对象中属性的值赋值给变量。
scriptlet person { name: zhangsan, age: 20 };// 变量的名字 具体被解构的对象let { name, age } person; // 解构赋值console.log(name); // 输出结果zhangsanconsole.log(age); // 输出结果20
/script使用另外一种形式去实现对象的解构赋值该形式支持变量的名字和对象中属性的名字不一样的情况等号左边的大括号代表对象解构。
scriptlet person { name: zhangsan, age: 20, sex: 男 };// 属性名:变量名 具体被解构的对象let { name: myName } person;console.log(myName); // zhangsan
/script3.3 字符串解构赋值
字符串能够使用解构赋值的原因是: 字符串时特殊的数组(字符串能够被转换成一个类似数组的对象)
let [a, b, c, d, e] Hello;
console.log(a, b, c, d, e);3.4 解构赋值的用途
交换变量的值
let a 3, b 5;
[a, b] [b, a];
console.log(a, b);从函数内部返回多个值
let {dataObj} {code: 200, msg: ok, dataObj: [jack,rose,bob,小明]};
console.log(dataObj);快速提取一个对象中的属性或方法
let {floor, random, sin} Math;
console.log();
console.log(Math.floor(Math.random() * 256)); // 原来的操作
console.log(floor(random() * 256)); // 现在的操作4 箭头函数
箭头函数是ES6中新增的函数它用于简化函数的定义语法有自己的特殊语法接收一定数量的参数并在其封闭的作用域的上下文即定义它们的函数或其他代码中操作。
4.1 箭头函数的语法
// 箭头函数基本语法
() { }箭头函数以小括号开头在小括号中可以放置参数。小括号的后面要跟着箭头箭头后面要写一个大括号来表示函数体这是箭头函数的固定语法。箭头函数调用因为箭头函数没有名字我们通常的做法是把箭头函数赋值给一个变量变量名就是函数名然后通过变量名去调用函数即可。
script// 定义没有参数的箭头函数const fn () {console.log(123); // 输出结果123};// 函数调用fn();
/script4.2 箭头函数的特点
省略大括号
在箭头函数中如果函数体中只有一句代码且代码的执行结果就是函数的返回值此时可以省略函数体大括号。
script// 计算两个数值相加的结果const sum (num1, num2) num1 num2;// 等价于// const sum (num1, num2) {// return num1 num2;// };const result sum(10, 20); // 使用result接收sum()函数执行的结果console.log(result); // 在控制台输出result值结果为30
/script省略参数外部的小括号
在箭头函数中如果参数只有一个可以省略参数外部的小括号。
script// 只有一个参数的函数定义方式// 传统的函数定义方式// function fn(v) {// return v;// }// ES6中函数定义方式const fn v v;
/script定义带有一个参数的函数并在浏览器的弹出框中弹出参数值。
scriptconst fn v {alert(v);};fn(20);
/script4.3 箭头函数中的this关键字
ES6前JavaScript的this关键字指向的对象是在运行时基于函数的执行环境绑定的在全局函数中this指向的是window当函数被作为某个对象的方法调用时this就指向那个对象。ES6中箭头函数不绑定this关键字它没有自己的this关键字如果在箭头函数中使用this关键字那么this关键字指向的是箭头函数定义位置的上下文this。也就是说箭头函数被定义在哪箭头函数中的this就指向谁。箭头函数解决了this执行环境所造成的一些问题如解决了匿名函数this指向的问题匿名函数的执行环境具有全局性包括setTimeout()和setInterval()中使用this所造成的问题。
scriptconst obj { name: zhangsan };function fn() {console.log(this); // 输出结果{name: zhangsan}return () {console.log(this); // 输出结果{name: zhangsan}};}// call()方法可以改变函数内部的this指向将函数fn()内部的this指向obj对象const resFn fn.call(obj);resFn();
/script5 剩余参数
5.1 剩余参数的语法
剩余参数是指在函数中当函数实参个数大于形参个数时剩余的实参可以存放到一个数组中。
剩余参数语法允许将一个不确定数量的参数表示为数组。这种不确定参数的定义方式对于声明一个具有未知参数个数的函数非常方便。
scriptfunction sum(first, ...args) { // 接收剩余参数console.log(first); // 输出结果:10console.log(args); // 输出结果:[20, 30]}sum(10, 20, 30);
/script剩余参数是程序员自定义的一个普通标识符接收剩余参数的变量是一个数组Array的实例能够直接使用所有的数组方法如 sort()、map()、forEach()或pop()方法等。
script// 使用剩余参数计算多个数值的求和结果const sum (...args) {let total 0;args.forEach((item) {total item;});// 等价于args.forEach(item total item);return total;};console.log(sum(10, 20)); // 输出结果30console.log(sum(10, 20, 30)); // 输出结果60
/script5.2 剩余参数和解构赋值配合使用
script// 以数组的解构赋值为例let students [王五, 张三, 李四];let [s1, ...s2] students;console.log(s1); // 输出结果王五console.log(s2); // 输出结果[张三, 李四]
/script6 扩展运算符
6.1 扩展运算符的语法
扩展运算符和剩余参数的作用是相反的扩展运算符可以将数组或对象转换为用逗号分隔的参数序列。扩展运算符也用3个点 … 表示。
scriptlet ary [1, 2, 3];// ...ary相当于1, 2, 3console.log(...ary); // 输出结果1 2 3// 等价于console.log(1, 2, 3); // 输出结果1 2 3
/script使用扩展运算符将ary数组拆分成以逗号分隔的参数序列后又将参数序列放在了console.log()方法中此时参数序列中的逗号会被当成console.log()方法的参数分隔符所以输出结果中没有逗号。
6.2 扩展运算符的应用
利用扩展运算符合并数组
script// 数组合并的第1种方法let ary1 [1, 2, 3];let ary2 [4, 5, 6];// ...ary1 // 表示将ary1数组拆分成1, 2, 3// ...ary2 // 表示将ary2数组拆分成4, 5, 6let ary3 [...ary1, ...ary2]; console.log(ary3); // 输出结果(6) [1, 2, 3, 4, 5, 6]
/scriptscript// 数组合并的第2种方法let ary1 [1, 2, 3];let ary2 [4, 5, 6];ary1.push(...ary2);console.log(ary1); // 输出结果(6) [1, 2, 3, 4, 5, 6]
/script利用扩展运算符将伪数组转换为真正的数组 伪数组可以应用数组的length属性但是无法直接调用数组方法它也可以像数组一样进行遍历。典型的伪数组包括函数中的arguments、document.getElementsByTagName()返回的元素集合以及document.childNodes等。
bodydiv1/divdiv2/divdiv3/divdiv4/divdiv5/divdiv6/divscriptvar oDivs document.getElementsByTagName(div);console.log(oDivs); // 输出结果HTMLCollection(6) [div, div, div, div, div, div]var ary [...oDivs];ary.push(a); // 在数组中追加aconsole.log(ary); // 输出结果(7) [div, div, div, div, div, div, a]/script
/body7 模板字符串
7.1 模板字符串的语法
模板字符串是ES6新增的创建字符串的方式它使用反引号进行定义。
scriptlet name 这是一个模板字符串;console.log(name); // 输出结果这是一个模板字符串
/script7.2 模板字符串的应用
模板字符串可以解析变量
scriptlet name 张三;let sayHello Hello, 我的名字叫${name};console.log(sayHello); // 输出结果Hello, 我的名字叫张三
/script在模板字符串中可以换行
scriptlet result { name: zhangsan,age: 20,sex: 男 };let html divspan${result.name}/spanspan${result.age}/spanspan${result.sex}/span/div;console.log(html);
/script在模板字符串中可以调用函数
scriptconst fn () {return 我是fn函数;};let html 我是模板字符串 ${fn()};console.log(html); // 输出结果我是模板字符串 我是fn函数
/script8 ES6的内置对象扩展
8.1 数组的扩展方法
ES6为Array数组、String字符串等内置对象提供了许多扩展方法从而帮助开发人员提高开发效率。
通过扩展方法可以实现很多方便的功能如将伪数组转换为真正的数组、在数组中查找出符合条件的数组成员等。
Array.from()方法
Array构造函数提供了一个from()方法它可以接收一个伪数组作为参数返回值为转换后的结果这个结果是一个真正的数组。
scriptvar arrayLike {0: 张三,1: 李四,2: 王五,length: 3};var ary Array.from(arrayLike);console.log(ary); // 输出结果(3) [张三, 李四, 王五]
/script在Array构造函数中from()方法还可以接收两个参数这与数组中的map()方法类似它用于处理数组中的每个元素并将处理后的结果放入返回的数组中。
scriptvar arrayLike {0: 1,1: 2,2: 3,length: 3};var ary Array.from(arrayLike, (item) {return item * 2;});// 等价于var ary Array.from(arrayLike, item item * 2)console.log(ary); // 输出结果[2, 4, 6]
/scriptArray.of() 方法
将一组数转为数组。
console.log(Array.of(9, 4, 2, 7)); // [9, 4, 2, 7]数组实例的copyWithin()方法
用于操作当前数组自身用来把某些个位置的元素复制并覆盖到其他位置上去。copyWithin(target[, start, end])target 从该位置开始替换数据start 可选值默认为 0从该位置开始读取值end 可选值默认为 数组长度到该位置前停止读取注意三个参数都应该是 数值如果不是系统会自动转为数值该方法会影响到原数组
const numArr [1,2,3,4,5,6,7,8];
// 从0的位置开始替换从5开始读取值到8这个位置停止读取
const relArr numArr.copyWithin(0,5,8);
console.log(relArr);
console.log(numArr);数组实例的find()方法
在数组实例中ES6提供了一个find()方法它用于在数组中查找出第一个符合条件的数组成员。
scriptvar ary [{id: 1, name: 张三}, {id: 2,name: 李四}];let target ary.find((item, index) item.id 2);console.log(target); // 输出结果{id: 2, name: 李四}
/script数组实例的findIndex()方法
数组实例提供了一个findIndex()方法用于在数组中查找出第一个符合条件的数组成员的索引如果没有找到则返回-1。
script// 找出数组中大于9的元素的位置let ary [1, 5, 10, 15];let index ary.findIndex((value, index) {return value 9;});// 等价于let index ary.findIndex((value, index) value 9);console.log(index); // 输出结果2
/script数组实例的includes()方法
ES6中为数组实例提供了includes()方法来检查某个数组是否包含给定的值返回一个布尔值true表示包含给定的值false表示不包含给定的值。
scriptlet ary [a, b, c];let result ary.includes(a);console.log(result); // 输出结果trueresult ary.includes(e)console.log(result); // 输出结果false
/scriptkeys() 遍历键名values() 遍历值
var arr [张三,18,zzq2102,男,计算机];
var obj {name:张三,age:18,class:zzq2102,sex:男,major:计算机};
var json {name:张三,age:18,class:zzq2102,sex:男,major:计算机};// 循环输出数组
for(let key of arr.keys()){console.log(key);
}
for (let v of numArr.values()) {console.log(v);
}
// 循环输出对象和json
for(let key of Object.keys(obj)){console.log(key);
}
// 数组含空位
console.log([...[,a].keys()]); // [0, 1]数组实例的 entries() 键值对
let numArr [9, 5, 2, 7];
for (const [i, v] of numArr.entries()) {console.log(i, v);
}8.2 字符串的扩展方法
前面我们学习了数组的includes()方法它用于在数组中查找出第一个符合条件的数组成员的位置。
ES6也提供了字符串的includes()方法用来确定一个字符串是否包含在另一个字符串中。
除此之外ES6还提供了startsWith()方法和endsWith()方法同样可以用于字符串的查找。
字符串实例的startsWith()方法和endsWith()方法
startsWith()方法表示参数字符串是否在原字符串的头部用于判断字符串是否以某字符串开头endsWith()方法表示参数字符串是否在原字符串的尾部用于判断字符串是否以某字符串结尾。上述两个方法如果满足条件则返回true反之返回false。
scriptlet str Hello ECMAScript 2015;let r1 str.startsWith(Hello);console.log(r1); // 输出结果turelet r2 str.endsWith(2016);console.log(r2); // 输出结果false
/script字符串实例的repeat()方法
repeat()方法表示将原字符串重复n次它返回一个新字符串并接收一个数值作为参数表示将字符串重复多少次。
scriptconsole.log(y . repeat(5)); // 输出结果yyyyyconsole.log(hello . repeat(2)); // 输出结果hellohello
/script8.3 字面量对象简写方式
ES6中如果对象的属性名和属性值对应的变量名相同可以省略不写。
let age 20, name Alice;// ES5 定义对象字面量
let obj {age: age,name: name,say: function() {console.log(1);}
}// ES6 定义对象字面量
let obj {age,name,say() {console.log(1);}
}
console.log(obj.name)
obj.say();9 初识Symbol
9.1 Symbol的基本使用
Symbol是ES6中引入的原始数据类型它的功能类似于一种标识唯一性的ID值表示独一无二。
Symbol通过Symbol()函数创建。Symbol()函数可以接收一个字符串作为参数为新创建的Symbol实例提供描述信息该描述信息主要是在控制台中显示或转为字符串时使用以便于区分。Symbol不是对象所以Symbol()函数不能使用new命令。
scriptlet s1 Symbol(a);let s2 Symbol(b);console.log(s1); // 输出结果Symbol(a)console.log(s2); // 输出结果Symbol(b)
/script每个Symbol实例都是唯一的即使具有相同参数的两个Symbol()函数进行比较时函数的返回结果都会是false。
scriptlet s1 Symbol(a);let s2 Symbol(a);console.log(s1); // 输出结果Symbol(a)console.log(s2); // 输出结果Symbol(a)console.log(s1 s2); // 输出结果false
/script9.2 使用Symbol作为对象属性名
因为每一个Symbol的值都是不相等的所以Symbol作为对象的属性名可以保证属性不重名。这适用于对象由多个模块组成的情况可以防止某一个键被意外改写或覆盖。
scriptlet MY_NAME Symbol();// 第1种写法let a {};a[MY_NAME] Hello!;console.log(a); // 输出结果{ Symbol(): Hello! }
/scriptscriptlet MY_NAME Symbol();// 第2种写法 let a {[MY_NAME]: Hello!,};console.log(a); // 输出结果{ Symbol(): Hello! }
/scriptscriptlet MY_NAME Symbol();// 第3种写法let a {};Object.defineProperty(a, MY_NAME, { value: Hello! });console.log(a); // 输出结果{ Symbol(): Hello! }
/script10 Set数据结构
10.1 Set数据结构基本使用
ES6提供了新的数据结构Set。
Set类似于数组但是成员的值都是唯一的没有重复的值。
Set实例的方法分为两大类即操作方法用于操作数据和遍历方法用于遍历成员。
Set数据结构常用于电商网站的搜索功能中用户搜索完成后网站要记录用户搜索的关键字方便用户下次直接单击搜索历史关键字来完成搜索。
创建Set数据结构
Set本身是一个构造函数创建此构造函数的实例对象就是创建Set数据结构。
scriptconst s1 new Set(); // 使用new关键字创建Set构造函数的实例console.log(s1.size); // 输出结果0
/script初始化Set数据结构
在创建Set数据结构时也可以传递一个数组作为参数用来初始化。
scriptconst s2 new Set([a, b]);console.log(s2.size); // 输出结果2
/script利用Set数据结构给数组去重
在初始化Set构造函数时可以传递一个数组作为参数如果数组中有重复的值那么Set数据结构会把重复的值过滤掉。
scriptconst s3 new Set([a, a, b, b]);console.log(s3.size); // 输出结果2const ary [...s3];console.log(ary); // 输出结果(2) [a, b]
/script10.2 Set实例的操作方法
add()方法
Set实例提供的add()方法用于向Set数据结构中添加某个值它接收一个参数代表要添加的值返回Set结构本身。
scriptconst s4 new Set();s4.add(a).add(b);console.log(s4.size); // 输出结果2
/scriptdelete()方法
Set实例提供的delete()方法用于删除Set数据结构中的某个值它接收一个参数代表要删除的值返回一个布尔值如果结果为true则表示删除成功为false则表示删除失败。
scriptconst s4 new Set();s4.add(a).add(b);const r1 s4.delete(a);console.log(s4.size); // 输出结果1console.log(r1); // 输出结果true
/scripthas()方法
Set实例提供has()方法该方法接收一个参数并判断该参数是否为Set数据结构中的成员返回一个布尔值如果结果为true则表示包含该成员为false则表示不包含该成员。
scriptconst s4 new Set();s4.add(a).add(b);const r1 s4.delete(a);console.log(s4.size); // 输出结果1console.log(r1); // 输出结果trueconst r2 s4.has(a);console.log(r2); // 输出结果false
/scriptclear()方法
Set实例提供的clear()方法用于清除Set数据结构中的所有成员该方法没有返回值。
scriptconst s4 new Set();s4.add(a).add(b);s4.clear();console.log(s4.size); // 输出结果0
/script10.3 Set实例的遍历方法
Set数据结构的实例与数组一样也拥有一个forEach()方法用于遍历Set数据结构中的成员该方法可以对每个成员执行某种操作没有返回值。 注由于Set数据结构没有下标所以不能使用通过下标方式获取数据。 scriptconst s5 new Set([a, b, c]);s5.forEach(value {console.log(value); // 依次输出a、b、c});
/script11 Map数据结构
11.1 Map数据结构的基本使用
JavaScript 的对象Object本质上是键值对的集合属性值对但是传统上只能用字符串当作键。这给它的使用带来了很大的限制。
为了解决这个问题ES6 提供了 Map 数据结构。它类似于对象也是键值对的集合但是“键”的范围不限于字符串各种类型的值包括对象都可以当作键。也就是说Object 结构提供了“字符串—值”的对应Map 结构提供了“值—值”的对应是一种更完善的实现。如果你需要“键值对”的数据结构Map 比 Object 更合适。
总的来说就是Map数据结构类似于对象用来存储键值对。但对象只能使用字符串作为属性名而Map可以使用任意类型的数据做为属性名。
创建初始化Map数据结构
作为构造函数Map 也可以接受一个数组作为参数。该数组的成员是一个个表示键值对的数组。
let map new Map([[a,1],[b,2]])
let arr [1,2,3]
let map1 new Map([[arr,5]])
console.log(map1)11.2 Map实例的属性和方法
size 属性
let arr [1,2,3]
let map new Map([[a,1],[b,2]])
// 获取长度
console.log(map.size); // 2set()方法
map.set(name,John)
map.set(arr,100)get()方法
console.log(map.get(arr));has()方法
console.log(map.has(b));delete()方法
map.delete(a);clear()方法
map.clear()
console.log(map);11.3 Map实例的遍历方法
let map new Map([[a, 1], [b, 2]])// 遍历map
for(let i of map){// console.log(i);console.log(i[0]);
}// entries 键值对
// 等价于上面的写法
for(let data of map.entries()){console.log(data);
}// 分别获取键和值
for(let [key,val] of map.entries()){console.log(key,val);
}// map.keys() 返回所有的键名
for(let key of map.keys()){console.log(key);
}// 返回所有的值
for(let val of map.values()){console.log(val);
}