常用数组/对象/深拷贝

120 阅读4分钟

1.数组去重:ES5,ES6

var arr = [5,"5",5,6,7,6] //要求:去重,且不同类型的5也算重复
//思考: 
var objTest ={5:1,"5":2}; 
console.log(objTest);//会发现后者覆盖前者,也就是对象不同类型同数据只算一次。
//ES5方法:借用obj
unArr(arr);
function unArr(arr){ 
 var newArr = []; obj = {}; 
 for(var i=0;i<arr.length;i++){
  if(!obj[arr[i]]){ 
   obj[arr[i]] = true;
   newArr.push(arr[i]); 
  } 
 } 
console.log(newArr); //[5 6 7] }

//ES6方法: 
var arr2 = new Set(arr); //{5,'5',6,7} //弊端:不同类型的同值不能去重;

2深/浅 拷贝方法!

*浅拷贝: 拷贝【对象属性】,一个改变互相影响
//1)数组浅拷贝:
    var arr1=[1,2,3]; var arr2=arr1; 
//2)对象浅拷贝: es6
   var obj1={age:18,arr:['1','2','3']}; 
   var obj2 = Object.assign({},obj1);
//思考
    var obj1={ age:18, arr:['1','2','3']}; 
    var obj2={}; 
    for(var k in obj1){//此方式可循环对象,k属性名,obj1[k]属性值 
       obj2[k]=obj1[k] 
    }; 
    obj1.age=20; //输出obj2.age,未随之变化,还是18;【正常】
    obj1.arr[0]="aaa";//输出obj2.arr,发现也被改变了;【弊端暴露】  
//【发现:循环拷贝靠谱! 所以后面:只要依次递归就可实现深拷贝啦!】  
//*注意:如果不循环,直接赋值obj2=obj1,那上面的验证全部会随之改变【暴露弊端】    

*深拷贝: 拷贝【源对象】//用递归解决对象(的内部的数组/对象)赋值弊端
var obj1 = {age:18,arr:['1','2','3']}; 
var obj2={}; 
function copy(obj1,obj2){ 
 for(var k in obj1){ 
  if(typeof obj1[k]!='object'){ //[],{}==>typeof都是object
      obj2[k] = obj1[k]; //正常copy赋值 
  }else{ 
      obj2[k] = Array.isArray(obj1[k])?[]:{};
      copy(obj1[k],obj2[k]); //递归 
  } 
 } 
 return obj2;
} 
var obj2 = copy(obj1,obj2); console.log(obj2); //拷贝成功
//修改原数据值验证: 
obj1.arr[0]="aaa"; 
console.log(obj1,obj2); //发现obj2未随着obj1变化而变化。

3常见的数组方法:

function Foo(){ 
 var i = 0; 
 return function (){ console.log(i++);} 
} 
var f1=Foo(); var f2=Foo(); 
f1();f1();f2();//0 1 0 //先输出i,再++  // f1/f2互不干扰;

var a1=[1,12,2]; var a2=[4,13];var a3=['a','A','B']; 
a1.concat(a2);//a1不变;因为concat不会影响原数组; 
a3.sort();//['A','B','a'] //大写<小写的ASCII码; 
a1.sort();//[1,12,2]//sort会按字符串比较,12个位数<2; 
a1.sort(function(a,b){return a-b}); //[1,2,12] 数字排序正确写法; 
a1.reverse();//数组反序

//判断是否为数组: 
var a=[];var b={}; 
//法1:
console.log(a instanceof Array); //true 
//法2:
console.log(a.constructor==Array);//true
//法3:
console.log(Array.isArray(a)); //true

push后加  unshift前加 
pop前删   shift后删 
find 第一个满足条件的值 
slice splice

4 dom操作:

 创建,查找节点:  createElement getElementById

 添加 , 移除:     appendChild   removeChild

 替换, 复制:     replaceChild   clone

5 1)阻止冒泡和默认行为:

父子div标签都有点击事件,但点击子,子+父标签两者都会被执行;【事件冒泡】【从下往上]
解决:@click.stop

2)事件委托/代理:【事件委托原理:就是利用dom元素的冒泡行为】

问题:ull>li,每个子li 都需要加事件,太繁琐;且后续动态添加的 li 无法自动绑定子事件;
解决:在ul父元素加事件即可@click='handleClick'
    handleClick(e){ console.log(e.target) } //target是鼠标点击的直接dom元素

6 js延迟加载: 等页面加载完成后再加载js文件,有助于提高页面加载速度。

//1) defer: 
<script src="test1.js" defer="defer"></script> 
//2) async: 
<script src="test1.js" async></script> 
//3) setTimeout(); 
//4) 外部引入的文件放到页面底部,来让js最后引入

7 严格模式

"use strict"  //严格模式:解决一些js的怪癖不严谨

var a=10;var a=20//严格模式下会报错; 
b=10;//未定义,也会报错。
//好处: 检测代码 规范化 压缩时节约文件成本
//坏处:报错 阻塞后面代码运行 压缩时有可能会出现错误

8创建对象的方法:

1var obj1 = {};

法2var obj2 = new Object();

法3function fn(){ };  var obj3 = new fn();

法4var obj4 = Object.create(Array.prototype);

