数组去重的几种方法、浅析事件委托

  这段时间我也面了几次,也看了数不胜数的面经,然而面经也只能起到辅助的作用(在看的时候难免会出现眼高手低的情况),我就栽了几次了????,所以建议大家在准备的时候一定要多动手联系啊。。。
  我准备了几道高频题(我自己经历),我会分几次博客来分享…

数组去重

  这道题我遇到过几次吧算是,之前老是和数组深拷贝弄混淆,我要记录下来。

1、ES6的Set()

//set可以去掉字符串、数值、布尔、undefined、null、NaN
//es6中Set内部利用算法 “Same-value-zero equality”,类似于“===”,不同的是NaN===NaN =>true

let arr = [1,2,5,6,51,4,21,1,2];
let set = new Set(arr);
console.log(Array.from(set));   //[1, 2, 5, 6, 51, 4, 21]

2、利用indexOf+新数组

function unique(arr){
    let res = [];
    res[0] = arr[0];
    for(let i = 1;i<arr.length;i++){
        if(res.indexOf(arr[i])==-1){
            res.push(arr[i])
        }
    }
    return res;
}
let arr = [1,'1',4,null,null,'1',4,undefined,undefined];
console.log(unique(arr))  //[1, "1", 4, null, undefined] 不能去掉NaN

3、利用对象键值不重复(不推荐)

function unique(arr){
    let res = [];
    let obj = {};
    for(let i = 0;i<arr.length;i++){
        if(!obj[arr[i]]){   //漏洞
            obj[arr[i]] = true;
            res.push(arr[i])
        }
    }
    return res;
}
let arr = [1,2,3,'1','2','3']  //[1,2,3]
// let arr = [1,'1',4,null,null,'1',4,undefined,undefined,NaN,NaN];
console.log(unique(arr))

  不推荐的原因:经过我的测试发现,if(!obj[arr[i]]){}判断的时候,会把字符串和数值当成同一种键存到对象里面,这种方法无法判断字符串和数值(知道解决方法的留言哦????)

4、终极版本

function unique(arr) {
    const result = [];
    result[0] = arr[0];
    for (let i = 1; i < arr.length; i++) {
       if (isAdd(result, arr[i])) {  result.push(arr[i])  }
    }
    return result;
 }
 function isAdd(result, val) {    //判断是否可以添加到新数组中
    for (let value of result) {  //遍历新数组
         if (isEqual(value, val))  return false;  
    }
    return true;
 }
 function isEqual(val1, val2) {  //判断当前元素是否存在与新数组中
    let type1 = typeof val1;
    let type2 = typeof val2;
    if (type1 !== type2) return false;
    if (type1 !== 'object') return val1 === val2;
    for (let key of Object.keys(val1)) {  //判断数组和对象类型
        if (!val2[key])  return false;
        if(!isEqual(val1[key], val2[key]))  return false;  //递归调用去判断子元素
    }
    return true;
 }

let arr = [1,'1',4,{"a":1},{"a":1},[1],[1],undefined,NaN,NaN];
console.log(unique(arr)) //[1, "1", 4, {…}, Array(1), undefined, NaN, NaN]

  一、NaN!==NaN;typeof NaN ‘number’,如果想判断NaNNaN可以使用Number.isNaN(),使用这个方法会判断NaN是否相等(不包括字符串)
  二、存在null时候会报错,因为typeof null == ‘object’,进行判断的时候不符合上面的条件,最后条件判断的时候就会出错。

事件委托

  也称为事件代理,将事件绑定到目标元素的父元素上,利用事件冒泡机制,给父元素监听事件,通过event.target来判断目标元素。这样做的好处既可以减少事件的注册数量、节约内存空间,还可以让新加的元素拥有方法。

简约版本

    <ul id="ul">
        <li>111</li>
        <li>222</li>
        <li>333</li>
    </ul>
    
 //js
    var ul = document.getElementById('ul');
	ul.addEventListener('click',function(e){
	    if(e.target.tagName=='LI'){  //获取的标签都是大写,也可以转小写再判断
	        console.log(e.target.innerText)
	    }
	},false)  //利用冒泡

  通过绑定到外层的父元素点击事件,当你点击 ‘li’ 的时候由于冒泡原理,会向上触发,刚好父元素 ul 有点击事件,则触发onclick事件,打印内容。

新加元素也可以拥有事件

	ul.addEventListener('click',function(e){
			、、、
	},false)
	
	//按钮点击添加事件
   var lis = ul.getElementsByTagName('li');
   var btn = document.getElementById('btn');
	btn.onclick = function(){
	    var li = document.createElement('li');
	    li.innerText = Number(lis[lis.length-1].innerText)+111;  //添加内容
	    lis.length++;
	    ul.appendChild(li);
	}

数组去重的几种方法、浅析事件委托
今天就先讲这两个题,可以继续关注我的博客哦!????
说几道昨天晚上做腾讯的笔试题,挺难的。

还是关于数组

let arr = [0,1,2,3,4,5,6,7,8,9];
arr.forEach((_,index)=>index%2===0&&arr.splice(index,1));
想想结果…


1、首先要清楚,forEach()这个方法是会改变原数组滴,面试中也会经常问道 map和forEach区别, 理解到了会改变原数组就好理解啦!!!

下标为0:0 % 2 === 0,先删除第一个元素,数组变成[1,2,3,4,5,6,7,8,9]
下标从1开始:1=>2,2=>3,删除第三个元素,数组为[1,2,4,5,6,7,8,9]
下标从3开始:3=>5,4=>6,删除元素,数组为[1,2,4,5,7,8,9]
依次循环,最后数组变为[1,2,4,5,7,8]

2、{}+[] === 0

{}语句优先,被当作空,{}在右边的时候,当作表达式
{}为空,[]调用其valueOf会转为 "",然后转为0,所以结果为0
[]+{} => [object,Object]

有不对的地方欢迎大家指出,我们共同进步。