H5大前端(Web前端)学习笔记(四)-ES6新特性

ES6新特性

  • letconst 命令
  • 变量的解构赋值
  • 字符串扩展
  • 函数扩展
  • 对象扩展
  • 数组扩展
  • 运算符扩展
  • Promise对象
  • Class
  • Class 继承

命令行工具

常用的命令行工具:

  • CMD命令行工具
  • PowerShell命令行工具

CMD命令行

  • 打开命令行窗口
    • win : 左下角开始,找到运行,点击,输入cmd,回车
    • win : win+r 快速打开命令行窗口
    • mac : command+空格,输入terminal
  • 选择盘符 : 盘符名加冒号 E:
  • 查看盘符及目录下文件与文件夹: wn:dir mac:ls
  • 清空命令行信息: win:cs mac:cleal
  • 进入文件夹或目录 : cd 文件夹名称
  • 返回到上一级目录 : cd../
  • 快速补全目录或文件夹名称: tab
  • 创建文件夹: mkdir 文件夹名称
  • 查看历史输入过的命令:上下按键

PowerShell

  • 打开方式
    • 在开始位置搜索 Powershel 打开
    • 在对应目录按住 shift+右键,打开
  • 其他保持一致

Babel转码器

可以将ES6代码转为ES5代码

  • 安装Babel
npm install --save-dev @babel/core
  • 配置文件.babelrc
{
	"presets":[],
	"plugins":[]
}
  • 转码规则

presets字段设定转码规则,官方提供以下规则集,可以根据需要安装

npm install --save-dev @babel/preset-env
  • 将规则加入.babelrc
{
	"presets":[
		"@babel/env"
	],
	"plugins":[]
}
  • Babel命令行转码
npm install --save-dev @babel/cli

基本用法如下:

#转码结果输出到标准输出
$ npx babel example.js
转码结果写入一个文件
# --out-file或-0 参数指定输出文件
$ npx babel example.js --out-file compiled.js
#或者
$ npx babel example.js -o compiled.js
# 整个目录转码
# --out-dir或-d 参数指定输出目录
$ npx babel src --out-dir lib
# 或者
$ npx babel src -d lib

