自学内容网 自学内容网

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 = 20var 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。

基本概念:

  1. 回调:指被传入到另一个函数的函数。

  2. 异步编程:指在代码执行时不会阻塞程序运行的方式。

  3. 事件驱动:指程序的执行是由外部事件触发而不是顺序执行的方式。

5.1.2 应用场景

回调函数是一种常见的编程技术,它可以在异步操作完成后调用一个预定义的函数来处理结果。回调函数通常用于处理事件、执行异步操作或响应用户输入等场景。

回调函数的作用是将代码逻辑分离出来,使得代码更加模块化和可维护。使用回调函数可以避免阻塞程序的运行,提高程序的性能和效率。另外,回调函数还可以实现代码的复用,因为它们可以被多个地方调用。

回调函数的使用场景包括:

  1. 事件处理:回调函数可以用于处理各种事件,例如鼠标点击、键盘输入、网络请求等。

  2. 异步操作:回调函数可以用于异步操作,例如读取文件、发送邮件、下载文件等。

  3. 数据处理:回调函数可以用于处理数据,例如对数组进行排序、过滤、映射等。

  4. 插件开发:回调函数可以用于开发插件,例如 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)!