JavaScript【9】ES语法
1.闭包:
1.概述:
闭包是指有权访问另一个函数作用域中的变量的函数。即使外部函数已经执行完毕,闭包仍能记住并访问外部函数的变量。通过闭包实现了js中的封装特性;
2.创建闭包:
思路:
创建闭包我们可以通过嵌套函数实现,在前面我们了解过,在嵌套函数中,我们不能直接访问到内层函数,在闭包语法中,我们在嵌套函数的外层函数中返回内层函数,这样在调用外层函数时返回内层函数,再通过调用内层函数,就可实现内层函数的访问,进而实现了内层函数的封装;
语法示例:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<script src="myModule.js"></script>
<script>/*** 如何产生一个闭包* 当一个嵌套函数的内部 引用了嵌套函数* 外部的变量时 就产生了闭包*/function funA() {let a = 1;function funB() {a++;console.log(a)}return funB;}let fb = funA();fb();fb();fb();</script>
</body>
</html>

应用:
在js中我们可以通过闭包定义功能模块,将特有的功能 定义为JS文件,将所有的功能 或者 数据是封装在一个函数的内部,向外暴露 特定的模块;
示例:定义一个功能模块实现字符串转大小写
function myModule(str) {//转小写function tolowercase() {console.log(str.toLowerCase())}//转大写function toupcase() {console.log(str.toUpperCase())}return {tolowercase:tolowercase,toupcase:toupcase}
}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
//引用js文件
<script src="myModule.js"></script>
<script>//调用暴露函数let module = myModule('Hello World');//调用内部封装方法module.toupcase();module.tolowercase();
</script>
</body>
</html>

2.ES语法:
1.变量声明:
-
**var**:变量可重复
-
**let**:变量不可重复
-
**const**:常量,在声明时必须赋值,且不可重复,一旦赋值后就不可更改;
2.解构解析:
1.概述:
指将数组的元素或对象的属性解析为变量的过程;
2.解析数组:将数组元素解析为变量
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><script>//解析数组let arr=['测试数据1','测试数据2','测试数据3'] ;let [test1,test2,test3]=arr;console.log(test1,test2,test3);</script>
</body>
</html>

3.解析对象:将对象属性解析为变量:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><script>//解析对象let person={name:'张三',tag:['测试数据1','测试数据2','测试数据3']}//彻底解析:let{name,tag:[test1,test2,test3]}=person;console.log(name,test1,test2,test3)//部分解析://let{name,tag}=person;//console.log(name,tag)</script>
</body>
</html>
 
3.模板字符串:
1.概述:
模板字符串式增强版本的字符串,使用时通过反引号包裹字符串内容,在模板字符串中可直接书写el表达式来插入数据,另外模板字符串可直接换行,不用进行字符串拼接;
2.示例:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><script>let str='插入的数据';let s=`hello${str}`;console.log(s)</script>
</body>
</html>

4.对象简化语法:
1.概述:
<font style="color:rgba(0, 0, 0, 0.85);">在 ES6(ECMAScript 2015)及以后的版本中,对象简化语法提供了更简洁的方式来定义对象。主要包括以下几个方面:</font>
-
属性简化语法:<font style="color:rgba(0, 0, 0, 0.85);">当属性名和变量名相同时,可以省略属性值的写法,直接使用变量名。</font>
-
<font style="color:rgba(0, 0, 0, 0.85);"> 方法简化语法:定义对象的方法时,可以省略 </font>`<font style="color:rgba(0, 0, 0, 0.85);">function</font>`<font style="color:rgba(0, 0, 0, 0.85);"> 关键字和冒号。</font>
-
<font style="color:rgba(0, 0, 0, 0.85);"> 计算属性名:可以使用方括号包裹一个表达式来作为属性名,这个表达式会在对象初始化时被计算。</font>
-
<font style="color:rgba(0, 0, 0, 0.85);"> 解构解析语法简化:可以在对象解构赋值中使用对象简化语法来提取和重新命名属性。</font>
2.示例:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>let name='zs';let age=18;let sayhello=function () {console.log('hello',this.name);}let p={name,age,sayhello}p.sayhello();console.log(p) </script>
</body>
</html>

5.箭头函数:
1.概述:
箭头函数是ES6引入的一种用于简化函数的语法表达式
2.基本语法:
let 函数名=(参数1,参数2,....)=>{执行语句;}
3.说明:
- 如果形参只有一个 可以不用写小括号;
- 如果只有执行一条语句 大括号和return也可以不写 并会将结果返回;
- 箭头函数中 this的指向 是声明时所在作用域下的的this(与普通函数不同)箭头函数不会改变this的指向的;
4.示例:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<script>//箭头函数let sum1=(num1,num2)=>{return num1+num2;}console.log(sum1(1,1))//等价于function sum2(num1,num2) {return num1+num2;}console.log(sum2(1,1))</script>
</body>
</html>

5.嵌套函数中普通函数与箭头函数的对比:
1.内层函数为普通函数的嵌套函数:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<script>let zs={name:'张三',age:18,getName:function () {console.log(this)function sub() {console.log(this)}sub();}}zs.getName()</script>
</body>
</html>
说明:在上面案例中,我们创建了一个对象zs,在此对象中有一个方法为嵌套函数。在调用时,嵌套函数的外层函数作为zs对象的方法被调用,因此输出的this为调用对象。而内层函数与对象zs并没有直接关系,在被调用时,是作为函数,而非方法,因此内层函数输出的this为window。这也说明了普通的函数在嵌套调用时,this的指向发生了改变;
2.内层函数为箭头函数的嵌套函数:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<script>let zs={name:'张三',age:18,getName:function () {console.log(this)let sub=()=>{console.log(this)}sub();}}zs.getName();</script>
</body>
</html>

