IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> ES6基础 -> 正文阅读

[JavaScript知识库]ES6基础

一、ES6简介

ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现

ES6简介与历史

二、变量声明let、const

2.1、let命令

块级作用域:

ES6 新增了let命令,用来声明变量。其的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效

if (true) {
    var a = 10;
    let b = 20;
}
console.log(a); //10
console.log(b); //Uncaught ReferenceError: b is not defined

分别用let和var声明了两个变量。在代码块之外调用这两个变量,结果let声明的变量报错,var声明的变量返回了正确的值。这表明,let声明的变量只在它所在的代码块有效。

不存在变量提升:

var命令会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined。这种现象多多少少是有些奇怪的,按照一般的逻辑,变量应该在声明语句之后才可以使用。

为了纠正这种现象,let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。

// var 的情况
console.log(foo); // 输出undefined
var foo = 2;

// let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2;

上面代码中,变量foovar命令声明,会发生变量提升,即脚本开始运行时,变量foo已经存在了,但是没有值,所以会输出undefined。 变量barlet命令声明,不会发生变量提升。这表示在声明它之前,变量bar是不存在的,这时如果用到它,就会抛出一个错误。 因此,使用let声明变量,极大的消除了代码的潜在bug的隐患。

2.2、const命令

const声明一个只读的常量。一旦声明,常量的值就不能改变。

const PI = 3.1415926;
PI = 3;  //TypeError: Assignment to constant variable.

上面代码表明改变常量的值会报错

  • const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。

  • 且如果只声明不赋值,就会报错

const foo;
// SyntaxError: Missing initializer in const declaration
  • const的作用域与let命令相同:只在声明所在的块级作用域内有效。
if (true) {
  const MAX = 5;
}

MAX // Uncaught ReferenceError: MAX is not defined

三、扩展运算符

3.1、指数运算符

