js面试

防抖

避免短时间内重复调用一个函数
设置一个定时器
最小时间间隔
在这个事件间隔内,连续触发该事件
只执行一次
比如:定时器200mm一次;触发一次等待两百毫秒才会触发,如果在两百毫秒内再次触发,就清除这个定时器,重新开启一个定时器

节流

发送ajax请求,只要第一次响应没回来,就不执行第二次
解决:设置一个开关,默认为true
执行时变为false
请求回来了,打开开关

浏览器同源策略(CORS)

浏览器禁止ajax使用其他服务器来源的数据
浏览器会检查ajax请求从服务器端获取的数据的响应头
如果响应头中的来源地址和当前网页所在的地址域名不一致,就报错
只有响应头中的来源地址和当前网页所在的地址相同,才允许使用该数据

数据类型

判断难点:null undefine NaN 数组,对象
undefine底层会变为null,
NaN是不等于NaN的
数组,对象 typeof都是[Object,Object]

解决: null undefine用===
NaN:用isNaN
数组 isArray() es5
原生: Object.prototype.toString.call(a)
或: {}..toString.call(a)

字符串次数

var arr="455540545dfs4asfsdlfkhanwougityeadgfbiaeswttdrwVBDSGYUAWESFSADRFSSDF";
 var obj={};
 var max=0;
 for(var item in arr){
     //console.log(arr[item]);
  if(obj[arr[item]]==undefined){
   obj[arr[item]]=1;
  }else{
      console.log(obj[arr[item]]);
    obj[arr[item]]++;
  }
  if(obj[arr[item]]>max){
    max=obj[arr[item]];
  }
 }
 console.log(obj,max)

数组去重

//方法一根据过滤器当下标和值的indexof(下标)相同就过滤出来
  var arr=[11,22,5654,11,22,3,145,2,145,2,3,"i","p","o","o","p","i","p"];
  console.log(
  arr.filter((item, index)=> {
        return arr.indexOf(item) === index
    })
  )
  //方法二双重for循环,第一个与第一个之后的比较,相等就splice出去,但会改变数组长度,需要内层循环减一,数组长度减一
var arr1=[11,22,5654,11,22,3,145,2,145,2,3,"i","p","o","o","p","i","p"];
    for(var i=0; i<arr1.length;i++){
      for(var j=i+1;j<arr1.length;j++){
         if(arr1[i]==arr1[j]){
           arr1.splice(j,1);
           j--;
         }
      }
    }
    console.log(arr1);
//3. includes(a)检测是否包含a
//创建一个空数组,判断空数组中有没有外层遍历的数组值,有就跳过,没有就加进来
var arr2=[11,22,5654,11,22,3,145,2,145,2,3,"i","p","o","o","p","i","p"];
var newArr=[];
for(var item of arr2){
  //!newArr.includes(item)&&newArr.push(item);
  //可用indexOf代替includes
  if(newArr.indexOf(item)==-1){
   newArr.push(item)
  }
}
console.log(newArr);
//4. 用sort排序,之后比较身边值
var arr3=[11,22,5654,11,11,11,22,3,145,2,145,2,3,"i","p","o","o","p","i","p"];
    arr3 = arr3.sort()
    //[2,2,3,3,11,11,22,22,145,145]
    let result = [arr3[0]]//[2]
    for (let i=1, len=arr3.length; i<len; i++) {
        //[11]!==[3]
        if( arr3[i] !== arr3[i-1]){
          result.push(arr3[i])//[2,3,11]
        }
    }
console.log(result);
//5.new Set es6新增,成员具有唯一性
var arr4=[11,22,5654,11,11,11,22,3,145,2,145,2,3,"i","p","o","o","p","i","p"];
console.log(new Set(arr4))
//6.利用对象属性具有唯一性
var arr5=[11,22,5654,11,11,11,22,3,145,2,145,2,3,"i","p","o","o","p","i","p"];
var obj={};
var re=[];
for(var item of arr5){
  if(!obj[item]){
    re.push(item);
    obj[item]=1;
  }
}
console.log(re);

数组回文

var a=prompt("请输入一串数字加字母");
    a=a.split("");
    console.log(a)
    var sum=0;
    var len=Math.floor(a.length/2);
    console.log(len)
      for(var i=0;i<len;i++){
        if(a[i]==a[a.length-1-i]){
          sum+=1;
        }
    }
    console.log("sum="+sum)
    if(sum==len){
      console.log("回文数组")
      }

将Url转对象

