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创建对象的方法:
法1: var obj1 = {};
法2: var obj2 = new Object();
法3: function fn(){ }; var obj3 = new fn();
法4: var 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