新增了一个指数运算符`**

2 ** 2 // 4
2 ** 3 // 8

运算符的一个特点是右结合。多个指数运算符连用时,是从最右边开始计算的。

// 相当于 2 ** (3 ** 2)
2 ** 3 ** 2// 512

指数运算符可以与等号结合,形成一个新的赋值运算符**=

let a = 1.5;
a **= 2;
// 等同于 a = a * a;

let b = 4;
b **= 3;
// 等同于 b = b * b * b;

3.2、 数组(扩展运算符)

解构赋值:
扩展运算符(spread)就是我们知道的三个点(...),它就好像rest参数的逆运算,将一个数组转为用逗号分隔的参数序列

console.log(...[1,2,3]);
//1 2 3
console.log(1,...[2,3,4],5)
//1 2 3 4 5
console.log([1,...[2,3,4],5])
//[1, 2, 3, 4, 5]
[...document.querySelectorAll('div')]
// [<div>, <div>, <div>]

复制数组:

let arr = [1, 2],
    arr1 = [...arr];
console.log(arr1); // [1, 2]

如果数组含有空位复制过来会有如下的结果

let arr2 = [1, , 3],
    arr3 = [...arr2];
console.log(arr3); [1, undefined, 3]

合并数组:

console.log([...[1, 2],...[3, 4]]); // [1, 2, 3, 4]
// 本质也是:**将一个数组转为用逗号分隔的参数序列,然后置于数组中**

3.3、对象

拓展运算符(...)用于取出 参数对象 所有 可遍历属性 然后拷贝到当前对象。

基本用法:
可复制其7他对象里面的内容

let person = {name: "Amy", age: 15};
let someone = { ...person };
console.log(someone);  //{name: "Amy", age: 15}

合并对象

let age = {age: 15};
let name = {name: "Amy"};
let person = {...age, ...name};
person;  //{age: 15, name: "Amy"}

注意:自定义的属性在拓展运算符后面,则拓展运算符对象内部同名的属性将**被覆盖掉。**同理,自定义的属性在拓展运算度前面,则变成设置新对象默认属性值。

let person = {name: "Amy", age: 15};
let someone = { ...person, name: "Mike", age: 17};
let someone1 = {  name: "Mike", age: 17,...person};
console.log(someone);  //{name: "Mike", age: 17}
console.log(someone1);  //{name: "Amy", age: 15}

拓展运算符后面是空对象、null、undefined,没有任何效果也不会报错。

//空对象
let a = {...{}, a: 1, b: 2};
console.log(a);  //{a: 1, b: 2}

// null 、 undefined
let b = {...null, ...undefined, a: 1, b: 2};
console.log(b);  //{a: 1, b: 2}

3.4、函数

...加上一个具名参数标识符组成用来表示不确定参数个数。具名参数只能放在参数组的最后,并且有且只有一个不定参数

function addNumbers(x,y,z){
    return x+y+z;
}

var numbers = [1,2,3,4];
addNumbers(...numbers); //6
//函数调用中,扩展运算符(...)将一个数组,变为参数序列

四、箭头函数、解构赋值、数组新特性、字符串新特性、es6模块化、es6面向对象

4.1、箭头函数

ES6 允许使用“箭头”(=>)定义函数

var f = v => v;

// 等同于
var f = function (v) {
  return v;
};

如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。

var f = () => 5;
// 等同于
var f = function () { return 5 };

var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
  return num1 + num2;
};

由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。

// 报错
let getTempItem = id => { id: id, name: "Temp" };

// 不报错
let getTempItem = id => ({ id: id, name: "Temp" });

注意:

  • 箭头函数没有自己的this对象

对于普通函数来说,内部的this指向函数运行时所在的对象,但是这一点对箭头函数不成立。它没有自己的this对象,内部的this就是定义时上层作用域中的this。也就是说,箭头函数内部的this指向是固定的,相比之下,普通函数的this指向是可变的。

function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

var id = 21;

foo.call({ id: 42 });
// id: 42

上面代码中,setTimeout()的参数是一个箭头函数,这个箭头函数的定义生效是在foo函数生成时,而它的真正执行要等到 100 毫秒后。如果是普通函数,执行时this应该指向全局对象window,这时应该输出21。但是,箭头函数导致this总是指向函数定义生效时所在的对象(本例是{id: 42}),所以打印出来的是42。

例子:回调函数分别为箭头函数和普通函数,对比它们内部的this指向。

function Timer() {
  this.s1 = 0;
  this.s2 = 0;
  // 箭头函数
  setInterval(() => this.s1++, 1000);
  // 普通函数
  setInterval(function () {
    this.s2++;
  }, 1000);
}

var timer = new Timer();

setTimeout(() => console.log('s1: ', timer.s1), 3100);
setTimeout(() => console.log('s2: ', timer.s2), 3100);
// s1: 3
// s2: 0

上面代码中,Timer函数内部设置了两个定时器,分别使用了箭头函数和普通函数。前者的this绑定定义时所在的作用域(即Timer函数),后者的this指向运行时所在的作用域(即全局对象)。所以,3100 毫秒之后,timer.s1被更新了 3 次,而timer.s2一次都没更新

4.2、解构赋值

解构赋值是对赋值运算符的扩展。是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。在代码书写上简洁且易读,语义更加清晰明了;也方便了复杂对象中数据字段获取。

  1. 解构的源:解构赋值表达式的右边部分
  2. 解构的目标:解构赋值表达式的左边部分。

数组模型的解构(Array):

  1. 基本:
let [a, b, c] = [1, 2, 3];
// a = 1
// b = 2
// c = 3
  1. 可嵌套
 let [a, [[b], c]] = [1, [[2], 3]];
// a = 1
// b = 2
// c = 3
  1. 可忽略
let [a, , b] = [1, 2, 3];
// a = 1
// b = 3
  1. 剩余运算符
let [a, ...b] = [1, 2, 3];
//a = 1
//b = [2, 3]

对象模型的解构(Object):

  1. 基本
let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
// foo = 'aaa'
// bar = 'bbb'
 
let { baz : foo } = { baz : 'ddd' };
// foo = 'ddd'
  1. 可嵌套可忽略
let obj = {p: ['hello', {y: 'world'}] };
let {p: [x, { y }] } = obj;
// x = 'hello'
// y = 'world'
let obj = {p: ['hello', {y: 'world'}] };
let {p: [x, {  }] } = obj;
// x = 'hello'
  1. 剩余运算符
let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40};
// a = 10
// b = 20
// rest = {c: 30, d: 40}

4.3、数组的新特性

4.4、字符串新特性

模板字符串:

  • 反引号标记字符串(``)(英文字符) 字符串模板
  • 反引号里可以写多行文本
  • 在字符串模板中可以使用插值
  • 插值的形式:${表达式}

五、class、extends、constructor、super

5.1、class

在ES6中, class(类)作为对象的模板被引入,可以通class 关键字定义类。class 的本质是函数。
它可以看作一个语法糖,让对象原型的写法更加清晰、更像面向对象编程的语法。

类表达式可以为匿名或命名。

// 匿名类
let Example = class {
    constructor(a) {
        this.a = a;
    }
}
// 命名类
let Example = class Example {
    constructor(a) {
        this.a = a;
    }
}

5.2、constructor

ES6引入了class类的概念,创建的每一个class类,都会有一个constructor()方法,该方法是一种用于创建和初始化class创建的对象的特殊方法–构造函数方法。

class Animal {
    constructor() {
        this.name = "animal";
    }
}
 
let animal = new Animal();
console.log(animal.name);
 
//输出:animal,所以 Animal类里的constructor()方法里的 this 指向的是被创建的实例对象

如果一个类没有指定constructor()方法,则会添加默认的constructor()方法;在这里插入代码片

class Animal(){}
等同于
class Animal(){
    constructor(){}  //默认的constructor方法
}

一个类只允许有一个constructor()方法,如果出现多个,则会报:Uncaught SyntaxError: A class may only have one constructor

5.3、extends

通过 extends实现类的继承。

class Child extends Father { ... }
class B{
   constructor(name){
     this.name = name;
   }
};
class A extends B{
    constructor(name,age){
     super(name)
     this.age = age;
   }
};
let a = new A('wxp',18);
console.log(a)//{name:'wxp',age:18}

5.4、super

ES6重新实现了类的继承,而在继承的过程中,super关键字实现了至关重要的作用

. super作为函数时,代表父类的构造函数

class A {}

class B extends A {
  constructor() {
    super();//子类的构造函数,必须执行一次super函数,代表父类的构造函数
  }
}

super作为函数使用时,必须出现在子类的构造函数constructor中,否则会报错

参考博客:ES6基础入门
参考教程:
ES6教程
ES6菜鸟教程

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-30 11:50:23  更:2021-09-30 11:52:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 20:35:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码