9将url 解析为一个对象:

 var url = "http://baidu.cn/index.html?key0=0&key1=1&key2=2"; 
 parseUrl(url);
 function parseUrl(url){ 
     var obj = {}; 
     var str1 = url.split("?")[1]; 
     var temp = str1.split("&"); 
     for(let i in temp){ 
         var k = temp[i].split('=')[0]; 
         var tt = temp[i].split('=')[1]; 
         obj[k]=tt; 
     } 
     obj['head']=url.split("?")[0]; 
     console.log(obj); //{key0: '0', key1: '1', key2: '2', head: 'http://baidu.cn/index.html'} 
 }

10 字符串中出现次数最多的字符

var str = "aaabbbcccaaabbccccc"; 
function test(str){ 
    var obj={}; 
    for(let i in str){ 
        if(obj[str[i]]){ 
            obj[str[i]]++; 
        }else{ 
            obj[str[i]]=1; 
        }
    } 
    return obj; 
 }; 
 var obj1 = test(str); console.log(obj1); //{a: 6, b: 5, c: 8}

var max = 0;  var maxS = ''; 
for(let i in obj1){ 
    if(obj1[i]>max){ 
        max = obj1[i]; 
        maxS=i;
    } 
} 
console.log("字符:"+maxS+",次数"+max); //字符:c,次数8

11 对象的key:

//数组作为obj2属性名:当数组相同时==>后者赋值会覆盖前者;不同时==>保留两者; 
    var arr =[1,2,3]; var brr = [4,5,6]; var crr=[4,5,6]; 
    var obj={};var obj2={}; 
    obj[arr]='aaa'; obj[brr]='bbb'; 
    console.log(obj); //{1,2,3:'aaa',4,5,6:'bbb'};
    obj2[brr]='aa'; obj2[crr]='bb'; 
    console.log(obj2);//{4,5,6:'bb'}//同属性会覆盖

//对象作为obj3属性名:均后者直接覆盖前者;==>与对象内容无关 
     var A={name:"张三"}; var B ={name:"李四"}; var C ={age:"18"};
     var obj3 = {}; 
     obj3[A]='11'; obj3[B]='22'; 
     console.log(obj3); //{[object Object]: '22'} //后者直接覆盖前者
     obj3[C]='33';
     console.log(obj3,obj3[A]); //{[object Object]:'33'},'33'
     
    var a = {};  var b={key:'a'};  var c ={key:'c'}; 
    a[b]='123';  a[c]='456'; 
    console.log(a,a[b]); //{[object Object]: '456'},456     

12 cookie / localStorage / sessionStorage 区别:

1) 存储大小: cookie不能超过4k 只能保存字符串类型,其他5M+; 
2) 有效期: cookie可设置生命周期; 
   //例》this.$cookie.set('token', token, 1); //过期时间1天 
   localStorage一直存在,可手动清除; 
   //localStroge设置失效时间:存一下当前时间,getItem获取到后计算时间,过期的话remove;
   sessionStorage关闭页面/浏览器清除; 
3)作用域: sessionStorage只在当前页面有效;页面之间不共享; 
4)均是浏览器存储。

13 离下一年还剩多少“天时分秒”:【倒计时】

setInterval(isDate,1000); 
function isDate(){ 
    var date1 = new Date(); 
    var year = date1.getFullYear();//当前年 
    var date2 = new Date(); date2.setFullYear(year+1); //年+1 
    date2.setMonth(0,1); //1月1日 
    date2.setHours(0,0,0); //0时0分0秒 
    console.log(date2); 
    var isTime =date2.getTime()-date1.getTime(); //时间戳 差值ms 
    //转化格式 
    var isSecond = parseInt(isTime/1000);//差值s 取整 
    var d = parseInt(isSecond/24/60/60);//天 
    var aa = isSecond%(24*60*60); //天的余数 单位是s 
    var h = parseInt(aa/60/60);//时 
    var bb = aa%(60*60);//时的余数 单位是s 
    var m = parseInt(bb/60); //分 
    var cc = bb%60; //秒 var 
    s= parseInt(cc); 
    console.log("距离"+date1.getFullYear()+'剩余'+d+'天'+h+'时'+m+'分'+s+'秒'); }

14 获取对象属性值

 var obj = {attr:1}
 console.log(obj.attr); 
 console.log(obj['attr']);
 
 //对象合并方法: 
 let a = {a1:1}; let b ={a2:2}; 
 let obj = Object.assign(a,b); //{a1: 1, a2: 2}

15 Object.assign(target, ...sources) 对象合并/浅拷贝。

参数:target--->目标对象
     source--->源对象
 var a = {a1:1}; var b ={a2:2}; 
 var c = {c1:3,age:'33'}; var d = {d1:4,age:'44'} 

 var obj = Object.assign(a,b); //{a1: 1, a2: 2} //对象a也会改变: a==obj,b不变 

 var obj2 = Object.assign({},a,b);//{a1: 1, a2: 2} //对象a不影响: a!=obj2 

 var obj3=Object.assign(c,d);//{c1: 3, age: '44', d1: 4} 相同属性会覆盖//a改变:a==obj3 

 var obj4=Object.assign({},a);//{a1:1} //obj4浅拷贝了a