目录
2.17.3 Number.isFinite 检测数值是否为有限数
2.17.4 Number.isNaN 检测一个数值是否为 NaN
2.17.5 Number.parseInt Number.parseFloat 字符串转整数
2.17.6 Number.isInteger 判断一个是否为整数
2.17.8 Math.sign 判断一个数到底为正数(1) 负数(-1) 还是零(0)
2.18.3 Object.setPrototypeOf 设置原型对象 Object.getPrototypeOf 获取原型对象
2.19.5 导入模块的写法方式 【标签中导入和专门的导入文件】
2.19.6 使用ES6的导入导出,在有些浏览器不能识别,所以需要将ES6转为ES5
4.2 Object.values 和 Object.entries
4.2.1 Object.values() 方法返回一个给定对象的所有可枚举属性的数组。
4.2.2 Object.entries() 方法返回一个给定对象自身可遍历属性 [key, value] 的数组
4.2.3 Object.getOwnPropertyDescriptors()方法返回指定对象所有自身属性的描述对象
6.1 对象扩展方法 Object.fromEntries 【转为对象】
6.4 Symbol.prototype.description 获取Symbol描述
7.3 String.prototype.matchAll 方法 分组捕获的结果
ES 全称 EcmaScript,是脚本语言的规范,而平时经常编写的 JavaScript,是EcmaScript的一种实现,所以 ES 新特性其实指的就是 JavaScript 的新特性。
一、ESMAScript相关介绍
1.1 什么是ECMA
ECMA(European Computer Manufacture Associate)中文名称为欧洲计算机制造协会,这个组织的目标是评估、开发和认可电信和计算机标准。1994年后该组织改名为 Ecma国际。
1.2 什么是ESMAScript
ESMAScript 是由 Ecma 国际通过 ECMA-262 标准化的脚本程序设计语言。
1.3 什么是ECMA-262
Ecma 国际指定了需要标准,而 ECMA-262 只是其中的一个,所有标准列表查看
Standards - Ecma International
1.4 ECMA-262 l历史
ECMA-262 (ECMAScript)历史版本查看网址
第1版 | 1997年 | 指定了语言的基本语言 |
第2版 | 1998年 | 较小改动 |
第3版 | 1999年 | 引入正则、异常处理、格式化输出等。IE开始支持。 |
第4版 | 2007年 | 过于激进,未发布 |
第5版 | 2009年 | 引入严格模式、JSON、扩展对象、数组、原型、字符串、日期方法 |
第6版 | 2015年 | 模块化、面向对象语法、Promise、箭头函数、let、const、数组解构赋值等等 |
第7版 | 2016年 | 幂运算符、数组扩展、Async/await 关键字 |
第8版 | 2017年 | Async/await、字符串扩展 |
第9版 | 2018年 | 对象解构赋值、正则扩展 |
第10版 | 2019年 | 扩展对象、数组方法 |
ES.next | 动态只想一个版本 |
注:从ES6开始,每年发布一个版本,版本号比年份最后一位大1 。
1.5 谁在维护 ECMA-262
TC39(Technical Committee 39)是推进 ECMAScript 发展的委员会。其会员都是公司(其中主要是浏览器厂商,有苹果、谷歌、微软、因特尔等)。TC39定期召开会议,会议由会员公司代表与特邀专家出席。
1.6 为什么学习ES6
- ES6 的版本变动内容最多,具有里程碑意义
- ES6加入许多新的语法特性,编程实现更简单、高效
- ES6是前端发展趋势,就业必备技能
1.7 ES6 兼容性
https://kangax.github.io/compat-table/es6/ 可查看兼容性
二、ESMAScript 6 新特性
2.1 let声明变量
2.1.1 let声明变量
1.变量不能重复声明;
2.变量有块级作用域;
3.不存在变量提升
4.不影响作用域链
<script>
// 声明变量的方式
let a;
let b, c, d;
let e = 100;
let f = 521, g = "ll", h = [];
// 1.变量不能重复声明
// let star = "ll";
let star = "lxxl";
// 重复声明就会报错:Uncaught SyntaxError: Identifier 'star' has already been declared
// var 是可以的,使用最新的值。
var star2 = "ll";
var star2 = "lxxl";
console.log(star2);
// 2.块级作用域
{
let girl = "cc"
}
// 报错:Uncaught ReferenceError: girl is not defined
// console.log(girl);
// 3.不存在变量提升
// 报错:Uncaught ReferenceError: Cannot access 'song' before initialization
// console.log(song);
let song = 'gg';
// var 定义的变量存在变量提升
// 4.不影响作用域链
{
let school = "xinchi";
function fn() {
console.log(school);
}
fn();
}
</script>
2.1.2 let实践案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>let 实践案例</title>
<style>
.page-header {
border-bottom: 1px #ccc solid;
}
.item {
width: 50px;
height: 20px;
border: 1px #ccc solid;
display: inline-block;
margin-right: 10px;
}
</style>
</head>
<body>
<div class="container">
<h2 class="page-header">点击切换颜色</h2>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<script>
// 获取div元素
let items = document.getElementsByClassName('item');
// 遍历并绑定事件
for (let i = 0; i < items.length; i++) {
items[i].onclick = function () {
// this指向当前调用事件函数的dom
console.log(this);
// 这种也可以,这里想区分 let 和 var 的不同
// this.style.background = "pink";
// 用var定义变量i时这种方式会报错。
items[i].style.background = "pink";
}
}
// 当使用var定义时,实际i为全局变量,并且在最后一次i已经被自增为3
// 所以会报错
{
var i = 0;
}
{
var i = 1;
}
{
var i = 2;
}
// 但是使用let定义
// 在事件函数中找i,找不到,便去上层去找,因为let有块级作用域,所以i是当前的i,不是最后自增之后的i
{
let i = 0;
items[i].onclick = function () {
console.log(this)
// this.style.background = "pink";
items[i].style.background = "pink";
}
}
{
let i = 1;
}
{
let i = 2;
}
</script>
</body>
</html>
2.2 const 声明常量
2.2.1 const声明常量
1.一定要赋初始值;
2.一般常量使用大写(潜规则);
3.常量的值不能修改
4.块级作用域
5.对于数组和对象的元素修改,不能算作对常量的修改,不会报错
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>const声明常量</title>
</head>
<body>
<script>
// 声明常量
const SCHOOL = "xinchi";
// 1.一定要赋初始值
// 报错:Uncaught SyntaxError: Missing initializer in const declaration
// const A;
// 2.一般常量使用大写(潜规则)
const a = 100;
// 3.常量的值不能修改
// 报错:Uncaught TypeError: Assignment to constant variable.
// SCHOOL = "heichi";
// 4.块级作用域
{
const PLAYER = "uzi";
}
// 报错:Uncaught ReferenceError: PLAYER is not defined
// console.log(PLAYER);
// 5.对于数组和对象的元素修改,不算作对常量的修改,不会报错
const TEAM = ['a', 'b', 'c', 'd'];
TEAM.push('e');
// 直接修改常量就会报错
// 报错:Uncaught TypeError: Assignment to constant variable.
TEAM = 100;
</script>
</body>
</html>
2.3 解构赋值
1.数组的解构赋值
const F4 = ['xl', 'gl', 'll', 'gx']; let [x, g, ll, xg] = F4;
2.对象的解构赋值
const zhao = { name: "zhao", age: 'no',say: function () {console.log('say hello');}}
可以全部取出:let { name, age1, say } = zhao;
也可以单独取一个属性:let { say } = zhao;
注意:对象的解构赋值,变量必须和对象属性名一致
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>解构赋值</title>
</head>
<body>
<script>
// ES6 允许按照一定模式从数组和对象中提取值,对变量进行赋值,这被称为解构赋值
// 1.数组的解构
const F4 = ['xl', 'gl', 'll', 'gx'];
let [x, g, ll, xg] = F4;
console.log(x); // xl
console.log(g); // gl
console.log(ll); // ll
console.log(xg); // gx
// 2.对象的解构
const zhao = {
name: "zhao",
age: 'no',
say: function () {
console.log('say hello');
}
}
// 注意:对象的解构赋值,变量必须和对象属性名一致。
// let { name, age1, say } = zhao;
// console.log(name); // zhao
// console.log(age1); // undefined
// console.log(say); //function () {console.log('say hello');}
// 也可以单独取一个属性
let { say } = zhao;
console.log(say);
</script>
</body>
</html>
2.4 模板字符串
语法:let str = ` hello `;
可以包含参数:let world="world"; let str2 = ` hello ${world}`;
参数语法:${ 变量}
注意:内容中可以出现换行符,空格等;原样输出,不会去掉空格、换行符。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>模板字符串</title>
</head>
<body>
<script>
// ES5字符串 "" ''
// ES6 引入新的声明字符串的方式 【 ` ` 】
// 1.声明
let str = `我也是一个字符串`;
console.log(str, typeof str);
// 2.内容可以直接出现换行符、空格,不改动直接输出
let str2 = `<ul>
<li>沈腾</li>
<li>玛丽</li>
<li>艾伦</li>
</ul>`;
console.log(str2);
// 3.变量拼接
// ES5用字符串和+ 一起拼接字符串
// ES6 模板字符串可以使用变量来替换需要拼接的值.
// 变量语法:${变量}
let str3 = "魏翔";
let out = `${str3}是一个好演员`;
console.log(out);
</script>
</body>
</html>
2.5 简化对象写法
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样更简洁。
注意:只有当变量和对象的属性名需要保持一致才能使用对象的简化对象写法。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>简化对象写法</title>
</head>
<body>
<script>
// ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。
// 这样可以更加简洁
let name = "ll";
let change = function () {
console.log('change myself');
}
// 只有变量名和属性名要保持一致才能简写
const school = {
name,
change,
improve() {
console.log('简写方式2')
},
// 就类似于
improve: function () {
console.log('简写方式')
}
};
console.log(school);
school.change();
school.improve();
</script>
</body>
</html>
2.6 箭头函数
2.6.1 箭头函数定义、注意事项
ES6 允许使用 【箭头函数】 (==>)定义函数
注意:
1.this 是静态的。this 始终指向函数声明的作用域下的 this的值
2.不能作为构造函数实例化对象
3.不能使用 arguments 变量
4.箭头函数的简写
1)省略小括号,当形参有且只有一个的时候; let add = n => {return n + n;}
2)省略花括号,当代码体只有一条语句的时候,此时 return 必须省略;
而且语句的执行结果就是函数的返回值;
let pow = (n) => n * n;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>箭头函数</title>
</head>
<body>
<script>
// ES6 允许使用 【箭头函数】 (==>)定义函数
// 声明一个函数
let fn = () => {
}
let fn2 = (a, b) => {
return a + b;
}
// 调用函数
let result = fn2(1, 2);
console.log(result);
// 1.this 是静态的。this 始终指向函数声明的作用域下的 this的值
function getName() {
console.log(this.name);
}
let getName2 = () => {
console.log(this.name);
}
// 设置 window 对象的name属性
window.name = "ll";
const school = {
name: 'lxl'
};
//直接调用
getName(); // ll 指向window的name
getName2(); // ll 指向window的name
// call方法调用
getName.call(school); // lxl 可以改变this指向,指向school
getName2.call(school); // 不能改变this指向
// 2.不能作为构造函数实例化对象
let Person = (name, age) => {
this.name = name;
this.age = age;
}
// 报错:Uncaught TypeError: Person is not a constructor
// let me = new Person('ll', 20);
// console.log(me);
// 3.不能使用 arguments 变量
let fnn = () => {
// 报错:Uncaught ReferenceError: arguments is not defined
// console.log(arguments);
}
fnn(1, 2, 3);
// 4.箭头函数的简写
// 1) 省略小括号,当形参有且只有一个的时候
let add = n => {
return n + n;
}
console.log(add(9)); // 18
// 2) 省略花括号,当代码体只有一条语句的时候,此时 return 必须省略
// 而且语句的执行结果就是函数的返回值
let pow = (n) => n * n;
console.log(pow(2));
</script>
</body>
</html>
2.6.2 箭头函数实践
箭头函数适合 与 this 无关的回调;如:定时器,数组的方法回调。
箭头函数不适合与 this有关的回调,事件回调,对象的方法。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>箭头函数实践</title>
<style>
div {
width: 200px;
height: 200px;
background: #58a;
}
</style>
</head>
<body>
<div id="ad"></div>
<script>
// 需求:点击div 2s后颜色变成橘色
// 获取元素
let ad = document.getElementById('ad');
// 绑定事件
ad.addEventListener('click', function () {
// 定时器
console.log(this); // 这里的this指向 当前点击的dom
// 解决办法一:在这里保存一个当前的饿this
let _this = this;
// setTimeout(function () {
// // 修改背景颜色 this
// console.log(this);// 指向window,所以报错
// // 报错:Uncaught TypeError: Cannot set properties of undefined (setting 'background')
// // this.style.background = 'pink';
// // 使用当前的this
// _this.style.background = 'pink';
// }, 2000);
// 解决办法二,使用箭头函数,this 始终指向函数声明的作用域下的 this的值
setTimeout(() => {
// 修改背景颜色 this
console.log(this);// 指向当前函数声明的作用域的this
this.style.background = 'pink';
}, 2000);
})
// 需求2:从数组中返回偶数的元素
const arr = [1, 2, 3, 3, 5, 6, 7, 8];
const result = arr.filter(function (item) {
if (item % 2 === 0) {
return true;
} else {
return false;
}
})
console.log(result);
// 使用箭头函数并简写
const result1 = arr.filter((item) => { return item % 2 === 0 });
// 发现只有一条语句和有且只有一个参数,在简写:去掉() {} 和 return
const result2 = arr.filter(item => item % 2 === 0);
console.log(result2); // [2, 6, 8]
// 箭头函数适合 与 this 无关的回调;如:定时器,数组的方法回调。
// 箭头函数不适合与 this有关的回调,事件回调,对象的方法
const obj = {
name: 'll',
getName: function () {
console.log(this); //指向当前的调用者
this.name;
(() => {
console.log(this) // 指向obj
})()
},
getAge: () => {
console.log(this); //指向window
(() => {
console.log(this) // 指向window
})()
}
}
const obj1 = {
name: "loo"
}
obj.getName();
obj.getName.call(obj1);
obj.getAge();
</script>
</body>
</html>
2.7 函数参数默认值
ES6 允许给函数参数赋值初始值
1.形参初始值 具有默认值的参数,一般位置要靠后(潜规则)
2.与解构赋值结合。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>函数参数默认值</title>
</head>
<body>
<script>
// ES6 允许给函数参数赋值初始值
// 1.形参初始值 具有默认值的参数,一般位置要靠后(潜规则)
// 如果放在前面,就会导致赋值可能不准
function add(a, b, c = 10) {
return a + b + c;
}
let result = add(1, 2);
console.log(result); //13
// 2.与解构赋值结合
// 对象解构赋值可以,保证形参和实参名称一致即可
function connect({ host = '127.0.0.1', username, age, port }) {
console.log(host);
console.log(username);
console.log(age);
console.log(port);
}
connect({
age: "ll",
username: 20,
port: 500
})
// 数组解构赋值也可以
function connect2([num1, num2, num3 = 10]) {
console.log(num1);
console.log(num2);
console.log(num3);
}
connect2([1, 2])
</script>
</body>
</html>
2.8 rest参数
ES5 的 arguments 的理解:Arguments 对象 - JavaScript | MDN
ES6 引入rest 参数,用于获取函数的实参,用来代替 arguments
注意:
1.rest 参数必须要放到最后。
2.rest 参数是一个数组,可以使用数组的filter,some,every,map 等方法。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>rest参数</title>
</head>
<body>
<script>
// ES6 引入rest 参数,用于获取函数的实参,用来代替 arguments
// ES5 获取实参的方式
function date() {
// arguments 是一个对应于传递给函数的参数的类数组对象。
// arguments对象不是一个 Array 。它类似于Array,但除了length属性和索引元素之外没有任何Array属性。例如,它没有 pop 方法。但是它可以被转换为一个真正的Array
console.log(arguments); //
console.log(typeof arguments); // 'object'
console.log(arguments[0]); //aa 可以通过数组的方式获取
// 转换为真正的数组
let args = Array.from(arguments);
let args2 = [...arguments];
console.log(args, args2); // ['aa', 'bb', 'cc']
}
date('aa', 'bb', 'cc');
// rest 参数
function date2(...args) {
console.log(args); // [1, 2, 3] 是一个数组,就包含filter,some,every,map 等方法
}
date2(1, 2, 3);
// rest 参数必须要放到最后
function fn(a, b, ...args) {
console.log(a); // 1
console.log(b); // 2
console.log(args); // [3, 4, 5, 6]
}
fn(1, 2, 3, 4, 5, 6);
// 不放在后面就会报错
// Uncaught SyntaxError: Rest parameter must be last formal parameter
// function fn1(a, ...args, b) {
// console.log(a);
// console.log(b);
// console.log(args);
// }
// fn1(1, 2, 3, 4, 5, 6);
</script>
</body>
</html>
2.9 spread 扩展运算符
2.9.1 扩展运算符
【...】 扩展运算符能将【数组】转换为逗号分隔的【参数序列】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>spread 扩展运算符</title>
</head>
<body>
<script>
// 【...】 扩展运算符能将【数组】转换为逗号分隔的【参数序列】
// 声明一个数组 ...
const tfboys = ['易烊千玺', '王源', '王俊凯'];
// 声明一个函数
function chunwan() {
console.log(arguments);
}
chunwan(...tfboys); //类似:chunwan('易烊千玺', '王源', '王俊凯');
</script>
</body>
</html>
2.9.2 扩展运算符的应用
1.数组的合并。
2.数组的克隆(浅克隆)。
3.将伪数组转为真正的数组。如:arguments参数、获取的一组dom等
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>扩展运算符的应用</title>
</head>
<body>
<div></div>
<div></div>
<div></div>
<p>1</p>
<p>2</p>
<script>
// 1.数组的合并
const kuazi = ["肖央", "王太利"];
const fenghuang = ['曾毅', '玲花'];
// 使用数组的 concat 方法
// const zuixuanxiaopingguo = kuazi.concat(fenghuang);
// 使用扩展运算符
const zuixuanxiaopingguo = [...kuazi, ...fenghuang];
console.log(zuixuanxiaopingguo); //['肖央', '王太利', '曾毅', '玲花']
// 2.数组的克隆(浅克隆)
const sanzhihua = ['E', 'G', 'M'];
const sanyecao = [...sanzhihua];
console.log(sanyecao); //['E', 'G', 'M']
sanzhihua.push({
a: 123
});
// 更改原数组的引用类型的值,就会影响复制的值,所以证明是浅拷贝
const me = [...sanzhihua];
console.log(me); // ['E', 'G', 'M', 3: {a: 456}]
sanzhihua[sanzhihua.length - 1].a = 456;
console.log(me); // ['E', 'G', 'M', 3: {a: 456}]
// 3.将伪数组转为真正的数组
const p = document.querySelector('p');
// querySelector 返回的一个dom,且取的是第一个
console.log(p);
const divs = document.querySelectorAll('div');
// 返回的是一组
console.log(divs);
const divArr = [...divs];
console.log(divArr); // [div, div, div]
</script>
</body>
</html>
2.10 Symbol基本使用
Symbol 详细了解地址: Symbol - JavaScript | MDN
ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。
Symbol的特点:
1) Symbol 的值是唯一的,用来解决命名冲突的问题。
2) Symbol 值不能与其他数据进行运算。
3) 定义的对象属性不能使用 for ... in 循环遍历,但是可以使用 Reflect.ownkeys 来获取对象的所有键名
2.10.1 创建Symbol
创建 Symbol方式:
1. 使用Symbol()创建 。 如: let s = Symbol();
2. 使用Symbol.for 创建。 如:let s4 = Symbol.for('aa');
注意:</