es6
es6
为什么学习ES6¶
-
es5语言的先天性不足。比如变量提升、内置对象的方法不灵活、模块化实现不完善等等
-
为了后面的vue、尤其是react框架做好了准备
-
目前大部分公司的项目都在使用es6
ECMAScript6.0(简称ES6)是 javascript 语言的下一代标准,已经在2015年6月正式发布了, 它的目标 是使得javascript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言
ES6即是一个历史名词,也是一个泛指,含义是5.1以后的jabascript的下一代标准,涵盖了ES2016 、ES2016、ES2017 等等,而是ES2015则是正式名称,特指该年发布的正式版本的语言标准
ES6新特性 - let 和 const命令 - es6的模板字符串 - 增强的函数 - 扩展的字符串、对象、数组功能 - 解构赋值 - Symbol - Map和Set - 迭代器和生成器 - Promise对象 - async 的用法 - 类 class - 模块化实现
浏览器支持 查看 http://kangax.github.io/compat-table/es6/
强大的babel - 被称为下一代的javascript编译器。可以将es6的代码转换成es5的代码,从而让浏览器获得支持
参考文献 ES6阮一峰教程: http://es6.ruanyifeng.com mdn教程: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript
let和const¶
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>let和const</title>
</head>
<body>
<script>
// var a;
// // var
// console.log(a);
// a = 2;
// 1.let声明变量,没有变量提升
// console.log(a);
// let a = 10;
// console.log(b);
// 2.是一个块作用域
// if(1===1){
// let b = 10;
// }
// console.log(b);
// var a = 2;
// var a = 4;
// 3.不能重复声明
// let a = 1;
// let a = 3;
// console.log(a);
// const 声明常量 一旦被声明 无法修改
// console.log(max);
// if(1===1){
// const max = 30;
// }
// const max = 30;
// const max = 40;
// max = 40;
// console.log(max);
/*
const person = {
name:'小马哥'
}
// person.name = 'alex';
person = {
age:20
}
console.log(person);
*/
//作用1: for循环是个经典例子
const arr = [];
for (let i = 0; i < 10; i++) {
arr[i] = function() {
return i;
}
}
console.log(arr[5]());
// 作用2:不会污染全局变量
let RegExp = 10;
console.log(RegExp);
console.log(window.RegExp);
// 建议:在默认情况下用const,而只有在你知道变量值需要被修改的情况使用let
</script>
</body>
</html>
模版字符串¶
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>模板字符串</title>
</head>
<body>
<div class="box">
</div>
<script>
// 模板字符串:使用tab键上面的反引号``,插入变量时使用${变量名}
const oBox = document.querySelector('.box');
let id = 1,
name = '小马哥';
let htmlStr = `<ul>
<li>
<p id=${id}>${name}</p>
</li>
</ul>`;
// oBox.innerHTML = "<ul><li><p id=" + id + ">" + name + "</p></li></ul>";
oBox.innerHTML = htmlStr;
</script>
</body>
</html>
强大的函数¶
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
// 1.带参数默认值的函数
// es5的写法
/* function add(a, b) {
a = a || 10;
b = b || 20;
return a + b;
}
console.log(add()); */
// function add(a, b = 20) {
// return a + b;
// }
// console.log(add(30));
// 2.默认的表达式也可以是一个函数
// function add(a, b = getVal(5)) {
// return a + b;
// }
// function getVal(val) {
// return val + 5;
// }
// console.log(add(10));
// es5写法 //vs code 多行注释快捷键 alt + shift + a
/* function pick(obj) {
let result = Object.create(null);
console.log(arguments.length) //4
for(let i = 1;i < arguments.length;i++){
result[arguments[i]] = obj[arguments[i]]
}
return result;
}
let book = {
title:'es6的教程',
author:'小马哥',
year:2019
}
let bookData = pick(book,'title','year','author');
console.log(bookData); */ //{title: 'es6的教程', year: 2019, author: '小马哥'}
// 3.剩余参数:由三个点...和一个紧跟着的具名参数指定 ...keys
/* function pick(obj, ...keys) {
// ...keys 解决了arguments 的问题
let result = Object.create(null);
for (let i = 0; i < keys.length; i++) {
result[keys[i]] = obj[keys[i]];
}
return result;
}
let book = {
title: 'es6的教程',
author: '小马哥',
year: 2019
}
let bookData = pick(book, 'year', 'author');
console.log(bookData); //{year: 2019, author: '小马哥'}
function checkArgs(...args) {
console.log(args); //(3) ['a', 'b', 'c']
console.log(arguments); //Arguments(3) ['a', 'b', 'c', callee: (...), Symbol(Symbol.iterator): ƒ]
}
checkArgs('a', 'b', 'c'); */
// 4.扩展运算符...
// 剩余运算符:把多个独立的合并到一个数组中
// 扩展运算法:将一个数组分割,并将各个项作为分离的参数传给函数
/* const maxNum = Math.max(20,30);
console.log(maxNum); //30
// 处理数组中的最大值,使用apply
const arr = [10, 20, 50, 30, 90, 100, 40];
console.log(Math.max.apply(null,arr)); //100
// es6 扩展运算法更方便
console.log(Math.max(...arr));//100 */
//******** es6的箭头函数 ********
// 使用=>来定义 function(){}等于与 ()=>{}
// let add = function (a, b) {
// return a + b;
// }
// let add = (a, b) => {
// return a + b;
// }
// let add = (val1, val2) => val1 + val2;
// console.log(add(10, 20));
// let fn = ()=> 'hello world' + 123;
// console.log(fn());
/* let getObj = id => {
return {
id: id,
name:'小马哥'
}
} */
// let getObj = id => ({id:id,name:"小马哥"});
// let obj = getObj(1);
// console.log(obj); //{id: 1, name: '小马哥'}
// let fn = (function() {
// return function() {
// console.log('hello es6');
// }
// })(); // 返回了内部函数
// fn()
// let fn = (() => {
// return () => {
// console.log('hello es6 2');
// }
// })();
// fn();
// 没有this绑定
// es5中this指向:取决于调用该函数的上下文对象
// let PageHandle = {
// id: 123,
// init: function () {
// //文档添加点击事件
// document.addEventListener('click',function(event) {
// // this.doSomeThings is not a function //点击文档触发
// // console.log(this);
// this.doSomeThings(event.type);
// })
// },
// doSomeThings:function(type){
// console.log(`事件类型:${type},当前id:${this.id}`);
// }
// }
// PageHandle.init();
let PageHandle = {
id: 123,
init: function () {
// 箭头函数没有this指向,箭头函数内部this值只能通过查找作用域链来确定,一旦使用箭头函数,当前就不存在作用域链
// 作用域链在init函数 向上找属于PageHandle对象,所以this指向了PageHandle对象
document.addEventListener('click', (event) => {
// this.doSomeThings is not a function
console.log('::'+this); //::[object Object]
this.doSomeThings(event.type);
}, false)
},
doSomeThings: function (type) {
console.log(`事件类型:${type},当前id:${this.id}`); //事件类型:click,当前id:123
}
}
PageHandle.init();
// 使用箭头函数的注意事项1:使用箭头函数 函数内部没有arguments
// let getVal = (a, b) => {
// console.log(arguments); // ReferenceError: arguments is not defined
// return a + b;
// }
// console.log(getVal(1, 3)); //4
// 2.箭头函数不能使用new关键字来实例化对象
// let Person = ()=>{
// };
// // function函数 也是一个对象,但是箭头函数不是一个对象,它其实就是一个语法糖
// console.log(Person); //()=>{ }
// let p = new Person(); //TypeError: Person is not a constructor
</script>
</body>
</html>
解构赋值¶
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>解构赋值</title>
</head>
<body>
<script>
// 解构赋值是对赋值运算符的一种扩展
// 它针对数组和对象来进行操作
// 优点:代码书写上简洁易读
let node = {
type:'iden',
name:'foo'
}
// let type = node.type;
// let name = node.name;
// 完全解构
let {type,name} = node;
console.log(type,name); //iden foo
let obj = {
a:{
name:"张三"
},
b:[],
c:'hello,world'
}
// 不完全解构 可忽略
// let {a} = obj;
// console.log(a); //{name: '张三'}
// 剩余运算符
let {a,...res} = obj;
console.log(a,res); //{name: '张三'} {b: Array(0), c: 'hello,world'}
// 默认值
// let {a,b = 30} = {a:20};
// console.log(a,b) // 20 30
// 对数组解构
// let arr = [1,2,3];
// let [a,b] = arr;
// console.log(a,b); // 1 2
// 可嵌套
// let [a,[b],c] = [1,[2],3];
// console.log(a,b,c) // 1 2 3
</script>
</body>
</html>
扩展的对象功能¶
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>扩展的对象的功能</title>
</head>
<body>
<script>
// es6直接写入变量和函数,作为对象的属性和方法
// const name = '小马哥',age = 20;
// const person = {
// name,//等价于name:name
// age,
// sayName(){
// console.log(this.name);
// }
// }
// person.sayName(); //小马哥
// function fn(x,y) {
// return {x,y};
// }
// console.log(fn(10,20)); //Object x: 10 y: 20 [[Prototype]]: Object
// let cart = {
// wheel:4,
// set(newVal){
// if(newVal < this.wheel){
// throw new Error('轮子数太少了')
// }
// this.wheel = newVal;
// },
// get(){
// return this.wheel;
// }
// }
// console.log(cart.get()); //4
// cart.set(6);
// console.log(cart.get()) //6
// const obj = {};
// obj.isShow = true;
// const name = 'a';
// obj[name+'bc'] = 123;
// console.log(obj); //{isShow: true, abc: 123}
// obj['f'+'bc'] = function () {
// console.log(this);
// }
// console.log(obj); //{isShow: true, abc: 123, fbc: ƒ}
// const name = 'a';
// const obj = {
// isShow:true,
// [name+'bc']:123,
// ['f'+name](){
// console.log(this);
// }
// }
// console.log(obj); //{isShow: true, abc: 123, fa: ƒ}
// 对象的方法
// is() ===
// 比较两个值是否严格相等
console.log(NaN === NaN); // false ES5缺点
console.log(Object.is(NaN,NaN)); // true 与严格比较运算符(===)的行为基本一致。
// ***** assign() ***
// 对象的合并
// Object.assign(target,obj1,obj2....)
// 返回合并之后的新对象
let newObj = Object.assign({},{a:1},{b:2});
console.log(newObj); //{a: 1, b: 2}
</script>
</body>
</html>
Symbol¶
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Symbol</title>
</head>
<body>
<script>
// 原始数据类型Symbol ,它表示是独一无二的值
// 最大的用途:用来定义对象的私有变量
const name = Symbol('name');
const name2 = Symbol('name');
console.log(name === name2); //false
let s1 = Symbol('s1');
console.log(s1); //Symbol(s1)
let obj = {
[s1]:'小马哥'
};
// obj[s1] = '小马哥';
// 如果用Symbol定义的对象中的变量,取值时一定要用[变量名]
console.log(obj[s1]); //小马哥
// console.log(obj.s1); //undefined
for(let key in obj){
console.log(key); //空
}
console.log(Object.keys(obj)); //[]
// 获取Symbol声明的属性名(作为对象的key)
let s = Object.getOwnPropertySymbols(obj);
console.log(s[0]); //Symbol(s1)
// Reflect翻译反射
let m = Reflect.ownKeys(obj);
console.log(m); //[Symbol(s1)]
</script>
</body>
</html>
Map和Set¶
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
// 集合:表示无重复值的有序列表
let set = new Set();
// console.log(set); //Set(1)
// 添加元素
set.add(2);
set.add('4');
set.add('4');
// set.add(['hello','world',3]);
// 删除元素
set.delete(2);
// 校验某个值是否在set中
console.log(set.has('4')); //true
console.log(set.size); //1
/* set.forEach((val,key)=>{
console.log(val);
console.log(key);
}) */
// 将set转换成数组
let set2 = new Set([1, 2, 3, 3, 3, 4]);
// 扩展运算符
let arr = [...set2]
console.log(arr); //(4) [1, 2, 3, 4]
// 1.set中对象的引用无法被释放
// let set3 = new Set(),obj = {};
// set3.add(obj);
// // 释放当前的资源
// obj = null;
// console.log(set3); //Set(1) {{…}}
let set4 = new WeakSet(),
obj = {};
set4.add(obj);
// 释放当前的资源
obj = null;
console.log(set4); //WeakSet {{…}}
// WeakSet
// 1.不能传入非对象类型的参数
// 2.不可迭代
// 3.没有forEach()
// 4.没有size属性
// Map类型是键值对的有序列表,键和值是任意类型
let map = new Map();
map.set('name','张三');
map.set('age',20);
console.log(map.get('name')); //张三
console.log(map); //Map(2) {'name' => '张三', 'age' => 20}
map.has('name');//true
map.delete('name');
map.clear();
console.log(map); //Map(0) {size: 0}
map.set(['a',[1,2,3]],'hello');
console.log(map); //Map(1) {Array(2) => 'hello'}
let m = new Map([
['a', 1],
['c', 2]
]);
console.log(m); //Map(2) {'a' => 1, 'c' => 2}
</script>
</body>
</html>
数组的扩展功能¶
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<script>
// 数组的方法 from() of()
// 1.from() 将伪数组转换成真正的数组
function add() {
console.log(arguments);
// es5转换
// let arr = [].slice.call(arguments);
// console.log(arr);
// es6写法
let arr = Array.from(arguments);
console.log(arr); //(3) [1, 2, 3]
}
add(1, 2, 3);
let lis = document.querySelectorAll('li')
console.log(lis); //NodeList(4) [li, li, li, li]
console.log(Array.from(lis)); //(4) [li, li, li, li]
// 扩展运算符 将伪数组转换成真正的数组
console.log([...lis]); //(4) [li, li, li, li]
// from() 还可以接受第二个参数,用来对每个元素进行处理
let liContents = Array.from(lis, ele => ele.textContent);
console.log(liContents); //(4) ['1', '2', '3', '4']
// 2.of() 将任意的数据类型,转换成数组
console.log(Array.of(3, 11, 20, [1, 2, 3], {
id: 1
})); //(5) [3, 11, 20, Array(3), {…}]
// 3.copywithin() 数组内部将制定位置的元素复制到其它的位置,返回当前数组
// 从3位置往后的所有数值去替换从0位置往后的三个数值
console.log([1, 2, 3, 8, 9, 10].copyWithin(0, 3)); //[8,9,10,8,9,10]
// 4.find() findIndex()
// find()找出第一个符合条件的数组成员
let num = [1, 2, -10, -20, 9, 2].find(n => n < 0)
console.log(num); // -10
// findIndex()找出第一个符合条件的数组成员的索引
// 条件是值小于0,返回索引号
let numIndex = [1, 2, -10, -20, 9, 2].findIndex(n => n < 0)
console.log(numIndex); // 2
// 5.entries() keys() values() 返回一个遍历器 可以使用for...of循环进行遍历
// keys() 对键名遍历
// values() 对值遍历
// entries() 对键值对遍历
console.log(['a','b'].keys()); //Array Iterator {}
for (let index of ['a', 'b'].keys()) {
console.log(index); // 0 1
}
for (let ele of ['a', 'b'].values()) {
console.log(ele); // a b
}
for(let [index,ele] of ['a','b'].entries()){
console.log(index,ele); // 0 'a' 1 'b'
}
let letter = ['a','b','c'];
let it = letter.entries();
console.log(it.next().value); //(2) [0, 'a']
console.log(it.next().value); //(2) [1, 'b']
console.log(it.next().value); //(2) [2, 'c']
console.log(it.next().value); //undefined
// 6.includes() 返回一个布尔值,表示某个数组是否包含给定的值
console.log([1,2,3].includes(2)); // true
console.log([1,2,3].includes('4')); // false
// 之前 indexof()
// console.log([1,2,3].indexOf('2')); // -1
</script>
</body>
</html>
迭代器¶
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>迭代器</title>
</head>
<body>
<script>
// Iterator
// 是一种新的遍历机制,两个核心
// 1.迭代器是一个接口,能快捷的访问数据,通过Symbol.iterator来创建迭代器 通过迭代器的next()获取迭代之后的结果
// 2.迭代器是用于遍历数据结构的指针(数据库的游标)
// 使用迭代
const items = ['one', 'two', 'three'];
// 1.创建新的迭代器
const ite = items[Symbol.iterator]();
console.log(ite.next()); //{value: "one", done: false} done如果为false表示遍历继续 如果为true表示遍历完成
console.log(ite.next());
console.log(ite.next());
console.log(ite.next());
</script>
</body>
</html>
生成器¶
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>生成器 Generator</title>
</head>
<body>
<script>
// generator函数 可以通过yield关键字,将函数挂起,为了改变执行流提供了可能,同时为了做异步编程提供了方案
// 它普通函数的区别
// 1.function后面 函数名之前有个*
// 2.只能在函数内部使用yield表达式,让函数挂起
// function* func() {
// console.log('one');
// yield 2;
// console.log('two');
// yield 3;
// console.log('end');
// }
// // 返回一个遍历器对象 可以调用next()
// let fn = func();
// console.log(fn) // func {<suspended>}
// console.log(fn.next()); //{value: 2, done: false}
// console.log(fn.next());
// console.log(fn.next()); //{value: undefined, done: true}
// 总结:generator函数是分段执行的,yield语句是暂停执行 而next()恢复执行
function* add() {
console.log('start');
// x 可真的不是yield '2'的返回值,它是next()调用 恢复当前yield()执行传入的实参
let x = yield '2';
console.log('one:'+x); // one:20
let y = yield '3';
console.log('two:'+y);
return x+y;
}
const fn = add();
console.log(fn.next()); //{value:'2',done:false}
console.log(fn.next(20)); //{value:'3',done:false} // 20赋值给了x
console.log(fn.next(30)); //{value:50,done:true} //30赋值给了y
// 使用场景1:为不具备Interator接口的对象提供了遍历操作
function* objectEntries(obj) {
// 获取对象的所有的key保存到数组 [name,age]
const propKeys = Object.keys(obj);
for(const propkey of propKeys){
yield [propkey,obj[propkey]]
}
}
const obj = {
name:'小马哥',
age:18
}
// obj[Symbol.iterator] = objectEntries;
// console.log(obj); //{name: '小马哥', age: 18, Symbol(Symbol.iterator): ƒ}
for(let [key,value] of objectEntries(obj)){
console.log(`${key}:${value}`);
}
// name:小马哥
// age:18
</script>
</body>
</html>
Generator的应用¶
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>11 Generator的应用</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<script>
// Generator 部署ajax操作,让异步代码同步化
// 回调地狱 参考https://blog.csdn.net/qq_42698326/article/details/111075519
/* $.ajax({
url: 'https://free-api.heweather.net/s6/weather/now?location=beijing&key=4693ff5ea653469f8bb0c29638035976',
method: 'get',
success(res) {
console.log(res);
// 继续发送请求
$.ajax({
url: '',
method: 'get',
success(res1) {
// 发送ajax
$.ajax({
url: '',
method: 'get',
success(res2) {
// 发送ajax
$
}
})
}
})
}
}) */
function* main() {
console.log('main');
let res = yield request(
'https://free-api.heweather.net/s6/weather/now?location=beijing&key=4693ff5ea653469f8bb0c29638035976'
)
console.log(res);
// 执行后面的操作
console.log('数据请求完成,可以继续操作');
}
const ite = main();
ite.next();
function request(url) {
$.ajax({
url,
method: 'get',
success(res) {
ite.next(res);
}
})
}
// 加载loading...页面
// 数据加载完成...(异步操作)
// loading关闭掉
function* load() {
loadUI();
yield showData();
hideUI();
}
let itLoad = load();
itLoad.next();
function loadUI() {
console.log('加载loading...页面');
}
function showData() {
// 模拟异步操作
setTimeout(() => {
console.log('数据加载完成');
itLoad.next();
}, 1000);
}
function hideUI() {
console.log('隐藏loading...页面');
}
</script>
</body>
</html>
Promise对象¶
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
</head>
<body>
<script>
// Promise 承诺
// 相当于一个容器,保存着未来才会结束的事件(异步操作)的一个结果
// 各种异步操作都可以用同样的方法进行处理 axios
// 特点:
// 1.对象的状态不受外界影响 处理异步操作 三个状态 Pending(进行) Resolved(成功) Rejected(失败)
// 2.一旦状态改变,就不会再变,任何时候都可以得到这个结果
/* let pro = new Promise(function(resolved,rejected) {
//模拟执行异步操作 得到的结果
let res = {
code: 201,
data:{
name:'小马哥'
},
error:'失败了'
}
setTimeout(() => {
if(res.code === 200){
resolved(res.data);
}else{
rejected(res.error);
}
}, 1000);
})
console.log(pro); //Promise
pro.then((val)=>{
console.log(val);
},(err)=>{
console.log(err); //失败了
}); */
/* function timeOut(ms) {
return new Promise((resolved,rejected)=>{
setTimeout(() => {
resolved('hello promise success!!')
}, ms);
})
}
timeOut(2000).then((val)=>{ // 两秒之后返回
console.log(val); //hello promise success!!
}) */
// https://free-api.heweather.net/s6/weather/now?location=beijing&key=4693ff5ea653469f8bb0c29638035976
/* const getJSON = function (url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onreadystatechange = handler;
xhr.responseType = 'json';
xhr.setRequestHeader('Accept', 'application/json');
// 发送
xhr.send();
function handler() {
if (this.readyState === 4) { // 4表示成功回调
if (this.status === 200) {
resolve(this.response.HeWeather6);
} else {
reject(new Error(this.statusText));
}
}
}
})
}
let a = getJSON(
'https://free-api.heweather.net/s6/weather/now?location=beijing&key=4693ff5ea653469f8bb0c29638035976')
.then((data) => {
// console.log(data);
return data[0]
}).then((obj)=>{
console.log(obj); //Promise {<pending>}
})
console.log(a); //{status: 'invalid key'}
*/
/*
catch(err=>{
})
// then(null,err=>{
// })
*/
// getJSON('https://free-ap.heweather.net/s6/weather/now?location=beijing&key=4693ff5ea653469f8bb0c29638035976')
// .then(data => {
// console.log(data);
// }).catch(err => {
// console.log(err);
// })
// then()方法
// then() 第一个参数是relove回调函数,第二个参数是可选的 是reject状态回调的函数
// then()返回一个新的promise实例,可以采用链式编程
// resolve() reject() all() race() done() finally()
// resolve()能将现有的任何对象转换成promise对象
// let p = Promise.resolve('foo');
/* let p = new Promise(resolve=>resolve('foo'));
p.then((data)=>{
console.log(data);
}) */
// 应用:一些游戏类的素材比较多,等待图片、flash、静态资源文件 都加载完成 才进行页面的初始化
// 伪代码
/* let promise1 = new Promise((resolve, reject) => {});
let promise2 = new Promise((resolve, reject) => {});
let promise3 = new Promise((resolve, reject) => {});
let p4 = Promise.all([promise1, promise2, promise3])
p4.then(()=>{
// 三个都成功 才成功
}).catch(err=>{
// 如果有一个失败 则失败
}) */
// race() 某个异步请求设置超时时间,并且在超时后执行相应的操作
// 1 请求图片资源
// function requestImg(imgSrc) {
// return new Promise((resolve, reject) => {
// const img = new Image();
// img.onload = function () { //onload 当图像装载完毕时调用的事件句柄。
// resolve(img); //Promise.resolve(value)方法返回一个以给定值解析后的Promise 对象
// }
// img.src = imgSrc;
// });
// }
// function timeout() {
// return new Promise((resolve, reject) => {
// setTimeout(() => {
// reject(new Error('图片请求超时'));
// }, 3000);
// })
// }
// Promise.race([requestImg('https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fblog%2F202102%2F18%2F20210218112720_25189.thumb.1000_0.jpg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1646595131&t=12acaf9c7b1e00ac6a874e1b0945c3af'),
// timeout()]).then(data=>{
// console.log(data);
// document.body.appendChild(data);
// }).catch(err=>{
// console.log(err);
// });
/*
server.listen(3000).then(()=>{
}).finally(server.stop()); //finally不管前面执行是否成功,最后都会执行
*/
</script>
</body>
</html>
async用法¶
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>async异步操作</title>
</head>
<body>
<script>
//Generator Promise async 1.解决回调地域 2.使得异步操作显得更加方便
// 作用:使得异步操作更加方便
// 基本操作 async它会返回一个Promise对象 then catch
// async是Generator的一个语法糖
async function f() {
// return await 'hello async';
let s = await 'hello world';
let data = await s.split('');
return data;
}
// 如果async函数中有多个await 那么then函数会等待所有的await指令 运行完的结果 才去执行
f().then(v => {
console.log(v) //Array(11)
}).catch(e => console.log(e));
async function f2() {
// throw new Error('出错了');
try {
await Promise.reject('出错了');
} catch (error) {
}
return await Promise.resolve('hello');
}
f2().then(v => console.log(v)).catch(e => console.log(e)); //hello
// 需求: 想获取和风天气 现在now的数据
const getJSON = function (url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onreadystatechange = handler;
xhr.responseType = 'json';
xhr.setRequestHeader('Accept', 'application/json');
// 发送
xhr.send();
function handler() {
if (this.readyState === 4) {
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
}
}
})
}
async function getNowWeather(url) {
// 发送ajax 获取实况天气
let res = await getJSON(url);
console.log(res); //object
// 获取HeWeather6的数据 获取未来3~7天的天气状况
let arr = await res.HeWeather6;
return arr[0].now;
}
//https://www.qweather.com/ api失效
getNowWeather(
'https://free-api.heweather.net/s6/weather/now?location=beijing&key=4693ff5ea653469f8bb0c29638035976')
.then(now => {
console.log(now);
})
</script>
</body>
</html>
class 类¶
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
// es5造类
/* function Person(name,age) {
this.name = name;
this.age = age;
}
Person.prototype.sayName = function() {
return this.name;
}
let p1 = new Person('小马哥',28);
console.log(p1);
*/
class Person {
// 实例化的时候会立即被调用
constructor(name, age) {
this.name = name;
this.age = age;
}
}
// 通过Object.assign()方法一次性向类中添加多个方法
Object.assign(Person.prototype, {
sayName() {
return this.name
},
sayAge() {
return this.age
}
})
let p1 = new Person('小马哥', 28);
console.log(p1);
</script>
</body>
</html>
类的继承 extends¶
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>类的继承</title>
</head>
<body>
<script>
// 使用关键字 extends
class Animal{
constructor(name,age) {
this.name = name;
this.age = age;
}
sayName(){
return this.name;
}
sayAge(){
return this.age;
}
}
class Dog extends Animal{
constructor(name,age,color) {
super(name,age);
// Animal.call(this,name,age);
this.color = color;
}
// 子类自己的方法
sayColor(){
return `${this.name}是${this.age}岁了,它的颜色是${this.color}`
}
// 重写父类的方法
sayName(){
return this.name + super.sayAge() + this.color;
}
}
let d1 = new Dog('小黄',28,'red');
console.log(d1.sayColor());
console.log(d1.sayName());
// 思考:如何让多个类 混入到一个类中????
</script>
</body>
</html>
module模块的使用¶
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script type='module'>
/*
运行模块导入 需要用服务器启动,vscode插件 Live Server
*/
// CommonJS和AMD
// ES6 module
import Person,{name,age,sayName} from './modules/index.js'
// import * as f from './modules/index.js'
// console.log(Person);
const p = new Person();
p.sayAge();
// console.log(f.default);
// console.log(name,age,sayName());
</script>
</body>
</html>
./modules/index.js
// es6模块功能主要有两个命令构成:export和import
// export用于规定模块的对外接口 import用于输入其它模块提供的功能
// 一个模块就是独立的文件
/* export const name = '张三';
export const age = 18;
export function sayName(){
return 'my name is 小马哥';
} */
// export {sayName}
const name = '张三';
const age = 18;
function sayName() {
return 'my name is 小马哥';
}
export {
name,age,sayName
}
/* const obj = {
foo:'foo'
} */
class Person{
constructor(){
}
sayAge(){
console.log('16');
}
}
export default Person;