说明:上面案例中,我们将嵌套函数的内层函数改为了箭头函数,此时通过执行结果可以发现,在调用函数时,嵌套函数的内外两层的this都指向了调用对象zs。因为根据箭头函数的特点,在箭头函数中的this表示在其定义时的作用域下的this。在上面案例中,箭头函数是定义在zs对象的方法(嵌套函数)的内部,因此其作用域为zs对象,因此箭头函数中的this与外层函数中的this是相同的;
6.rest参数:等同于Java中的动态参数
1.概述:
在 ES6(ECMAScript 2015)中,引入了 rest 参数(Rest parameters)来更方便地处理函数的参数。Rest 参数允许我们将一个不定数量的参数表示为一个数组。它使用三个点(<font style="color:rgba(0, 0, 0, 0.85);">...</font>
)后跟一个参数名来定义。
2.示例:
function add(...args) {console.log(args)}add(1,1,2,3,45,85,8,8);
7.扩展运算符
1.概述:
扩展运算符用三个点(<font style="color:rgba(0, 0, 0, 0.85);">...</font>
)表示,可以将一个可迭代对象(如数组、字符串等)展开为单个的元素。
2.示例:
const arr2 = ['测试数据A','测试数据B','测试数据D']
console.log({...arr2)
3.应用场景:
1.合并数组:
const arr2 = ['测试数据A','测试数据B','测试数据D']const arr1 = ['测试数据C','测试数据E','测试数据F']console.log([...arr1,...arr2,"测试数据Y"])
2.合并对象:
let obj1 = {name: "zhangsan"};let obj2 = {age: 18};console.log({...obj1, ...obj2})
8.迭代器:
1.概述:
迭代器 iterator是一种为各种不同的数据提供统一的访问机制;
2.使用:
方式1:for of循环:内部通过迭代器实现
const arr = ['测试数据A', '测试数据B', '测试数据D'];for (const value of arr) {console.log(value)}
方式2:直接使用:
const arr = ['测试数据A', '测试数据B', '测试数据D'];let iterator = arr[Symbol.iterator]();console.log(iterator.next())console.log(iterator.next())console.log(iterator.next())console.log(iterator.next())
9.js中的集合
1.set集合:
概述:
Set集合,要求元素唯一不可重复,实现了 iterator 接口,可以使用 扩展运算符 或者 for of 进行遍历;
创建set集合:
let s = new Set();
let s = new Set([1,2,3,1,2,5,6,8,9]);
操作方法:
let s = new Set([1,2,3,1,2,5,6,8,9]);
//获取元素个数
console.log(s.size)
// 通过 add 方法 新增元素 并 返回当前集合console.log(s.add(4));
//删除元素 并返回 booleanconsole.log(s.delete(5));
//检查元素是否存在 返回 booleanconsole.log(s.has(5))
//清除所有元素s.clear();
2.map集合:
创建方式:
let m = new Map();
let m = new Map([['name', '张三'],['gender', '男'],]);
操作方法;
let m = new Map([['name', '张三'],['gender', '男'],]);//元素个数console.log(m.size);//添加获取元素console.log(m.set('age',20))console.log(m.get('age'));//验证集合中 key是否存在console.log(m.has("age"));//清除 集合m.clear()//返回所有的keyconsole.log(m.keys())//返回所有的值console.log(m.values())
10.类
1.概述:
在 ES6(ECMAScript 2015)中引入了类(class)的概念,使得 JavaScript 的面向对象编程更加直观和易于理解。
2.定义:
通过class关键字来定义一个类
class MyClass {constructor() {// 构造函数,用于初始化对象}// 方法定义method1() {//...}method2() {//...}
}
3.构造函数;
构造函数是类中的特殊方法,用于在创建对象时初始化对象的属性。构造函数使用 <font style="color:rgba(0, 0, 0, 0.85);">constructor</font>
关键字定义,并且在创建对象时自动调用。
class MyClass {constructor() {// 构造函数,用于初始化对象}
}
4.方法:
在类中定义的函数称为方法。方法可以访问对象的属性,并执行特定的操作。
class MyClass {// 方法定义method1() {//...}method2() {//...}
}
5.继承:在ES6语法中支持extends关键字实现继承
class Phone {//构造方法constructor(brand, color, price) {this.brand = brand;this.color = color;this.price = price;}// 方法call() {console.log("我可以打电话")}}//子类class SmartPhone extends Phone {constructor(brand, color, price, screen, pixel) {super(brand, color, price);this.screen = screen;this.pixel = pixel;}//子类的方法photo() {console.log("我可以拍照")}playGame() {console.log("我可以打游戏")}//重写父类方法call() {console.log("我可以视频通话")}//静态方法static run() {console.log("我可以运行程序!")}}let Nokia = new Phone('诺基亚', '黑色', 200);Nokia.call();const phoneHW = new SmartPhone('华为', '灰色', 6000, '8.7inch', '800W');phoneHW.playGame();phoneHW.call();SmartPhone.run();console.log(phoneHW)