Let命令

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

  • var关键字:函数级作用域
  • let关键字
    • let是块级作用域(花括号级作用域{}
    • let不存在变量提升
    • let不允许重复声明(在相同作用域内)

Const命令

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

  • 一旦声明,就必须立即初始化
  • 作用域与let相同,块级作用域
  • 不存在变量提升
  • 不可以重复声明

对象的解构赋值(变量的结构赋值)

user = {
	name : 'xxx',
	age : 20
};
let {name, age} = user;

注意
对象的属性没有次序,必须和属性同名,才能取到正确的值

  • 对象的解构赋值可以很方便将现有对象的方法复制到某个变量
let {log} = console;
let {random, floor, ...} = Math;

如果将一个已经声明的变量用于解构赋值,报错。

字符串扩展

字符串Unicode表示法

ES6 加强了对 Unicode 的支持,允许采用 \uxxx 形式表示一个字符,其中 xxx 表示字符的 Unicode 码点。
Unicode
统一码(Unicode),也叫万国码、单一码,是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。

"\u0061"
// "a"

字符串遍历接口

for...of遍历循环

forlet i of "hello"{
	console.log(i); //i是字符串中的每一个字符
}

模板字符串

模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。

// 动态创建一个a标签,a标签的href属性是动态的
let url = 'www.baidu.com';
//当向页面写入动态标签时,标签的数据一般来源于服务器
let h1 = '<a href="' + url +'">百度</a>';
//字符串模板
let h2 =`<a href='${url}'>百度</a>`;

字符串新增方法

includes(), startsWith(), endsWith()

传统上,JavaScript 只有 indexof方法,可以用来确定一个字符串是否包含在另一个字符串中。ES6 又提供了三种新方法。

  • includes() : 返回布尔值,表示是否找到了参数字符串
  • startsWith() : 返回布尔值,表示参数字符串是否在原字符串的头部
  • endswith() : 返回布尔值,表示参数字符串是否在原字符串的尾部

这三个方法都支持第二个参数,表示开始搜索的位置

let s='Hello_world!';
s.startswith('world',6) // true
s.endswith('Hello',5)// true
s.includes('He11o'6)// false

repeat()

repeat() 方法返回一个新字符串,表示将原字符串重复n次。

'x'.repeat(3) //“xxx'
'he1lo'.repeat(2)// "hellohello"
'na'.repeat(0)//""

padstart(),padEnd()

ES2017 引入了字符串补全长度的功能。如果某个字符串不够指定长度,会在头部或尾部补全。 padstart() 用于头部补全, padEnd() 用于尾部补全。

'x'.padstart(5,'ab')//'ababx
'x'.padstart(4,'ab')//'abax'
'x'.padEnd(5,'ab')//'xabab
'x'.padEnd(4'ab')//'xaba

trimStart(), trimEnd()

ES2019对字符串实例新增了 trimstart()trimEnd() 这两个方法。它们的行为与 trim()一致, trimstart() 消除字符串头部的空格, trimEnd() 消除尾部的空格。它们返回的都是新字符串,不会修改原始字符串。

at()

at() 方法接受一个整数作为参数,返回参数指定位置的字符,支持负索引(即倒数的位置)。

const str ='hel1o';
str.at(1)//"e"
str.at(-1)//"o'

注意
如果参数位置超出了字符串范围,at()返回undefined

数组扩展:扩展运算符

扩展运算符(spread)是三个点()。将一个数组转为用逗号分隔的参数序列

  • 替代函数的 apply 方法

由于扩展运算符可以展开数组,所以不再需要 appy 方法,将数组转为函数的参数了

// ES5 的写法
Math.max.apply(nu71, [14, 3, 77])
// ES6 的写法
Math.max(...[14, 3, 77])
// 等同于
Math.max(14, 3, 77);
  • 合并数组
//扩展运算符提供了数组合并的新写法
const arrl = ['a', 'b'];
const arr2 =['c'];
const arr3 =['d','e'];
//ES5 的合并数组
arr1.concat(arr2,arr3); // ['a','b','c','d',r'e']
// ES6 的合并数组
[...arr1,...arr2,...arr3]//['a','b','C','d','e']

数组扩展:新增方法

  • Array.from()

Array.from 方法用于将类数组转为真正的数组

温馨提示
常见的类数组有三类:

  • arguments
  • 元素集合
  • 类似数组的对象

arguments

function add(){
	let collect = Array.from(arguments);
	collect.push(40);
	console.1og(collect);
}
add(10,20,30)

元素集合

let divs = document.queryselectorA1l('div');
console.log(Array.from(divs));

类似数组的对象

let arrayLike = {
	'0' : 'a',
	'1' : 'b',
	'2' : 'c',
	length : 3
};
let arr = Array.from(arrayLike);
console.log(arr);
  • Array.of()

Array.of() 方法用于将一组值,转换为数组

Array.of(3, 11, 8)//[3,11,8]

对象的扩展

属性的简洁表示法

ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。

let name ="hello";
const user = {
	name ,
	age:20
}

除了属性简写,方法也可以简写

const o = {
	method(){
		return "hello";
	}
};
//等同于
const o = {
	method: function(){
		return "hello";
	}
}

这种写法用于函数的返回值,将会非常方便

function getPoint(){
	const x=1;
	const y= 10;
	return {x, y};
}
getPoint() // {x:1,y:10}

属性名表达式

ES6 允许字面量定义对象时,用表达式作为对象的属性名,即把表达式放在方括号内

let propkey = 'hello';
let obj= {
	[propKey]: true,
	['a'+'bc']:123
 };

对象的扩展运算符

ES2018 将这个运算符引入了对象

let z = {a: 3, b: 4};
let n = {...z};
console.log(n);
{...{}, a: 1}
// { a: 1 }

函数的扩展:箭头函数

基本用法

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

var add = (x) => x:
// 等同于
var add =function(x){
	return x;
};

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

var add = (x,y) => x+y;
// 等同于
var add = function(x,y){
	return x+y;
};

var add = () => 100;
// 等同于
var add = function(){
	return 100;
};

如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回

var add = (x,y) => {
	var z= 10;
	return x+y+z;
};
// 等同于
var add= function(x,y){
	var z = 10;
	return x+y+z;
}

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

var add = (x,y) => ({x:10,y:20});

箭头函数的一个用处是简化回调函数(匿名函数)

var arr = [10,20,30];
arr.map(item =>{
	console.log(item);
})

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

var name = "hello";
var user = {
	name:"world",
	getName(){
		setTimeout(() => {
			console.log(this.name); //world
		})
	}
}
user.getName()

温馨提示
箭头函数里面根本没有自己的 this ,而是引用外层的 this

Set数据结构

基本用法

ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值

  • Set本身是一个构造函数,用来生成 Set 数据结构。
const s= new set();
[2, 3, 5, 4, 5, 2, 2].forEach(x=> s.add(x));
for(let i of s){
	console.1og(i);
}
//2 3 5 4

通过 add()方法向 Set 结构加入成员,结果表明 Set 结构不会添加重复的值

  • Set函数可以接受一个数组作为参数
const set=new set([12344]);
[...set]
//[1,2,3,4]
  • 数组去除重复成员的方法
// 去除数组的重复成员
[...new Set(array)]
  • 字符串去除重复字符
[...new Set('ababbc')].join('')
// "abc"
  • 向 Set 加入值的时候,不会发生类型转换,所以5"5"是两个不同的值。
var myset=new Set();
myset.add("5");
myset.add(5);
console.log(myset);
//Set(2){'5',5}

size属性

返回 set 实例的成员总数

const items =new Set([12345555]);
items.size //5

方法

  • add() :添加
  • delete() :删除某个值,返回一个布尔值,表示删除是否
  • has() :返回一个布尔值,表示该值是否为Set成员
  • clear() :清除所有成员,没有返回值

Promise对象

基本概念

Promise 是异步编程的一种解决方案,比传统的解决方案–回调函数和事件-一更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise 对象
所谓Promise ,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理
有了Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外Promise 对象提供统一的接口,使得控制异步操作更加容易

基本用法

ES6规定,Promise 对象是一个构造函数,用来生成Promise 实例

const promise = new Promise(function(resolve, reject){
    // ... some code
    if(/*异步操作成功*/){
        resolve(value);
    }else{
        reject(error);
    }
});

Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是resovereject 。它们是两个函数,由JavaScript 引擎提供,不用自己部署
Promise 实例生成以后,可以用 then 方法分别指定 resolved 状态和 rejected 状态的回调函数。

promise.then(function(value){
    //success
}, function(error){
    //failure
})

Promise_Ajax实操

<body>
    <script>
        //XHR对象
        const getJSON = function(url){
            const promise = new Promise(function(resolve,reject){
                //异步请求:网络请求代码
                const handler = function(){
                    if(this.readyState !== 4){
                        // 0 1 2 3 4
                        return;
                    }
                    if(this.readyState === 200){
                        resolve(this.response)
                    }else{
                        reject(new Error(this.statusText))
                    }
                }
                const client = new XMLHttpRequest();
                client.open("GET",url);
                client.onreadystatechange = handler;
                client.responseType = "json";
                client.setRequestHeader("Accept", "application/json");
                client.send();
            })
            return promise;
        }

        getJSON("http://...").then(function(data){
            console.log(data);
        }, function(error){
            console.log(error);
        })
    </script>

</body>

Async函数

ES2017 标准引入了 async 函数,使得异步操作变得更加方便
async函数可以将异步操作变为同步操作

function print(){
    //定时器是异步的
    setTimeout(()=>{
        console.log("定时器");
    }, 10);
    console.log("Hello");
}
print(); // Hello 定时器

基本语法

function timeout(ms){
    //resolve:是一个函数
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            console.log("定时器");
            resolve();
        },ms);
    })
}
async function asyncPrint(ms, value){
    // 把具有异步操作的代码前面放入:await
    await timeout(ms);
    console.log(value);
}
asyncPrint(10, "Hello");

