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));
//删除元素 并返回 boolean
console.log(s.delete(5));
//检查元素是否存在 返回 boolean
console.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()
//返回所有的key
console.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)