JavaScript--ES6(2)

class类

在ES6中,class (类)作为对象的模板被引入,可以通过 class 关键字定义类,但是其本质是 function ,可以看作一个语法糖,让对象原型的写法更加清晰、更像面向对象编程的语法,类的声明不可以重复,与let等一样,类定义不会被提升,这意味着必须在访问前对类进行定义,否则就会报错

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

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

需要注意, ES6的类中不能直接定义变量,变量被定义在constructor中 ,constructor 方法是类的默认方法,创建类的对象时被调用。也被称为类的构造方法(构造函数、构造器)。一个类中有且仅有一个构造方法

class People {
	constructor() {
		console.log("你好");
	}
} 
new People(); //将执行constructor方法

类存在方法,一是原型方法,二是静态方法

原型方法不需要使用function关键字,通过“对象.原型方法”调用

静态方法使用static修饰,调用时不需要创建对象,直接通过“类名.静态方法”调用

//原型
class People {
	say(world) {
		console.log(`say ${world}`);
	}
}
let p = new People();
p.say("hello"); //say hello

//静态
class People {
	static sum(a, b) {
		console.log(a + b);
	}
}
People.sum(1, 2);

 与Java中的类一样,js中的类也可以继承,使用extends关键字实现继承 ,子类可以继承父类中所有的方法和属性 ,但子类只能继承一个父类(单继承),一个父类可以有多个子类 ;子类的构造方法中必须有super()来指定调用父类的构造方法,并且位于子类构造方法中的第一行 ;子类中如果有与父类相同的方法和属性,将会优先使用子类的(覆盖)。通过继承,解决了代码的复用

class People {
    //父类构造方法
	constructor() {
        this.a = 100; //父类中定义的变量
		console.log("People constructor");
	}
    //原型方法
	eat() {
		console.log("eat...")
	}
    //静态方法
    static play() {
		console.log("play...")
	}
}
			
class Student extends People {
    //子类构造方法
	constructor() {
		super(); //调用父类构造器,必须存在,且位于子类构造器第一行的位置
        this.b = 200; //子类定义的变量
		console.log("Student constructor");
	}
	study() {
		console.log("study...");
	}
}
			
let stu = new Student();
console.log(stu.a, stu.b);
stu.eat();
stu.study();
Student.play();

内部类:属于外部类的成员,必须通过“外部类.内部类”访问

// 外部类
class Outer {
	constructor() {
         console.log("outer");
    }
}
// 内部类
Outer.Inner = class {
    constructor() {
         console.log("Inner");
    }
}     
new Outer.Inner();

箭头函数

箭头函数定义

箭头函数提供了一种更加简洁的函数书写方式。基本语法是:

参数 => 函数体
(参数) => {函数体}

 基本语法:

//普通函数
var f = function(a){
 return a;
}
f(1);  //1

//箭头函数
var f = a => a
f(10); //10

 当箭头函数没有参数或者有多个参数,要用 () 括起来

var f = (a,b) => a+b;
f(6,2);  //8

 当箭头函数函数体有多行语句,用 {} 包裹起来,表示代码块,当只有一行语句,并且需要返回结果时,可以省略 {} , 结果会自动返回

var f = (a,b) => {
 let result = a+b;
 return result;
}
f(6,2);  // 8

当箭头函数要返回对象的时候,为了区分于代码块,要用 () 将对象包裹起来

var f = (id,name) => ({id: id, name: name});
f(6,2);  // {id: 6, name: 2}

 使用箭头函数时,要注意this等关键字的指向,因为箭头函数没有 this、super、arguments 和 new.target 绑定

箭头函数体中的 this 对象,是定义函数时的对象,而不是使用函数时的对象

function a() {
	setTimeout(function() {
		console.log(this); //this始终指向全局Window对象
	}, 100)
}
a.call({num: 200});
					
function b() {
	setTimeout(() => {
		console.log(this); //this绑定的是b函数中的this对象
	}, 100);
}
b.call({num: 300});

 箭头函数不可以作为构造函数,也就是不能使用 new 命令,否则会报错 ,且箭头函数只能定义式(没有名字)

function Person() {
	console.log(this);
}
new Person(); //Person {}
			
var People = ()=>{
	console.log(this);
}
new People(); //TypeError: People is not a constructor

箭头函数可以与解构一起使用

//变量为目标,返回值为源
let cal = (a, b) => {
    return {
        add: a+b,
        sub: a-b,
        mul: a*b,
        div: a/b
    };
}
let {add, sub, mul, div} = cal(10, 5);

//形参为目标,实参为源
var show = ({one, two}) => {
	console.log(one + "---" + two);
}
show({one: "hello", two: "你好"});

适合使用的场景

ES6 之前,JavaScript 的 this 对象一直很令人头大,回调函数,经常看到 var self = this 这样的代码,为了将外部 this 传递到回调函数中,那么有了箭头函数,就不需要这样做了,直接使用 this 就行。

所以,当我们需要维护一个 this 上下文的时候,就可以使用箭头函数。

总结

  • 要有个箭头

  • 箭头的前面是小括号,放形参,只有一个形参的时候可以省略小括号;

  • 箭头的后面是函数体;

  • 如果函数体只有一个语句,没有{},此时的返回值不需要return;

  • 箭头函数里面的this总是指向最靠近的function 内部的this;

  • 对象里面的方法,尽可能不要使用箭头函数;

  • 箭头函数里面没有arguments,可以使用…reset,接收过来就是数组类型,接收的是形参之外的所有的实参;