使用场景:网络请求之间的依赖关系,很多接口可能要以来于上一个接口的数据才能执行

Class类

Class的基本语法

//ES5类的表现形式
function Person(name, age){
    this.name = name;
    this.age = age;
}
Person.prototype.getName = function(){
    console.log(this.name);
}
var p = new Person("zhangsan",20);
p.getName();

ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class关键字,可以定义类
基本上,ES6 的 class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已

class Person{
    constructor(name, age){
        this.name = name;
        this.age = age;
    }

    getName(){
        console.log(this.name);
    }
}
var p = new Person("zhangsan",20);
p.getName();

constructor 方法

constructor() 方法是类的默认方法,通过 new 命令生成对象实例时自动调用该方法。一个类必须有 constructor()方法,如果没有显式定义,一个空的 constructor()方法会被默认添加

class Point {
}
// 等同于
class Point {
	constructor(){}
}

类的实例

生成类的实例的写法,与 ES5 完全一样,也是使用 new 命令

class Point {
	//...
}
// 报错
var point = Point(23);

//正确
var point = new Point(23);

注意
类不存在变量提升(hoist),这一点与 ES5 完全不同

Class属性与方法

  • 实例方法

通过类的实例对象调用方法

class People{
	say(){
		console.1og("He11o");
	}
}
var p=new People();
p.say()
  • 实例属性

