2024年9月18日--关于ES6(1)
一 ECMAScript的简介
1.1 什么是 ECMAScript
ECMAScript,发音 [ek - ma - script] 。在中文中, ECMAScript 可以读作 "伊克玛Script"。
官方定义: ECMAScript 是定义脚本语言的规范, 而 JavaScript 是遵循 ECMAScript 规范实现的一种编程语言。ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
1.2 ES6 和 JavaScript 的区别
ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现(另外的 ECMAScript 方言还有 JScript 和 ActionScript)。日常场合,这两个词是可以互换
ES6(ECMAScript 2015)是ECMAScript规范的第六个版本,JavaScript基于第六版的规范,新增很多功能。
1.3 ES6的新规范
-
ES6引入了"块级作用域",使用let和const关键字来声明变量和常量,使变量的作用域清晰可控
-
ES6引入了"箭头函数",箭头函数比传统的函数语法更简洁, 具有更少的冗余代码
-
ES6引入了"类(Class)"的概念,这是一种基于原型的面向对象编程的语法糖, 使用类可以更方便地创建和管理对象
-
ES6引入了"模板字符串", 使用反引号(`)创建字符串可以方便地嵌入变量和表达式
-
ES6引入了"解构赋值", 这是一种新的赋值语法,可以将数组或对象的属性直接赋值给变量
-
ES6引入了"函数参数默认值"
-
ES6引入了"Promise对象", 简化了异步编程, 使其更可读和可维护
-
ES6引入了 Set、Map 等
-
ES6引入了"模块化"(ES Module)
二 变量与常量
2.1 var定义变量(ES6之前)
-
var可以在全局范围或者函数范围内声明变量
// 变量与常量 var num1 = 10; // 在整个window中 function f1() { var num2 = 20; //只能在函数内访问 } console.log(window.num1); //全局变量会自动绑定到window对象上 console.log(num2); // Uncaught ReferenceError: num2 is not defined
-
var 变量可以重新声明和修改
var myname = "michael"; console.log(myname) myname = "jackson"; //修改 console.log(myname) var myname = "lucy"; //重新声明,不会报错; 如果在java中,就报错了 console.log(myname);
-
var 的变量提升:在执行代码前,变量或函数的声明会移至到作用域的顶端。比如:
我们这样写 会被解析成这样 console.log(age);
var age = 20
var age
console.log(age)
age=20
变量提升后,会使用undefined进行初始化,因此并不会报
变量没有被定义的错误
-
总结如下:
var定义的变量,与java语言中的变量的用法相比较,并没有那么严谨。因此ES6之后引入了两个let和const,以及块级作用域的概念。
2.2 let和const(ES6之后)
从ES6开始,引入了块级作用域,以及let和const两个关键字来规范变量的用法。目的是要像java变量一样更具严谨性。块级作用域,其实就是{}
包含的范围。直接书写{}
,或者函数体的{}
就是块级作用域。
2.2.1 let定义的变量
-
必须先声明和初始化,才能使用变量
-
变量的作用域,就是其所在的
{}
,在作用域范围外使用,会报错 -
在作用域内,变量可以被修改,但是不能重复声明
2.2.2 const定义的变量
-
const定义的变量,是==常量==,因此不能被再次赋值
-
const定义的常量,也是有其作用域的,只能在作用域内被访问。
三 模版字符串与解构
3.1 模版字符串
let name = "张三" let age = 21; let line = "我是" + name + ",今年我" + 21 + "岁" console.log("line的值:", line); // 模版字符串(返单引号):`` 使用${变量}的形式引用外部变量, 可以使用+号了,还可以换行 let start = `郑重的说一下:` let info = `${start}我是${name},今年我${age}岁` console.log(info); let mult = `哈哈哈, 你好 ` console.log(mult);
3.2 解构
//解构: 可以从数组或者对象中提取值并赋值给变量 //语法 let [变量1,变量2,....] = 数组|对象 // 解构数组 let [x, y, z] = [1, 2, 3] //解构出三个元素 console.log(x, y, z); let [m, n] = [1, 2, 3] //解构出前两个 console.log(m, n); let [, b,] = [1, 2, 3] // 解构出第二个元素 console.log(b); let [a, ...other] = [1, 2, 3] // ...other 表示剩余的所有元素 console.log(a, other); let [x1, x2, x3, x4 = 100] = [1, 2, 3] // ... 设置默认值 console.log(x1, x2, x3, x4); //完成两个变量的值的交换 let a1 = 10; let b1 = 20; [b1, a1] = [a1, b1] console.log(a1, b1); //解构对象 let person = { 'name': 'michael', 'gender': 'male', 'age': 21 } // 获取name属性, 变量名必须和属性名相同 let { name } = person console.log("name:", name); //自定义变量名 let { name: myName, gender, age: myAge, sayHi } = person console.log(myName, gender, myAge); //设置默认值 let { salary = 10000 } = person; console.log("salary", salary);
四 JS中的数据类型
之前我们学习过,JS中的数据类型主要分为两类,
一类是数值(基本)类型
String,Number,Boolean, null, undefined, Symbol
一类是引用数据(对象)类型
Object,Array,Function,RegExp,Date
在ES6中,又引入了Set、Map、Class等引用类型…
4.1 Set、扩展运算符
Set 是一种特殊的数据结构,是用于存储无序且唯一的值的集合对象
// let nums = new Set(); //创建一个空的Set集合 let nums = new Set(['a', 'b', 'c', 'c']); console.log(nums); //Set(3) {'a', 'b', 'c'} console.log(nums.size); // 3 // 添加元素 nums.add('d'); nums.add('c'); //添加不进去,因为重复了 console.log(nums); // Set(4) {'a', 'b', 'c', 'd'} // 删除元素 nums.delete('c') console.log(nums); // Set(3) {'a', 'b', 'd'} //查看是否包含某元素 console.log("是否包含:", nums.has('d')) //是否包含: true //Array.from(..) Set转数组 let arr_1 = Array.from(nums); console.log(arr_1); // (3) ['a', 'b', 'd'] //扩展运算符: 用于展开可迭代对象(如字符串,数组,集合等) let arr_2 = [...nums] console.log(arr_2); // (3) ['a', 'b', 'd'] //扩展运算符的应用1 let n1 = [3, 4, 5] let n2 = [7, 8, 9] let n3 = [1, 2, ...n1, 6, ...n2, 10]; console.log(n3); //(10) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] //扩展运算符的应用2 let obj1 = { idcard: 1001 } let obj2 = { address: "长春" } let obj3 = { name: "lily", ...obj1, age: 21, ...obj2 } console.log(obj3); //{name: 'lily', idcard: 1001, age: 21, address: '长春'} //遍历1: for...of形式 for (el of nums) { console.log(el); } //遍历2: forEach函数 nums.forEach((value) => console.log(value)) //清空Set nums.clear(); console.log(nums); console.log(nums.size); //数组转Set: 实现去重 let arr_3 = [1, 2, 3, 2, 3, 4] let mynums = new Set(arr_3); console.log(mynums); //Set(4) {1, 2, 3, 4}
4.2 Map
Map 是一种特殊的数据结构,是用于存储键值对的==有序==集合对象
//创建Map集合
// let persons = new Map() //创建一个空的Map集合
let persons = new Map([
["1002", "李四"],
["1001", "张三"]
])
console.log(persons) //Map(2) {'1001' => '张三', '1002' => '李四'}
console.log(persons.size); // 2
//添加元素 或 替换
persons.set('1003', '王五')
console.log(persons); //Map(3) {'1001' => '张三', '1002' => '李四', '1003' => '王五'}
persons.set('1003', '赵六') //Map中的key是唯一的,再次使用相同key进行set时,会覆盖掉原有的value.
console.log(persons); //Map(3) {'1001' => '张三', '1002' => '李四', '1003' => '赵六'}
//删除元素
persons.delete('1003')
console.log(persons); //Map(2) {'1001' => '张三', '1002' => '李四'}
//是否包含指定元素
console.log("是否包含:", persons.has('1002')); //是否包含: true
//Map 转 数组
let arr_1 = Array.from(persons)
console.log(arr_1); //(2) [Array(2), Array(2)]
console.log("第一个元素的第二个值:", arr_1[0][1]);
//使用扩展运算符,将Map集合转成数组
let arr_2 = [...persons]
console.log(arr_2); //(2) [Array(2), Array(2)]
console.log("第一个元素的第二个值:", arr_1[0][1]);
//遍历1: for...of
for ([key, value] of persons) {
console.log(key, value);
}
//遍历2: forEach函数
persons.forEach((value, key) => { console.log(key, value) })
//遍历3:
let ks = persons.keys()
for (key of ks) {
let value = persons.get(key)
console.log(key, value);
}
//遍历4:
let vs = persons.values();
for (v of vs) {
console.log(v);
}
//遍历5:
let entries = persons.entries();
for ([key, value] of entries) {
console.log(key, value);
}
//清空Map
persons.clear();
console.log(persons.size);
4.3 class
ES6引入了class关键字,用来定义类。 类是多个具有相同特征的对象的模版,用一个类可以创建许多不同的对象。
4.3.1 基本用法
-
语法格式:
class 类名{…}
-
类名首字母需要大写,用于区别变量名。
-
类体中可以定义属性、构造方法、实例方法等
4.3.2 案例演示
案例1
class Person { name; age; constructor(name, age) { this.name = name; this.age = age; } //实例方法(普通方法) info() { return "姓名:" + this.name + ", 年龄:" + this.age } } let p1 = new Person('michael', 21); console.log(p1); console.log(p1.name, p1.age); console.log(p1.info())
案例2:
class Student { //构造函数, 可以指定形参。 属性如果没有显式声明,在构造方法中使用了未定义的变量,会自动提升为属性变量。 constructor(name, age, gender) { this.name = name; this.age = age; this.gender = gender; } sayHi(name) { console.log(`${name},你好!!我是${this.name},今年${this.age}岁`); } } let s1 = new Student("张三", 21, '男'); s1.sayHi('老李') let s2 = new Student(); let s3 = new Student("李四", 22, '女');
案例3:
class Human { #other //私有属性 constructor(name, age, other) { this.name = name; this.age = age; this.#other = other; } introduce() { console.log(this.name, this.age, this.#other); } ///使用存取器 getter 获取私有属性 get other() { return this.#other; } //使用存取器 setter 设置私有属性 set other(value) { this.#other = value } } let h1 = new Human('zhangsan', 21, 'yigehaoren') h1.introduce(); h1.other = "一个好人" //默认调用setter存取器 进行赋值 console.log(h1.other); // 默认调用getter存取器,获取值 console.log(h1);
4.4 类的继承
ES6类支持单继承,使用extends关键字,就可以继承class了。
class Human {
constructor(name, age) {
this.name = name;
this.age = age;
}
introduce() {
console.log(this.name, this.age);
}
}
// 使用extends 表示继承
class Employee extends Human {
//子类的构造器中,必须使用super()来调用父类的构造器,来给继承过来的属性赋值
constructor(name, age, gender) {
super(name, age)
this.gender = gender;
}
sayHi() {
console.log(`${this.name},${this.age},${this.gender}`);
}
}
let e1 = new Employee("张三", 21, 'f');
console.log(e1);
console.log(e1 instanceof Employee);
console.log(e1 instanceof Human);
e1.introduce()
e1.sayHi()
4.5 箭头函数
//匿名函数 let getNum1 = function (a, b) { console.log(a + b); } // 箭头函数: 对应的就是java的lambda表达式。 let getNum2 = (a, b) => { console.log(a + b) }; getNum2(10, 20) // 一个形参时,可以省略小括号 let getNum3 = a => { let b = a * 10; let r = b * 10; console.log(r); } getNum3(2) // 函数体只是一个表达式时,可以省略{}, 如果表达式中有return关键字,必须省略 let getNum4 = (a, b) => a + b; let r1 = getNum4(10, 30) console.log(r1); // 箭头函数,可以作为参数进行传递 let nums = [10, 20, 30, 40]; let f1 = (value, index) => console.log(value, index); nums.forEach(f1)
五 异步编程
5.1 回调函数
5.1.1 概念
回调函数(callback function),当一个函数作为参数传入另一个参数中,并且它不会立即执行,只有当满足一定条件后该函数才可以执行,这种函数就称为回调函数。 你可以将其理解为 回头再调用的意思, 其实回调函数就是普通函数,只不过名字起的特殊,根据应用场景而命名的而已。
回调函数通常用于事件处理、异步编程和处理各种操作系统和框架的API。
基本概念:
-
回调:指被传入到另一个函数的函数。
-
异步编程:指在代码执行时不会阻塞程序运行的方式。
-
事件驱动:指程序的执行是由外部事件触发而不是顺序执行的方式。
5.1.2 应用场景
回调函数是一种常见的编程技术,它可以在异步操作完成后调用一个预定义的函数来处理结果。回调函数通常用于处理事件、执行异步操作或响应用户输入等场景。
回调函数的作用是将代码逻辑分离出来,使得代码更加模块化和可维护。使用回调函数可以避免阻塞程序的运行,提高程序的性能和效率。另外,回调函数还可以实现代码的复用,因为它们可以被多个地方调用。
回调函数的使用场景包括:
-
事件处理:回调函数可以用于处理各种事件,例如鼠标点击、键盘输入、网络请求等。
-
异步操作:回调函数可以用于异步操作,例如读取文件、发送邮件、下载文件等。
-
数据处理:回调函数可以用于处理数据,例如对数组进行排序、过滤、映射等。
-
插件开发:回调函数可以用于开发插件,例如 WordPress 插件、jQuery 插件等。
回调函数是一种非常灵活和强大的编程技术,可以让我们更好地处理各种异步操作和事件。
例子1:
let nums = [10, 20, 30, 40];
let f1 = (value, index) => console.log(value, index);
nums.forEach(f1)
例子2:
let f1 = () => { console.log("aaaaaa"); }
document.getElementById("btn").addEventListener("click", f1)
例子3: 定时器里的第一个参数:就是回调函数。 3秒后回头来调用该函数
setTimeout(()=>{
console.log("hello world")
},3000)
---未完待续---
原文地址:https://blog.csdn.net/weixin_64513190/article/details/142336908
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!