var show = (a, b, ...reset) => {
	console.log(a + b);
	console.log(reset);
}
show(1, 2, 3, 4, 5);

模块

概述
  • ES6 引入了模块化,其设计思想是在编译时就能确定模块的依赖关系,以及输入和输出的变量。

  • ES6 的模块化分为导出(export)导入(import)两个模块。

特点

  • ES6 的模块自动开启严格模式,不管你有没有在模块头部加上 use strict;

  • 模块中可以导入和导出各种类型的变量,如函数,对象,字符串,数字,布尔值,类等。

  • 每个模块都有自己的上下文,每一个模块内声明的变量都是局部变量,不会污染全局作用域。

  • 每一个模块只加载一次(是单例的), 若再去加载同目录下同文件,直接从内存中读取

export导出

default关联使用,并且一个js模块中只能有一个export default语句 (即默认导出,一般包含了导出文件的大部分内容),其余的使用export 语句(单个导出)

//导出字符串
export default "abc";

//导出数字
export default 123;

//导出布尔值
export default true;

//导出数组
export default [1,2,3];

//导出对象
var obj = {
	name: '张三',
	age: 20
}
export default obj;

//导出函数
var func = function() {
	console.log("func函数");
	return 100;
}
export default func;


//导出类
class People {
	constructor() {
		this.a = 100;
	}
	say() {
		console.log("say...");
	}
}
export default People;

import导入

from关联使用,此时script标签的type必须设置为module

单例模式:多次重复执行同一句 import 语句,那么只会执行一次,而不会执行多次。import 同一模块,声明不同接口引用,会声明对应变量,但只执行一次 import

<script type="module">
	import People from './js/myModule.js';
	let p = new People();
	p.say();
</script>

 导出 export default 修饰的内容时可以自定义变量名,但导入export修饰的内容时,需要使用{},且变量名需要与导出文件中的变量名相同

import obj, { fn, fm3, fm4 } from "./a.js"

异步编程

promise对象

Promise对象是一种数据容器,Map、Set等也是,在函数中不区分大小写

概述

promise是异步编程的一种解决方案。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息

Promise 异步操作有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。除了异步操作的结果,任何其他操作都无法改变这个状态

Promise 对象只有:从 pending 变为 fulfilled 和从 pending 变为 rejected 的状态改变。只要处于 fulfilled 和 rejected ,状态就不会再变了即 resolved(已定型)

Promise是一个构造函数,其原型上有then、catch方法,对象上有reject、resolve方法

promise使用
var p = new Promise(function(resolve, reject){
    //做一些异步操作
    setTimeout(function(){
        console.log('完成');
        resolve('数据');
    }, 1000);
});

 参数说明:

  • resolve:异步操作执行成功后的回调函数

  • reject:异步操作执行失败后的回调函数

上面的代码中,直接通过new创建了Promise对象,并没有调用它,但是传进去的函数已经执行了。因此我们用Promise的时候一般是包含在一个函数中,在需要的时候去运行这个函数

function runAsync(){
    var p = new Promise(function(resolve, reject){
        //做一些异步操作
        setTimeout(function(){
            console.log('执行完成');
            resolve('随便什么数据');
        }, 2000);
    });
    return p;            
}
runAsync()

 通过return返回了一个Promise对象。也就是说调用这个包装函数可以得到Promise的对象,接下来就可以使用Promise对象上的thencatch方法了

runAsync().then(function(data){
    console.log(data);
    //后面可以用传过来的数据做些其他操作
    //......
});

 在runAsync()的返回上直接调用then方法,then接收一个参数,是函数,函数的参数data将会拿到我们在runAsync中调用resolve时传的的参数

此时then里面的函数就是回调函数,能够在runAsync这个异步任务执行完成之后被执行

链式操作用法

因为Promise 中的return返回的是一个Promise对象,所有可以继续所有then方法

runAsync1()
.then(function(data){
    console.log(data);
    return runAsync2();
})
.then(function(data){
    console.log(data);
    return runAsync3();
})
.then(function(data){
    console.log(data);
});

 这就是链式操作用法,通过这种操作,可以处理地域回调的问题

catch的用法

Promise对象除了then方法,还有一个catch方法 ,它和then的第二个参数一样,用来指定reject的回调 ,效果和写在then的第二个参数里面一样。不过它还有另外一个作用:在执行resolve的回调(也就是上面then中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死js,而是会进到这个catch方法中

getNumber()
.then(function(data){
    console.log('resolved');
    console.log(data);
    console.log(somedata); //此处的somedata未定义
})
.catch(function(reason){
    console.log('rejected');
    console.log(reason);
});

在链式操作方法中,可以只写一个catch

async函数

async

async 是 ES7 才有的与异步操作有关的关键字,和Promise有很大的关联

async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数

async function helloAsync(){
    return "helloAsync";
  }
await

async 函数中可能会有 await 表达式,async 函数执行时,如果遇到 await 就会先暂停执行 ,等到触发的异步操作完成后,恢复 async 函数的执行并返回解析值

await 操作符用于等待一个 Promise 对象, 它只能在异步函数 async function 内部使用。如果在 async function 函数体外使用 await ,你只会得到一个语法错误

返回值返回 Promise 对象的处理结果。如果等待的不是 Promise 对象,则返回该值本身 ;如果一个 Promise 被传递给一个 await 操作符,await 将等待 Promise 正常处理完成并返回其处理结果

await针对所跟不同表达式的处理方式:

  • Promise 对象:await 会暂停执行,等待 Promise 对象 resolve,然后恢复 async 函数的执行并返回解析值。

  • 非 Promise 对象:直接返回对应的值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值