美文网首页
Set集合,Map集合,Symbol,Promises

Set集合,Map集合,Symbol,Promises

作者: 白雪公主960 | 来源:发表于2018-07-04 16:01 被阅读6次

2017-08-22-day08

Set 集合:

  • 什么是: 值不允许重复的集合。专门用于按元素值,直接判断集合中是否存在指定元素
  • 何时: 快速去重复(通过元素值,快速判断是否包含元素时)
  • 如何使用:
var set=new Set(凡是可遍历的,都可打散转为Set)
 将set转回数组: var arr=[...set];//散播

下面是一个简单的例子

var arr=[1,2,3,2,1];
var set=new Set(arr);
console.log(set);//将数组转为Set类型
arr=[...set];
console.log(arr);//将Set类型转为数组

以下是一个经典笔试题,数组去重复,且考虑百万数量级的情况下有什么方法效率高,repeat1是最笨的实现方式,indexOf底层是for循环的方式,repeat2是用Set类型来实现的,底层是哈希实现方式,下面用过打印执行时间来观察。在执行函数前加console.time,执行函数后加console.timeEnd可以打印出该程序的执行时间。

for(var i=0,arr=[];i<1000000;i++){
  arr[i]=parseInt(Math.random()*1000+9000)
}

function repeat1(arr){
  var res=[];
  for(var i=0;i<arr.length;i++){
    if(res.indexOf(arr[i])==-1)
      res.push(arr[i]);
  }
  return res;
}
function repeat2(arr){
  var set=new Set(arr);
  return [...set];
}

以下是另一种实现方法,结果巨快的。这是一种最好的数组去重的方法。这种答案最好。

function repeat3(arr){
  var res=[];
  var hash={};
  for(var i=0;i<arr.length;i++){
    if(hash[arr[i]]===undefined){
      hash[arr[i]]=1;
      res.push(arr[i]);
    }
  }
  return res;
}

左1是要被去重的数组,左2是一个哈希数组(也可以理解为对象)它是用来筛选数组的,右1是最终结果,将左1的值在对象的key值中是undefined,那么就给它定义并赋值1,不是1也可以这个随意。只是要让它存在而已。后面的自行理解。


  • Set集合的其他方法:
    1)set.size 获取集合中元素的个数
    2)set.has(value)判断集合中是否包含指定元素
    3)set.add(value)添加元素,如果已经存在,则无效
    4)set.delete(value)删除元素
    5)set.clear()清空集合

Map 集合:

  • 什么是: 一组键值对的集合(实际上就是关联数组或对象的一种封装)
  • 何时: 代替关联数组(对象)使用
    如何:
var hash=new Map(); //相当于新建对象{}
      hash.set(key,value); //相当于给对象赋值hash[key]=value
      var bool=hash.has(key); //相当于判断对象值是否存在hash[key]!==undefined
  • Map集合的其他API
    map.size 获得map中键值对的个数
    map.has(key)查询一个key是否存在
    map.get(key)获得指定键对应的值
    map.set(key,value)添加一个新的键值对,如果key已经存在,则不会重复添加
    map.delete(key)删除指定key对应的键值对
    map.keys()获取map中所有的key的集合
    map.values()获取map中所有的value的集合

将上面百万级别数组去重的问题用map的方式改写一遍,结果如下,速度还可以,和set差不多,但是没有hash快,那个最好。

function repeat3(arr){
  var res=[];
  var hash=new Map();
  for(var i=0;i<arr.length;i++){
    if(!hash.has(arr[i])){
      hash.set(arr[i],1);
      res.push(arr[i]);
    }
  }
  return res;
}

for of : 代替for循环遍历

  • 什么是: 依次获得数组/类数组对象/集合中每个值
  • 何时: 只要不关心位置,只关心每个元素值时
  • 如何:
for(var value of 数组|类数组对象|集合){
        value: 自动获得当前元素值
      }

以下是一个简单的遍历对象数组的例子

let array = [{"a": 1}, {"b": 2}, {"c":3}];
for (let obj of array) {
  console.log(obj);
}

问题:
1). 无法获得位置
2). 必须从头到尾,逐个执行,不能跳跃或遍历部分
3). 只能从头到尾,顺序遍历,不能反向遍历

Symbol类型(用的少)

  • ES6中,为了获得一个不与对象中现有任何属性冲突的唯一属性,定义了Symbol类型
  • Symbol是第六大原始类型
  • Symbol的值必须通过Symbol函数获的
  • Symbol的值作为属性名时,不能用.访问,只能用[]访问。
    以下是一个例子,点击一下按钮就让小方块右移一段距离,图片正在移动时再点击无效,html中
<button id="btn_right">右移一次</button>
<div id="pop"></div>

css中

