相关学习推荐:javascript
前言
说起JavaScript,大家都知道是一门脚本语言。那么ES是什么鬼呢?ES全称ECMAScript ,是JavaScript语言的国际标准。
最近总结了条js的基础特性相关的知识点,大家一起看一下吧
1.严格模式使用严格模式,可以在函数内部进行较为严格的全局和局部的错误条件检查严格模式的编译指示,"use strict"创建全局变量,未声明变量,非严格模式下为创建全局变量;严格模式下为抛出ReferenceError对变量调用delete操作符,删除变量,非严格模式下为静默失败;严格模式下为抛出ReferenceError操作对象情况下:a,只读属性赋值会抛出TypeError;b,对不可配置的属性使用delete操作符会抛出TypeError;c,为不可扩展的对象添加属性会抛出TypeError。重名属性情况:a,非严格模式下没有错误,以第二个属性为准;b,严格模式下会抛出语法错误。函数参数必须唯一,重名参数,在非严格模式下没有错误,只能访问第二个参数;严格模式下,会抛出错误。
复制function funValue(value){
value="dada";
alert(value);// dada
alert(argument[0]);// 非严格模式:dada// 严格模式模式 dadaqianduan}
funValue(dadaqianduan);复制代码
访问arguments.callee和arguments.caller,在非严格模式下没有问题,严格模式下抛出TypeError。2.Class基础语法
在JavaScript当中如何声明一个类?如何定义类中的方法?如何实例化对象?
我们来看看下面的代码示例:
复制// es5let dada = function(type) { this.type = type}
dada.prototype.study =function(){ console.log(魔王哪吒);}let da1 =new dada(程序员)let da2 =new dada(It)
da1.constructor.prototype.study =function(){ console.log(dadaqianduan);}
da1.study()复制代码
JavaScript constructor 属性
定义和用法
constructor 属性返回对创建此对象的数组函数的引用。
语法
object.constructor
constructor 是一种用于创建和初始化class创建的对象的特殊方法。
复制// es6class Da { constructor(name) { // 构造函数内写属性this.name = name;}
eat(){// 构造函数外写方法
console.log(i eat)}}const da1 =newDa(da1);console.log(da1.name);// da1console.log(da1);复制代码
一个类中只能有一个名为“constructor"的方法,出现多次构造函数constructor方法会抛出一个SyntaxError错误在一个构造方法中可以使用super来调用一个父类的构造方法如果没有指定一个构造函数方法constructor方法,就会使用一个默认的构造函数3.类的属性Setter和Getter
复制var daObj ={get val(){return;},set val(value){}}复制代码
get:
复制var da ={ a:1,get val(){returnthis.a 1;}}console.log(da.val);//2da.val = 100;console.log(da.val);//2class Da { constructor(type) { this.type = type}get age(){return1}set age(val){this.realAge = val
}
eat(){ console.log(i am eat)}}let da1 =newDa(da1)console.log(da1.age)
da1.age =1console.log(da1.realAge)复制代码
复制classDa{
constructor(type, age){this.type = type
this.age1 = age
}get age(){returnthis._age
}set age(val){this._age = val
}}复制代码
利用set/get实现对element.innerHTML封装
复制class myHTMLElement {
constructor(element){this.element = element
}get html(){returnthis.element.innerHTML
}set html(value){this.element.innerHTML = value
}}复制代码
设置一个闭包,通过一定的规则来限制对它的修改:
复制let myName =dadaclassDa{
constructor(type){this.type = type
}get name(){return myName
}set name(val){
myName = val
}}复制代码
4.静态方法
在es5中实现的静态方法:
复制let Da=function(type){this.type = type this.eat =function(){ console.log(i eat)}}Da.study =function(book){ console.log(i book);}复制代码
复制let Da=function(type){this.type = type
}Da.prototype.eat =function(){Da.walk() console.log(i am)}Da.walk =function(){ console.log(walk)}let da1 =newDa(da1)
da1.eat()// walk// i am复制代码
静态方法在你的实例化对象是找不到的
在es6中的静态方法,标记static
复制classDa{
constructor(type){this.type = type
}
eat(){
console.log(i eat)}static study(){
console.log(i study)}}复制代码
5.如何继承一个类
在es5中的继承:
复制// 定义一个父类
let Da=function(type){this.type = type
}// 定义方法Da.prototype.eat =function(){
console.log(i am)}// 定义静态方法Da.study =function(book){
console.log(i study)}// 定义子类
let Da1=function(){// 初始化父类Da.call(this,da1);this.run =function(){
console.log(i run)}}// 继承Da1.prototype =Da.prototype复制代码
在es6中的继承
复制classDa{ constructor(type){this.type = type
}
eat(){// Da.walk();
console.log(i eat)}static walk(){ console.log(i walk)}}class da extendsDa{// 构造函数//constructor (type) {//super(type)//}
run(){ console.log(i run)}}let da1 =new da(da1)复制代码
6.面向对象编程Class
类的声明,属性,方法,静态方法,继承,多态,私有属性
复制// 类的声明
let Da=function(type){this.type = type
this.eat =function(){
console.log(i eat);}}
let da =newDa(da);复制代码
复制// prototype
let Da=function(type){this.type = type
}Da.prototype.eat =function(){
console.log(i eat)}
let da1 =newDa(da1)复制代码
es6中的Class
复制classDa{// 构造函数
constructor(type){this.type = type
}// 方法
walk(){
console.log(i walk)}}
let da =newDa(da);// console.log(typeof Da); function复制代码
7.函数参数的默认值
函数参数是从左到右解析,如果没有默认值会被解析成 undefined
复制// 参数默认值function da (x,y,z){}function sum(){
let num =0Array.prototype.forEach.call(arguments,function(item){
num = item *1})Array.from(arguments).forEach(function(item){
num = item *1})return num
}复制代码
复制// 不确定function sum(...nums){
let num =0
nums.forEach(function(item){
num = item *1})return num
}
console.log(sum(1,2,3,4,5))复制代码
复制function sum (){
let num =0Array.prototype.forEach.call(arguments,function(item){
num = item *1})return num
}function sum (...nums){
let num =0
nums.forEach(function(item){
num = item *1})return num
}复制代码
8.es6箭头函数
箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this,arguments,super或new.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。
复制()=>{}// function Da() {}// let da = function() {}
let da =()=>{
console.log(hello)}
da()
let da = name =>{}复制代码
复制const materials =[Hydrogen,Helium,Lithium,Beryllium];console.log(materials.map(material => material.length));// expected output: Array [8, 6, 7, 9]复制代码
拓展
判断函数有几个参数
在 ES5 中可以在函数体内使用 arguments 来判断。在 ES6 中可以借助 Function.length 来判断。(统计第一个默认参数前面的变量数)
复制console.log(sum(...[4]))
console.log(sum.apply(null,[4]))复制代码
9.JavaScript中的三个点(…)
JavaScript当中,函数的参数前面有三个点,代表什么呢?我们看下代码示例:
复制function myFunc(a, b,...args){
console.log(a);// 22
console.log(b);// 98
console.log(args);// [43, 3, 26]};
myFunc(22,98,43,3,26);复制代码
复制function myFunc(x, y,...params){// used rest operator here
console.log(x); console.log(y); console.log(params);}var inputs =["a","b","c","d","e","f"];
myFunc(...inputs);// used spread operator here// "a"// "b"// ["c", "d", "e", "f"]复制代码
复制var obj1 ={ foo:bar, x:42};var obj2 ={ foo:baz, y:13};var clonedObj ={...obj1 };// Object { foo: "bar", x: 42 }var mergedObj = { ...obj1, ...obj2 };// Object { foo: "baz", x: 42, y: 13 }复制代码
10.Object Property
JS中对象的属性定义,代码示例如下:
复制let x =da1;
let y =da2;
let obj ={
x,
y
}
console.log(obj);// 结果{x:da1,y:da2}复制代码
复制let x=1; let y=2; let z=3
let obj ={x: x,
y,[z y]:4,* hello(){// 异步
console.log(dada)}}// function* functionName() {}
obj.hello()复制代码
11.Set数据结构
Set存储的成员不允许的重复的(它类似于数组)
Set 本身是一个构造函数,用来生成 Set 数据结构。
复制const s =newSet();[2,3,5].forEach(x => s.add(x));Set函数可以接受一个数组(或类似数组的对象)作为参数,用来初始化constset=newSet([1,2,3,4,4]);复制代码
实现数组去重
复制var arr =[1,1,2,2,3,3];// step1:数组转集合var s =newSet(arr);// 已经去掉重复值,当前不是数组,而集合
s.size;// 3// step2:集合转数组
console.log([...s]);// 1,2,3;// Array.form 方法可以将 Set 结构转为数组const items =newSet([1,2,3]);const arr =Array.from(items);function dada(array){returnArray.from(newSet(array));}
dada([1,1,2])复制代码
Set的遍历
keys():返回键名的遍历器values():返回键值的遍历器entries():返回键值对的遍历器forEach():使用回调函数遍历每个成员
操作方法
add(value):添加某个值,返回Set结构本身。delete(value):删除某个值,返回一个布尔值,表示删除是否成功。has(value):返回一个布尔值,表示该值是否为Set的成员。clear():清除所有成员,没有返回值。
复制let set=newSet([1,2,3,4,4]);// 添加数据
let addSet =set.add(5);
console.log(addSet);// Set(5) {1, 2, 3, 4, 5}// 删除数据
let delSet =set.delete(4);
console.log(delSet);// true// 查看是否存在数据 4
let hasSet =set.has(4);
console.log(hasSet);// false// 清除所有数据set.clear();
console.log(set);// Set(0) {}复制代码
实现并集(Union)、交集(Intersect)和差集(Difference)
复制let a =newSet([1,2,3]);
let b =newSet([4,3,2,1]);// 并集
let union=newSet([...a,...b]);// Set {1, 2, 3, 4}// 交集
let intersect =newSet([...a].filter(x => b.has(x)));// set {1, 2, 3}// 差集
let difference =newSet([...b].filter(x =>!a.has(x)));// Set {4}复制代码
12.Map数据结构
JS当中的哈希表,使用方法如下:
复制let map =newMap()
map.set(1,2)
map.set(3,4)
map.set(1,3)
console.log(map)创建var da =newMap();var jeskson ={};遍历
da.forEach(function(value,key,map){}长度
da.size
删除//da.delete() 删除key,全部清楚da.clear()新增
da.set(key,value)
da.has(查索引值)
da.forEach((value,key)=>{})for( let [key, value] of map){}// let map = new Map( [[1,2], [3,4]] )
map的key任意都可以
let o =function(){
console.log(o)}
map.set(o,3)
console.log(map.get(o));// 3复制代码
复制// map.jsvarDictionary=function(){var items ={};// 检查键this.has =function(key){return key in items;}// 添加键值对this.set=function(key, value){
items[key]= value;}// 通过键移除元素this.delete=function(key){if(this.has(key)){delete items[key]returntrue}returnfalse}// 键获取值this.get=function(key){returnthis.has(key)? items[key]:undefined;}// 列表返回字典值this.values =function(){var values =[];for(var k in items){if(this.has(k)){
values.push(items[k])}}return values;}// 获取全部键名this.keys =function(){returnObject.keys(items);}// 获取私有变量itemsthis.getItems =function(){return items;}}复制代码
Map数据结构,它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
13.Object.assign(对象的拷贝)
Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
复制const target ={ a:1, b:2};const source ={ b:4, c:5};const returnedTarget =Object.assign(target, source);
console.log(target);// expected output: Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget);// expected output: Object { a: 1, b: 4, c: 5 }>Object{ a:1, b:4, c:5}>Object{ a:1, b:4, c:5}复制代码
语法
复制Object.assign(target,...sources)复制代码
参数
复制target复制代码
目标对象
复制sources复制代码
源对象
返回值
目标对象。
复制const obj ={ a:1};const copy =Object.assign({}, obj);
console.log(copy);// { a: 1 }复制代码
Object.assign()拷贝的是(可枚举)属性值Object.assign方法的第一个参数是目标对象,后面的参数都是源对象如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性由于undefined和null无法转成对象,所以如果它们作为参数,就会报错如果undefined和null不在首参数,就不会报错如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用(这个对象的任何变化,都会反映到目标对象上面。)
复制Object.assign(undefined)// 报错Object.assign(null)// 报错
let obj ={a:1};Object.assign(obj,undefined)=== obj // trueObject.assign(obj,null)=== obj // trueconst obj1 ={a:{b:1}};const obj2 =Object.assign({}, obj1);
obj1.a.b =2;
obj2.a.b // 2const target ={ a:{ b:c, d:e}}const source ={ a:{ b:hello}}Object.assign(target, source)// { a: { b: hello } }const source ={get foo(){return1}};const target ={};Object.assign(target, source)// { foo: 1 }复制代码
Object.assign复制的是属性值value,如果属性值是一个引用类型,那么复制的其实是引用地址,就会存在引用共享的问题(Object.assign(target,source1,…,sourceN)浅拷贝的过程)
要点:
复制functionObjectAssign(target,...sources){// 对第一个参数的判断,不能为undefined和nullif(target ===undefined|| target ===null){throwmyTypeError(error);}// 将第一个参数转为对象(不是对象转换为对象)const targetObj =Object(target);// 将源对象自身的所有可枚举属性复制到目标对象for(let i =0; i{ let script = document.createElement(script)
script.src = src
script.onload =()=> resolve(src)
script.onerror =(err)=> reject(err) document.head.append(script)})}复制代码
复制function loadScript(src){ let script = document.createElement(script);
script.src = src; document.head.append(script)}复制代码
复制var promise =newPromise(function(resolve, reject){
resolve(传递给then的值)})
promise.then(function(value){
console.log(value)},function(error){
console.error(error)})复制代码
Promise对象是用于表示一个异步操作的最终完成(或失败),以及其结果值。
示例:
复制const promise =newPromise((resolve, reject)=>{
setTimeout(()=>{
resolve(da);},200);});
promise.then((value)=>{
console.log(value);});
console.log(promise);复制代码
语法:
复制newPromise(function(resolve,reject){...});复制代码
描述:Promise对象是一个代理对象,被代理的值在Promise对象创建时可能是未知的,它允许你为异步操作的成功和失败分别绑定相应的处理方法,这让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是一个能代表未来出现的结果的promise对象。
一个Promise有以下几种状态:
pending,初始状态,既不是成功,也不是失败状态。fulfilled,意味着操作成功完成。rejected,意味着操作失败。
pending状态的Promise对象可能会变为fulfilled状态并传递一个值给相应的状态处理方法。
Promise.prototype.then和Promise.prototype.catch方法返回promise对象,所以它们可以被链式调用。
方法:
Promise.all(iterable)
返回一个新的promise对象在iterable参数对象里所有的promise对象都成功时,才会触发成功当任何一个iterable里面的promise对象失败,才会触发promise对象的失败成功状态会把一个包含iterable里所有promise返回值的数组作为成功回调的返回值,顺序和iterable的顺序一样如果这个新的promise对象触发了失败,会把iterable里的第一个触发失败的promise对象的错误信息作为它的失败信息场景,多用于处理多个promise对象的状态集合
Promise.any(iterable)
接收一个Promise对象的集合,当其中的一个promise成功,就返回那个成功的promise的值
Promise.reject(reason)
返回一个状态为失败的Promise对象,然后将失败信息传递给对应的处理方法
Promise.resolve(value)
返回一个状态由给定value决定的Promise对象
Promise原型
属性:Promise.prototype.constructor返回被创建的实例函数,默认为Promise函数。
方法:
Promise.prototype.catch(onRejected)Promise.prototype.then(onFulfilled,onRejected)Promise.prototype.finally(onFinally)
复制function myAsyncFunction(url){returnnewPromise((resolve, reject)=>{const xhr =newXMLHttpRequest();
xhr.open(GET,url);
xhr.onload =()=> resolve(xhr.responseText);
xhr.onerror =()=> reject(xhr.statusText);
xhr.send();});}复制代码
17.ES6代理默认情况下,代理不执行任何操作
示例:
复制var target ={}var handler ={}var proxy =newProxy(target, handler)
proxy.a =bconsole.log(target.a)// bconsole.log(proxy.c === undefined)// true复制代码
为了更好地了解代理的有用性,让我们做一些小练习。
示例:
想象一下,您已经17岁了,即将满18岁。并且您希望您的程序在打开时自动向您祝贺。为此,您可以使用代理。
复制var person ={ name:"dada", age:17};
person =newProxy(person,{set(target, property, value){if(value ===18){ console.log("Congratulations! You are of legal age");Reflect.set(target, property, value);returntrue;}}});
person.age =18;if(value <13&& value >99){thrownewError(The age should be between 13 and 99)}else{Reflect.set(target, property, value)}复制代码
语法:
复制let p =newProxy(target, handler)复制代码
target 用Proxy包装的目标对象handler 一个对象,其属性是当执行一个操作时定义代理的行为的函数
如果不想再调用key的时候,返回undefined:
复制console.log(o.dada ||)复制代码
使用Proxy
复制let o ={
name:dada, age:1}let handler ={get(obj, key){returnReflect.has(obj, key)?obj[key]:}}let p =newProxy(o, handler)console.log(p.from)复制代码
希望从服务器获取的数据只读,不允许修改:
复制for(let [key] of Object.entries(response.data)){Object.defineProperty(response.data, key,{
writable:false})}复制代码
使用Proxy:
复制let data =newProxy(response.data,{set(obj, key, value){returnfalse}})复制代码
检验逻辑代码:
复制// Validator.jsexport default(obj, key, vlaue) => { if(Reflect.has(key) && value > 20) {
obj[key]= value
}}importValidatorfrom./Validatorlet data =newProxy(response.data,{set:Validator})复制代码
使用Proxy,对读写进行监控:
复制let validator ={set(target, key, value){if(key ===age){if(typeof value !==number||Number.isNaN(value)){thrownewTypeError(Age must be a number)}if(value<=0){thrownewTypeError(Age must be a positive number)}}returntrue}}const person ={ age:12}const proxy =newProxy(person,validator)
proxy.age =dada// TypeError numberproxy.age = NaNproxy.age = 0 // positive numberproxy.age = 3复制代码
示例:每个对象都有一个自己的id
复制classComponent{ constructor(){this.proxy =newProxy({ id:Math.random().toString(36).slice(-8)})}get id(){returnthis.proxy.id
}}复制代码
18.Generator
复制function* dada(){for(let i=0; i<2; i {yield console.log(i);}}const da = dada()
da.next()
da.next()复制代码
Generator函数与普通函数的区别在于定义的时候有一个*,执行下面函数:
复制function* dada(){
console.log(dadaqianduan);}
dada();// 没有执行函数如需要输出,改为:var da = dada();
da.next();复制代码
要生成一个自增的id:
复制var count_id =0;function dada_id(){
count_id ;return count_id;}复制代码
方法
复制Generator.prototype.next()返回一个由yield表达式生成的值。Generator.prototype.return()返回给定的值并结束生成器。Generator.prototype.throw()向生成器抛出一个错误。复制代码
书写风格:
复制function*da(){}function* da(){}复制代码
方法
Generator对象方法:next,return,throw
通过Next方法来获取每一次遍历的结果,这个方法返回一个对象,这个对象包含两个value和done。
value:当前程序的运行结果
done:遍历是否结束
next是可以接收参数的,这个参数可以让你在generator外部给内部传递数据,这个参数就是作为yield的返回值。
return()方法可以让generator遍历终止
复制function* da(){yield1yield2yield3}var d = da()
console.log(d.next())// {value:1,done:false}
console.log(d.return())// {value:undefined,done:true}
console.log(d.next())// {value:undefined,done:true}复制代码
return可以传入参数,作为返回的value的值
复制function* da(){yield1yield2yield3}var d = da()
console.log(d.nex())// {value:1,done:false}
console.log(d.return(100))// {value:100,done:true}
console.log(d.next())// {value:undefined,done:true}复制代码
throw()方法在generator外部控制内部执行的“终断”
generator函数声明:
复制function* genFunc(){...}const genObj = genFunc();复制代码
generator表达式:
复制const genFunc =function*(){...}const genObj = genFunc();复制代码
对象中定义:
复制const obj ={* generatorMethod(){...}}const genObj = obj.generatorMethod();复制代码
类定义(类声明或类表达式):
复制classMyClass{* generatorMethod(){...}}const myInst =newMyClass();const genObj = myInst.generatorMethod();复制代码
最简单的iterator遍历规范:
复制authors[Symbol.iterator]=function(){// thisreturn{next(){return{done:false,
value:1}}}}复制代码
19.module
在es6前,js文件之间的导入,导出是借助require.js,sea.js,如现在使用import,export,来实现原生javascript的导入,导出。
export:
复制导出变量或者常量exportconst da =dadaqianduanexport let da1 =da1exportvar da2 =da1const name =dada
let name1 =dada1export{
name,
name1
}导出函数exportfunction da(value){
console.log(value)}const da =(value)=>{
console.log(value);}export{
da
}导出Objectexport({
name:da1,
message:dadaqianduan})
let da ={
name:name1}export{
da
}导出ClassclassDa{
constructor(){this.id =1}}export{Da}exportclassDa{
constructor(){this.id =1}}修改导出名称const name =da1export{
name as cname
}exportdefault name复制代码
import
复制// 直接导入const name =dada
let name1 =dada1var name2 =dada2export{
name as cname
}exportdefault name2
import name2,{name1, name}from A复制代码
复制exportconst sqrt =Math.sqrt;exportfunction square(x){return x * x;}exportfunction dada(x,y){return sqrt(square(x) square(y));}import{square,da}fromda;
console.log(square(11));// 121
console.log();复制代码
复制exportdefaultfunction(){...}import myFunc frommyFunc;exportdefaultclass{...}importMyClassfromMyClass;const inst =newMyClass();复制代码
20.import, export
复制require--lib.js--function add(x,y){return x y
}module.exports ={
add: add,};--main.js--var add =require(lib).addd;
console.log(add(1,2));复制代码
复制import--lib.js--exportfunction add(x,y){return x y
}--main.js--import{add}fromlib;
console.log(add(1,2));复制代码
复制--lib.js--exportconst sqrt =Math.sqrt;exportfunction square(x){return x * x;}exportfunction da(x,y){return sqrt(square(x) square(y));}--main.js--import{square, da}fromlib--myFunc.js--exportdefaultfunction(){...};--main.js--import myFunc frommyFunc;
myFunc();复制代码
21.Array.prototype.includes,Promise
该方法判断一个数组是否包含一个指定的值,返回布尔值
复制let da1 =[1,2,3];
console.log(da1.includes(2));复制代码
复制arr.find(function(item){return item ===1;})
arr.filter(function(item){return item ===2;})Math.pow(2,3)->2**3复制代码
复制async function firstAsync(){
let promise =newPromise((resolve,reject)=>{
setTimeout(function(){
resolve(dadaqianduan)},1000)})
console.log(await promise)
console.log(await Promise.resolve(1))
console.log(2)returnPromise.resolve(3)}
firstAsync().then(val =>{
console.log(val)})复制代码
await后面是Promise对象
Object.values()返回一个数组,其元素是再对象上找到的可枚举属性值。
复制let da ={da:1,da2:2}
console.log(Object.value(da))// [1,2]Object.values是在对象上找到可枚举的属性的值,所以只要这个对象是可枚举的就可以复制代码
Object.entries()方法返回一个给定对象自身可枚举属性的键值对数组
22.JS异步进阶
题目一:
复制Promise.resolve().then(()=>{
console.log(1)}).catch(()=>{
console.log(2)}).then(()=>{
console.log(3)})复制代码
题目二:
复制Promise.resolve().then(()=>{
console.log(1)thrownewError(da)}).catch(()=>{
console.log(2)}).then(()=>{
console.log(3)})复制代码
题目三:
复制Promise.resolve().then(()=>{
console.log(1)thrownewError(da)}).catch(()=>{
console.log(2)}).catch(()=>{
console.log(3)})复制代码
题目四:
复制async function fn(){return1}(async function(){const a = fn()// ??const b = await fn()// ??})()复制代码
题目五:
复制console.log(100)
setTimeout(()=>{
console.log(200)})Promise.resolve().then(()=>{
console.log(300)})
console.log(400)复制代码
题目六:
复制async function async1(){
console.log(async1 start)
await async2()
console.log(async1 end)}
async function async2 (){
console.log(async2)}
console.log(script start)
setTimeout(function(){
console.log(setTimeout)},0)
async1()newPromise(function(resolve){
console.log(promise1)
resolve()}).then(function(){
console.log(promise2)})
console.log(script end)复制代码
加载图片:
复制// 加载function loadImg(src){const p =newPromise((resolve,reject)=>{const img = document.createElement(img)
img.onload =()=>{
resolve(img)}
img.onerror =()=>{const err =newError(图片加载失败)
reject(err)}
img.src = src
})return p
}const url =httpsconst p = loadImg(url)
p.then(img =>{
console.log(img.width)return img
}).then(img =>{
console.log(img.height)}).catch(ex =>{
console.error(ex)})复制代码
复制async function async1(){
console.log(async1 start)// 2
await async2()// undefined
console.log(async1 end)// 5}
async function async2(){
console.log(async2)// 3}
console.log(script start)// 1
async1()
console.log(script end)// 4复制代码
for…of常用于异步的遍历
复制function add(num){returnnewPromise(resolve =>{
setTimeout(()=>{
resolve(num*num)},1000)})}const nums =[1,2,3]
nums.forEach(async(i)=>{const res = await add(i)})复制代码
23.宏任务和微任务
宏任务:setTimeout,setInterval,ajax等
微任务:Promise async/await
微任务执行时比宏任务要早:
宏任务:DOM渲染后触发,如setTimeout
微任务:DOM渲染前触发,如Promise
24.For await of 异步操作集合
复制function da(time){returnnewPromise(function(resolve,reject){
setTimeout(function(){
resolve(time)},time)})}
async function test(){
let arr =[da(2000),da(1000),da(3000)]for await (let item of arr){
console.log(Date.now(), item)}}复制代码
复制const input ={
a:1,
b:2}const output ={...input,
c:3}
console.log(output)const input ={
a:1,
b:2,
c:3}
let {a,...rest }= input复制代码
25Array.prototype.flat()
该方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合为一个新数组。
Array.prototype.flat()建议将数组递归展平至指定范围depth并返回新数组。
depth(指定要提取嵌套数组的结构深度)
语法:Array.prototype.flat(depth)
depth —默认值1,Infinity用于展平所有嵌套数组。
复制const numbers =[1,2,[3,4,[5,6]]];// Considers default depth of 1
numbers.flat();>[1,2,3,4,[5,6]]// With depth of 2
numbers.flat(2);>[1,2,3,4,5,6]// Executes two flat operations
numbers.flat().flat();>[1,2,3,4,5,6]// Flattens recursively until the array contains no nested arrays
numbers.flat(Infinity)>[1,2,3,4,5,6]复制代码
语法:Array.prototype.flatMap(callback)
callback:function产生新Array的元素。
复制const numbers =[1,2,3];
numbers.map(x =>[x *2]);>[[2],[4],[6]]
numbers.flatMap(x =>[x *2]);>[2,4,6]复制代码
Object.fromEntries
Object.fromEntries执行与的相反操作Object.entries。它将一组键值对转换为一个对象。
复制const records =[[name,da],[age,32]];const obj =Object.fromEntries(records);>{ name:da, age:32}Object.entries(obj);>[[name,Mathew],[age,32]];复制代码
Symbol.prototype.description
只读属性,返回Symbol对象的可选描述:
复制Symbol(desc).toString();>"Symbol(desc)"Symbol(desc).description;>"desc"Symbol().description;>""Symbol().description;>undefined复制代码
完结,笑纳。
想了解更多编程学习,敬请关注php培训栏目!