function parseUrl(url){
  var reg=/(\w+):\/\/([\w\.-]+)((\/\w+)+)\?([^#]+)#(\w+)/;
  //之所以上边正则,每一部分都用()分隔开,是因为想用match的获取子字符串的功能。match在匹配时,不但会匹配完整的字符串,而且正则中每个()的子内容也会分别匹配出来。
  var arr=url.match(reg);
  var obj={};
  obj.protocol=arr[1];
  obj.host=arr[2];
  obj.pathname=arr[3];
  obj.hash=arr[arr.length-1];
  var search=arr[arr.length-2];
  //参数部分先按&切割
  arr2=search.split("&");
  //先给结果对象添加专门保存参数值的params属性,值也是一个空格对象
  obj.params={}
  //遍历用&切割后的每段子字符串
  for(var str of arr2){
    //每遍历一段子字符串,就用=切割
    var arr=str.split("=");
    //切割后的第一部分作为属性名,第二部分作为属性值
    var key=arr[0], value=arr[1];
    //如果obj.params内已经有了当前属性,则将当前属性值和新属性值拼接为一个数组,用concat
    if(obj.params[key]!==undefined){
      obj.params[key]=[].concat(obj.params[key],value);
    }else{//否则如果没有改属性名才强行添加到obj的params对象属性内
      obj.params[key]=value;
    }
  }
  return obj;
}

判断是否是数组

1. 找爹   obj.__ptoty__==array.Prtotype
       Object.getPrototypeOf(obj)==array.Prtotype
       array.prototype.isprototypeOf(obj)
2. 找妈  obj.constructor==array
 obj instanceof array
3.class基因
Object.prototype.toString.call(obj);
4. es5判断
Array.isArray(obj);

数组降维

二维数组降维
arr=[].concat(...arr)
多维数组降维

function fun(arr){
    //先降一次维
    arr=[].concat(...arr);
    //再检查降维后的数组中是否还包含子数组
    var hasArray=arr.some(function(elem){
        return Array.isArray(elem);
    })
    if(hasArray){ //如果包含子数组
       arr=fun(arr);//就只能再降维一次,直到检查不再包含子数组为止
    }
    return arr
}

两个变量,交换值

  • 只能交换数字值
    a+=b, b=a-b, a-=b
    a^=b, b^=a, a^=b
  • 任意
    a=[b,b=a][0]
    [a,b]=[b,a]

实现浏览器多个标签页之间的通讯

  1. cookie+setinterval
发送方
document.cookie="msg="+d1.value;
接收方
setinterval(()=>{
d1.innerHTML="document.cookie"
},500)

问题:cookie有大小限制,发送服务器会带一些不需要的东西,定时器不好
优点是无兼容性问题

  1. localStorage
发送方
localStorage.setItem("msg", d1.value.trim());
接收方
window.addEventListener("storage", () => {
            msg.innerHTML = localStorage.getItem("msg");
        })

localStorage内容一旦改变,无论那个页面,都会触发storage事件
问题:h5的内容,有兼容性问题

  1. webStroket

看h5去
缺点:需要后端配合

  1. sharedWorker
    worker.js
let data="";//在所有shareworker共享的worker.js中,保存一个data变量,存储多个worker共享数据
onconnect=function(e){//必须提供一个名为onconnect事件处理函数
    //每当一个页面new shareworker("worker.js")时
    //就会为新建的worker绑定onconnect事件处理函数
  var port=e.ports[0]; //获得当前连接上了的客户端对象
  port.onmessage=function(e){//当当前对象收到消息时
     
   if(e.data===""){//如果消息为空,说明向获得消息
     port.postMessage(data);
   }else{//消息不为空,说明想将消息放在data中让别人取
     data=e.data;
   }
  }
}

发送

var worker=new SharedWorker("worker.js");
    worker.port.start();
    send.onclick=function(){
      if(msg.value.trim()!==""){
        worker.port.postMessage(msg.value.trim())
      }
    }

接收

 var worker = new SharedWorker("worker.js");
        //2.当worker.js中给客户端返回了data会自动触发当前客户端的message事件,data值会自动保存进事件对象e的data属性中
        worker.port.addEventListener("message", function(e) {
            rec.innerHTML = e.data;
        }, false)
        worker.port.start();
        //1.接收端反复想共享的worker.js对象发送消息,意味想获取data的值
        setInterval(function() {
            worker.port.postMessage("");
            //只要发送消息,就触发worker.js中的onmessage
        })

the-Node-js-event-loop.png

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,997评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,603评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,359评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,309评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,346评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,258评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,122评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,970评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,403评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,596评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,769评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,464评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,075评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,705评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,848评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,831评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,678评论 2 354

推荐阅读更多精彩内容

  • FEGuideTeam/FEGuide 一份涵盖大部分前端工程师所需要掌握的核心知识。这个项目就是为了帮助那些找工...
    acc8226阅读 838评论 0 6
  • 1.typeof是用来干什么的?typeof可以判断所有的值类型可以判断函数但是所有的引用类型返回的都是objec...
    懵逼猫9527阅读 261评论 0 1
  • 目录 闭包 类的继承与创建[https://www.jianshu.com/p/5ce78ff4bc9d] 如何解...
    Grandperhaps阅读 1,149评论 2 30
  • 1.什么是闭包?举例说明从作用域链谈闭包闭包就是能够读取其他函数内部变量的函数,闭包实现累加效果 function...
    大佬_娜阅读 565评论 0 0
  • 1.事件循环 2.闭包 3.ES6/ES7新特性 4.ajax: 5.防抖节流: 闭包实现函数去抖和节流去抖使用s...
    清欢_4869阅读 377评论 0 0