div{
  width:100px; height:100px;
  background:red;
  position:fixed;
  top:100px; left:0;
  transition:all 2s linear;
}

js中

function moveRight(elem,dist){
  var left=
    parseFloat(getComputedStyle(elem).left);
  left+=dist;
  elem.style.left=left+"px";
}

var isMoving=Symbol("isMoving");
console.dir(isMoving);
pop[isMoving]=false;
btn_right.onclick=function(){
  if(pop[isMoving]==false){
    pop[isMoving]=true;
    moveRight(pop,100);
    setTimeout(()=>pop[isMoving]=false,2000);
  }
}
pop.isMoving=false;
image.png

****Promises(重点掌握)

  • 什么是: 解决"callback hell"(回调地狱)
  • 为什么: 回调函数,层级很可能很深,可读性极差
  • 何时: 今后,只要多个回调函数,必须保证顺序执行时
    我先写了这样的3个函数,callback指的是回调函数,下一个任务必须要在上一个任务完成之后才可以执行,这种必须得用回调函数来做。如果把callback()直接放在第一个任务中的话,它不会等3秒,而会直接执行,只有放在setTimeOut中才会等3秒再执行。
function conn(callback){
  console.log("连接数据库...");
  //3秒后自动调用callback
  setTimeout(callback,3000);
}
function query(callback){
  console.log("查询数据...");
  setTimeout(callback,5000);
}
function response(callback){
  console.log("返回响应...");
  setTimeout(callback,2000);
}

如何让这3个函数串起来顺序执行呢,执行conn并在它的参数中传一个匿名函数,匿名函数中调用query(),依次类推。只有这样写才会先执行conn,等3秒后执行query,等5秒后执行response,等2秒后打印查询出结果。

//callback hell
conn(function(){
  query(function(){
    response(function(){
      console.log("查询出结果!");
    })
  })
});

但是上面的写法很难看一直往下陷,像一个大坑。称之为回调地狱。

  • 如何使用Promise: 2步:

1). 在前一个函数内

return new Promise((callback)=>{
  ... callback() ...
})

2). 在调用前一个函数时,

前一个函数.then(()=>{ 后一个函数(); })

下面我们将上面的那个例子改为promise的形式,它可以将不确定层级的函数抹平成一级。.then的作用不是调用的意思,它是把后面的参数给Promise对象。这里的callback在后面的介绍中相当于resolve函数。

function conn(){
  console.log("连接数据库...");
  return new Promise((callback)=>{
    setTimeout(callback,3000);
  });
}
function query(){
  console.log("查询数据...");
  return new Promise((callback)=>{
    setTimeout(callback,5000);
  });
}
function response(){
  console.log("返回响应...");
  return new Promise((callback)=>{
    setTimeout(callback,2000);
  })
}

conn()//往下调用的时候是平级的
  .then(()=>query())
  .then(()=>response())
  .then(()=>console.log("查询出结果"))
Promise可以接受2参数来进行错误处理: 分2步

1). 在前一个函数内

 return new Promise(resolve,reject)=>{
       如果没出错,执行resolve
       如果出错,执行reject("错误提示")
 })

2). 在调用前一个函数时,其中.then执行的是resolve的内容,.catch执行的是reject的内容。一旦出错后面调用的函数都不会执行。

前一个函数.then(()=>{ 下一个函数(); }) 
              .catch((err)=>{ 输出err }

将上面的例子模拟出可以出错的样式,用resolve和reject来进行改写,这里在reject中还传了参数以便出错时知道在哪个函数中出错的。

function conn(){
  console.log("连接数据库...");
  return new Promise((resolve,reject)=>{
                    //.then   .catch
    setTimeout(()=>{
      var err=Math.random()<0.3?true:false;
      if(!err)
        resolve();
      else
        reject("连接出错");
    },3000);
  });
}
function query(){
  console.log("查询数据...");
  return new Promise((resolve,reject)=>{
    setTimeout(()=>{
      var err=Math.random()<0.3?true:false;
      if(!err)
        resolve();
      else
        reject("查询出错");
    },5000);
  });
}
function response(){
  console.log("返回响应...");
  return new Promise((resolve,reject)=>{
    setTimeout(()=>{
      var err=Math.random()<0.3?true:false;
      if(!err)
        resolve();
      else
        reject("响应出错");
    },2000);
  })
}
conn()
  .then(()=>query())
  .then(()=>response())
  .then(()=>console.log("查询出结果"))
  .catch((err)=>console.log(err))

很多情况一些框架都支持promise,都不需要开发者去写return promise这段代码,只要会使用.then和。catch的用法即可。

相关文章

网友评论

      本文标题:Set集合,Map集合,Symbol,Promises

      本文链接:https://www.haomeiwen.com/subject/rpxeuftx.html