Map、Set
参考https://www.runoob.com/w3cnot...
Map
Map是一组键值对的构造,具备极快的查找速度。
举个例子,假如要依据同学的名字查找对应的问题,如果用Array实现,须要两个Array:
var names = ['Michael', 'Bob', 'Tracy'];var scores = [95, 75, 85];
给定一个名字,要查找对应的问题,就先要在names中找到对应的地位,再从scores取出对应的问题,Array越长,耗时越长。
如果用Map实现,只须要一个“名字”-“问题”的对照表,间接依据名字查找问题,无论这个表有多大,查找速度都不会变慢。用JavaScript写一个Map如下:
var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);m.get('Michael'); // 95
初始化Map须要一个二维数组,或者间接初始化一个空Map。Map具备以下办法:
var m = new Map(); // 空Mapm.set('Adam', 67); // 增加新的key-valuem.set('Bob', 59);m.has('Adam'); // 是否存在key 'Adam': truem.get('Adam'); // 67m.delete('Adam'); // 删除key 'Adam'm.get('Adam'); // undefined因为一个key只能对应一个value,所以,屡次对一个key放入value,前面的值会把后面的值冲掉:var m = new Map();m.set('Adam', 67);m.set('Adam', 88);m.get('Adam'); // 88
Set
Set和Map相似,也是一组key的汇合,但不存储value。因为key不能反复,所以,在Set中,没有反复的key。
要创立一个Set,须要提供一个Array作为输出,或者间接创立一个空Set:
var s1 = new Set(); // 空Setvar s2 = new Set([1, 2, 3]); // 含1, 2, 3
反复元素在Set中主动被过滤:
var s = new Set([1, 2, 3, 3, '3']);s; // Set {1, 2, 3, "3"}
留神数字3和字符串'3'是不同的元素。
通过add(key)办法能够增加元素到Set中,能够反复增加,但不会有成果:
s.add(4);s; // Set {1, 2, 3, 4}s.add(4);s; // 依然是 Set {1, 2, 3, 4}
通过delete(key)办法能够删除元素:
var s = new Set([1, 2, 3]);s; // Set {1, 2, 3}s.delete(3);s; // Set {1, 2}
Maps 和 Objects 的区别?
一个 Object 的键只能是字符串或者 Symbols,但一个 Map 的键能够是任意值。
Map 中的键值是有序的(FIFO 准则),而增加到对象中的键则不是。
Map 的键值对个数能够从 size 属性获取,而 Object 的键值对个数只能手动计算。
Object 都有本人的原型,原型链上的键名有可能和你本人在对象上的设置的键名产生抵触。
for in 、for of区别?
例一:
const obj = { a: 1, b: 2, c: 3 } for (let i in obj) { console.log(i) // a、 b、c } for (let i of obj) { console.log(i)// Uncaught TypeError: obj is not iterable 报错了 }
例二:
const arr = ['a', 'b', 'c'] // for in 循环 for (let i in arr) { console.log(i)//0,1,2 返回的数据下标 } // for of for (let i of arr) { console.log(i)//a,b,c }
例三:
const arr = ['a', 'b'] // 手动给 arr数组增加一个属性 arr.name = 'qiqingfu' // for in 循环能够遍历出 name 这个键名 for (let i in arr) { console.log(i) // a,b,name } for (let i of arr) { console.log(i)//a,b }
联合下面的例子,剖析得出:
for...in 语句用于遍历数组或者对象的属性(对数组或者对象的属性进行循环操作)。
for in失去对对象的key或数组,字符串的下标
for of和forEach一样,是间接失去值
for of不能对象,会报错
简略说,for in是遍历键名,for of是遍历键值。
var let const的区别?
var申明变量能够反复申明,而let不能够反复申明 var是不受限于块级的,而let是受限于块级 var会与window相映射(会挂一个属性),而let不与window相映射 var能够在申明的下面拜访变量,而let有暂存死区,在申明的下面拜访变量会报错 const申明之后必须赋值,否则会报错 const定义不可变的量,扭转了就会报错 const和let一样不会与window相映射、反对块级作用域、在申明的下面拜访变量会报错
箭头函数的了解?
1、箭头函数根本模式
let func = (num) => num;let func = () => num;let sum = (num1,num2) => num1 + num2;[1,2,3].map(x => x * x);
2、箭头函数根本特点
(1). 箭头函数this为父作用域的this,不是调用时的this
箭头函数的this永远指向其父作用域,任何办法都扭转不了,包含call,apply,bind。
一般函数的this指向调用它的那个对象。
let person = { name:'jike', init:function(){ //为body增加一个点击事件,看看这个点击后的this属性有什么不同 document.body.onclick = ()=>{ alert(this.name);//?? this在浏览器默认是调用时的对象,可变的? } }}person.init();
上例中,init是function,以person.init调用,其外部this就是person自身,而onclick回调是箭头函数,
其外部的this,就是父作用域的this,就是person,能失去name。
let person = { name:'jike', init:()=>{ //为body增加一个点击事件,看看这个点击后的this属性有什么不同 document.body.onclick = ()=>{ alert(this.name);//?? this在浏览器默认是调用时的对象,可变的? } }}person.init();
上例中,init为箭头函数,其外部的this为全局window,onclick的this也就是init函数的this,也是window,
失去的this.name就为undefined。
(2). 箭头函数不能作为构造函数,不能应用new
//构造函数如下:function Person(p){ this.name = p.name;}//如果用箭头函数作为构造函数,则如下var Person = (p) => { this.name = p.name;}
因为this必须是对象实例,而箭头函数是没有实例的,此处的this指向别处,不能产生person实例,自圆其说。
(3). 箭头函数没有arguments,caller,callee
箭头函数自身没有arguments,如果箭头函数在一个function外部,它会将内部函数的arguments拿过去应用。
箭头函数中要想接管不定参数,应该应用rest参数...解决。
let B = (b)=>{ console.log(arguments);}B(2,92,32,32); // Uncaught ReferenceError: arguments is not definedlet C = (...c) => { console.log(c);}C(3,82,32,11323); // [3, 82, 32, 11323]
(4). 箭头函数通过call和apply调用,不会扭转this指向,只会传入参数
let obj2 = { a: 10, b: function(n) { let f = (n) => n + this.a; return f(n); }, c: function(n) { let f = (n) => n + this.a; let m = { a: 20 }; return f.call(m,n); }};console.log(obj2.b(1)); // 11console.log(obj2.c(1)); // 11
(5). 箭头函数没有原型属性
var a = ()=>{ return 1;}function b(){ return 2;}console.log(a.prototype); // undefinedconsole.log(b.prototype); // {constructor: ƒ}
(6). 箭头函数不能作为Generator函数,不能应用yield关键字
(7). 箭头函数返回对象时,要加一个小括号
var func = () => ({ foo: 1 }); //正确var func = () => { foo: 1 }; //谬误
(8). 箭头函数在ES6 class中申明的办法为实例办法,不是原型办法
//deom1class Super{ sayName(){ //do some thing here }}//通过Super.prototype能够拜访到sayName办法,这种模式定义的办法,都是定义在prototype上var a = new Super()var b = new Super()a.sayName === b.sayName //true//所有实例化之后的对象共享prototypy上的sayName办法//demo2class Super{ sayName =()=>{ //do some thing here }}//通过Super.prototype拜访不到sayName办法,该办法没有定义在prototype上var a = new Super()var b = new Super()a.sayName === b.sayName //false//实例化之后的对象各自领有本人的sayName办法,比demo1须要更多的内存空间
因而,在class中尽量少用箭头函数申明办法。
(9). 多重箭头函数就是一个高阶函数,相当于内嵌函数
const add = x => y => y + x;//相当于function add(x){ return function(y){ return y + x; };}
(10). 箭头函数常见谬误
let a = { foo: 1, bar: () => console.log(this.foo)}a.bar() //undefined
bar函数中的this指向父作用域,而a对象没有作用域,因而this不是a,打印后果为undefined
function A() { this.foo = 1}A.prototype.bar = () => console.log(this.foo)let a = new A()a.bar() //undefined
原型上应用箭头函数,this指向是其父作用域,并不是对象a,因而得不到预期后果
一般函数和箭头函数区别?
//箭头函数let fun = () => { console.log('lalalala');}//一般函数function fun() { console.log('lalla');}
应用箭头函数应留神什么?
(1)用了箭头函数,this就不是指向window,而是父级(指向是可变的)(2)不可能应用arguments对象(3)不能用作构造函数,这就是说不可能应用new命令,否则会抛出一个谬误(4)不能够应用yield命令,因而箭头函数不能用作 Generator 函数
对于then()办法的了解
then()只有在Promise对象中才有。
1.then()办法是异步执行
2.意思是:就是当then()前的办法执行实现后在执行then()外部的程序,这样就防止了,数据没获取到等的问题。
3.语法:promise.then(onCompleted,onRejected);
4.参数
1.必须。(promise) Promise对象2.必须。(onCompleted) 承诺胜利实现时要运行的履行处理程序函数3.可选。(onRejected) 承诺被回绝时要运行的谬误处理程序函数
promise原理实现
1、最简略的实现
基于下面的利用场景发现promise能够又三种状态,别离是pedding、Fulfilled、Rejected.
pedding Promise对象实例创立时候的初始状态Fulfilled能够了解为胜利的状态Rejected能够了解为失败的装填
Promise.all能够将多个Promise实例包装成一个新的Promise实例。同时,胜利和失败的返回值是不同的,胜利的时候返回的是一个后果数组,而失败的时候则返回最先被reject失败状态的值。
具体代码如下:
let p1 = new Promise((resolve,reject)=>{ resolve('胜利了')})let p2 = new Promise((resolve,reject)=>{ resolve('success')}) let p3 = Promise.reject('失败')Promise.all([p1,p2]).then((result)=>{ console.log(result) //['胜利了','success']}).catch((error)=>{ console.log(error)})Promise.all([p1,p3,p2]).then((result)=>{ console.log(result) }).catch((error)=>{ console.log(error) //失败了,打出'失败'})
Promise.all在解决多个异步解决时十分有用,比如说一个页面上须要等两个或多个ajax的数据回来当前才失常显示,在此之前只显示loading图标。