实例属性指的是类的实例对象可调用的属性

class People{
	constructor(name,age){
		this.name = name;
		this.age = age;
	}
	say(){
		console.log(this.name,this.age);
	}
}
//p:实例对象
var p= new People("iwen",20);
p.say()
console.log(p.name,p.age);
  • 静态方法

类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法“

class Person{
	static classMethod(){
		console.1og(“He11o");
	}
}
Person.classMethod()//Hello
var p=new Person();
p.classMethod()//p.classMethod is not a function

温馨提示
注意,如果静态方法包含this关键字,这个 this指的是类,而不是实例。

  • 静态属性

静态属性指的是 Class 本身的属性,即 Class.propName

class People{}
People.status ="等待";
console.log(People.status);

Class的继承

Class 可以通过 extends 关键字实现继承,让子类继承父类的属性和方法。extends 的写法比 ES5 的原型链继承,要清晰和方便很多

class Point {
}
class colorPoint extends Point {
}

ES6 规定,子类必须在 constructor()方法中调用 super() ,否则就会报错,这是因为子类自己的 this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,添加子类自己的实例属性和方法。如果不调用super() 方法,子类就得不到自己的 this 对象

class Person{
    constructor(name, age){
        this.name = name;
        this.age = age;
    }
    getName(){
        console.log(this.name);
    }
    static getInfo(){
        console.log("people");
    }
}
class Student extends Person{
    constructor(name, age, schoolName){
        super(name, age);
        this.schoolName = schoolName;
    }
    getSchool(){
        console.log(this.schoolName);
    }
}
var stu = new Student("zhangsan", 20, "xx大学");
stu.getName();
Student.getInfo();
stu.getSchool();

Module语法

历史上,JavaS一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。其他语言都有这项功能,比如 Ruby 的require、Python 的 import ,甚至就连 CSS 都有@import ,但是JavaScript 任何这方面的支持都没有,这对开发大型的、复杂的项目形成了巨大障碍

ES6 模块是通过 export 命令显式指定输出的代码,再通过 import 命令输入。

export var Hello = "hello"// hello.js文件
import { Hello } from"./hello.js" // index.js文件

测试方式

我们采用NodeJS方式进行测试Module语法。
但是NodeJS采用的是CommonJS的模块化规范,使用require引入模块;而import是ES6的模块化规范关键字。想要使用import,必须引入babel转义支持,通过babel进行编译,使其变成node的模块化代码。

  • 第一步:全局安装babel-cli npm install -g babel-cli
  • 第二步:安装babel-preset-env npm install -D babel-preset-env
  • 第三步:运行代码 babel-node --presets env index.js

export命令

  • export命令导出变量
export var firstName ='zhang';
export var lastName ='san';
export var year = 2000;
  • export命令导出函数
export function add(x,y){
	return x+y;
};

import命令

  • 使用 export 命令定义了模块的对外接口以后,其他JS文件就可以通过 import 命令加载这个模块
// profile.js
export var firstName ='sxt'
export var lastName =itbaizhan';
export var year =2000;
// main.js
import { firstName,lastName,year }from'./profile.js';
  • 如果想为输入的变量重新取一个名字,import 命令要使用 as关键字,将输入的变量重命名
// value.js
export var value =1;
// main.js
import { value as val }from'./value.js';
  • 除了指定加载某个输出值,还可以使用整体加载,即用星号(*)指定一个对象,所有输出值都加载在这个对象上面
// circle.js
export function area(radius){
	return Math.PI * radius * radius;
}
export function circumference(radius){
	return 2*Math.PI * radius;
}
// main.js
import { area, circumference } from './circle';
// 可以修改如下
import * as circle from'./circle';

export default命令

从前面的例子可以看出,使用 import 命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。但是,用户肯定希望快速上手,未必愿意阅读文档,去了解模块有哪些属性和方法
为了给用户提供方便,让他们不用阅读文档就可以加载模块,就要用到export default命令,为模块指定默认输出。

//export-default.js
export default function{
	console.log('foo');
}

其他模块加载该模块时, import 命令可以为该匿名函数指定任意名字

// import-default.js
import customName from './export-default':
customName();//'foo'

一个文件中,默认只能存在一个export default命令

  • 24
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

30ring

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值