1. 如何判断一个对象里面的属性值都为空
const applyData = {name:'',age:''}let result = !Object.values(applyData).every(item => item === '');console.log(result) //false
// 获取指定名称的cookie的值const getCookie = (objName) => {var cookies = document.cookie.split('; ')for (var i = 0; i < cookies.length; i++) {var temp = cookies[i].trim().split('=')if (temp[0] === objName) {return temp[1]}}return ''}const setCookie = (name, value, seconds) => {seconds = seconds || 0 // seconds有值就直接赋值,没有为0,这个跟php不一样var expires = ''if (seconds !== 0) {// 设置cookie生存时间var date = new Date()date.setTime(date.getTime() + seconds * 1000)expires = '; expires=' + date.toGMTString()}document.cookie = name + '=' + escape(value) + expires + '; path=/' // 转码并赋值}const clearCookie = (name) => {setCookie(name, '', -1)}const formatTime = (dt) => {var h = dt.getHours()var m = dt.getMinutes()var s = dt.getSeconds()var r = ''if (h > 0) {r += (h > 9 ? h.toString() : '0' + h.toString()) + ':'} else {r += '00' + ':'}r += (m > 9 ? m.toString() : '0' + m.toString()) + ':'r += s > 9 ? s.toString() : '0' + s.toString()return r}const formatMonth = (inputTime) => {var date = new Date(inputTime)var y = date.getFullYear()var m = date.getMonth() + 1m = m < 10 ? '0' + m : mreturn y + '-' + m}const formatDate = (inputTime) => {var date = new Date(inputTime)var y = date.getFullYear()var m = date.getMonth() + 1m = m < 10 ? '0' + m : mvar d = date.getDate()d = d < 10 ? '0' + d : dreturn y + '-' + m + '-' + d}const formatDateTime = (inputTime) => {var date = new Date(inputTime)var y = date.getFullYear()var m = date.getMonth() + 1m = m < 10 ? '0' + m : mvar d = date.getDate()d = d < 10 ? '0' + d : dvar h = date.getHours()h = h < 10 ? '0' + h : hvar minute = date.getMinutes()var second = date.getSeconds()minute = minute < 10 ? '0' + minute : minutesecond = second < 10 ? '0' + second : secondreturn y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second}const formatDateRange = (inputTime) => {var date = new Date(inputTime)var y = date.getFullYear()var m = date.getMonth() + 1m = m < 10 ? '0' + m : mvar start = y + '-' + m + '-01'var lastDay = new Date(y, m, 0)var d = lastDay.getDate()var end = y + '-' + m + '-' + dreturn [start, end]}const capitalize = (str) => {return str.toLowerCase().replace(/( |^)[a-z]/g, (L) => L.toUpperCase())}const monthDiff = (daterange) => {var start = daterange[0]var end = daterange[1]var result = []if (start.split('-')[0] === end.split('-')[0]) {for (var month = start.split('-')[1]; month <= end.split('-')[1]; month++) {result.push({key: month,value: start.split('-')[0] + '-' + month})}} else {for (month = start.split('-')[1]; month <= 12; month++) {result.push({key: month,value: start.split('-')[0] + '-' + month})}for (month = 1; month <= end.split('-')[1]; month++) {result.push({key: String(month),value: end.split('-')[0] + '-' + month})}}return result}// 颜色格式 hex 转 rgbaconst hexToRgba = (bgColor, precent) => {let color = bgColor.slice(1) // 去掉'#'号let rgba = [parseInt('0x' + color.slice(0, 2)),parseInt('0x' + color.slice(2, 4)),parseInt('0x' + color.slice(4, 6)),precent]return 'rgba(' + rgba.toString() + ')'}const getColor = (index, precent) => {if (precent <= 20) precent = 20else if (precent > 20 && precent <= 40) precent = 40else if (precent > 40 && precent <= 60) precent = 60else if (precent > 60 && precent <= 80) precent = 80else precent = 100precent /= 100// ['#FADBCA', '#E17761'], ['#FFFBCC', '#FFEE66'], ['#FDE6CA', '#F69F62'], ['#E1FBF5', '#CFF5F2'], ['#E3E3F3', '#A9A9F6'], ['#EBFCED', '#C0F0D0'], ['#ECF9F8', '#BAD8DB'], ['#F8FCCC', '#E0F266'], ['#F6E0FA', '#D09DE3'], ['#E9FDD6', '#AAF383'], ['#E1FAF0', '#9EE1D4'], ['#FEF9DB', '#FEE894'], ['#FEF8EB', '#FCE3C2'], ['#FDEDD9', '#F8B98C'], ['#FEEECD', '#F9BD69'], ['#FADBCA', '#E17761'], ['#FFFBCC', '#FFEE66'], ['#FDE6CA', '#F69F62']var allColor = ['#fccde2', '#c5e3f6']// return hexToRgba(allColor[index % 18][1], precent)return hexToRgba(allColor[index % 2], precent)}// 对象转化为数组const jsonToArray = (obj) => {let arr = []for (let i in obj) {let o = {}o[i] = obj[i]arr.push(o)}return arr}// 表格相同项进行合并展示const dealRow = (arr, size) => {let flag = {projectId: '',index: 0,length: 1}arr.forEach((item, index) => {if (flag.projectId === item.projectId) {flag.length += 1} else {if (flag.projectId) {arr[flag.index].colspan = 1arr[flag.index].rowspan = flag.lengthfor (let i = 1; i < flag.length; i++) {if ((flag.index + i) % size === 0) {arr[flag.index + i].colspan = 1arr[flag.index + i].rowspan = flag.length - i} else {arr[flag.index + i].colspan = 0arr[flag.index + i].rowspan = 0}}flag.projectId = item.projectIdflag.index = indexflag.length = 1arr[index].colspan = 1arr[index].rowspan = flag.length} else {flag.projectId = item.projectId// 考虑只筛选出一条任务的情况if (arr[flag.index].colspan === 0 || arr[flag.index].rowspan === 0) {arr[flag.index].colspan = 1arr[flag.index].rowspan = flag.length}}}if (index === arr.length - 1 && flag.length > 1) {arr[index - flag.length + 1].colspan = 1arr[index - flag.length + 1].rowspan = flag.lengthfor (let i = 0; i < flag.length - 1; i++) {arr[index - i].colspan = 0arr[index - i].rowspan = 0if ((flag.index + i + 1) % size === 0) {arr[flag.index + i + 1].colspan = 1arr[flag.index + i + 1].rowspan = flag.length - i + 1}}}})return arr}// 在roleMap里查询对应角色的人名 arr为roleMap type为对应角色const getRoleType = (arr, type) => {let result = []for (let i in arr) {if (arr[i] === type) {result.push(i)}}return result}// 遍历叠加const ReduceArray = (arr, name) => {let result = ''if(arr && arr.length) {arr.forEach(item => {result = String(item[name]) + ' '})}return result}// 时间降序排列// const compareTime = (property) => {// return function (obj1, obj2) {// var value1 = new Date(obj1[property].replace(/-/g, '/')).getTime()// var value2 = new Date(obj2[property].replace(/-/g, '/')).getTime()// return value2 - value1 // 降序// }// }// const compareTime = (arr) => {// console.log(arr)// return arr.sort((a, b) => {// return moment(b, 'DD/MM/YYYY').valueOf() - moment(a, 'DD/MM/YYYY').valueOf();// })// }// import moment from "moment"module.exports = {getCookie,setCookie,clearCookie,formatTime,formatMonth,formatDate,formatDateTime,formatDateRange,capitalize,monthDiff,hexToRgba,getColor,jsonToArray,dealRow,getRoleType,ReduceArray,// compareTime}
快速生成日期数组
Array.from({ length: 12 }, (a, i) => {console.log(a)let now = new Date()now = now.setMonth(now.getMonth() - i)now = new Date(now)let index = now.toLocaleString('ja').lastIndexOf('/')return now.toLocaleString('ja').replaceAll('/', '-').slice(0, index)}).reverse(), //横坐标
数组排序
https://www.w3school.com.cn/js/js_array_sort.asp
sort() 方法是最强大的数组方法之一。
var fruits = ["Banana", "Orange", "Apple", "Mango"];fruits.sort(); // 对 fruits 中的元素进行排序
数组对象排序
var cars = [{type:"Volvo", year:2016},{type:"Saab", year:2001},{type:"BMW", year:2010}];cars.sort((a, b) => return a.year - b.year);
属性是字符串:
cars.sort((a, b) => {var x = a.type.toLowerCase();var y = b.type.toLowerCase();if (x < y) {return -1;}if (x > y) {return 1;}return 0;});
//按时间线排序data.sort((a, b) => {var x = a.monthDate.toLowerCase()var y = b.monthDate.toLowerCase()if (x < y) {return -1}if (x > y) {return 1}return 0})
数组去重
https://segmentfault.com/a/1190000016418021
https://segmentfault.com/a/1190000021951088
测试数据
var meta = [0,'0',true,false,'true','false',null,undefined,Infinity,{},[],function(){},{ a: 1, b: 2 },{ b: 2, a: 1 },];var meta2 = [NaN,NaN,Infinity,{},[],function(){},{ a: 1, b: 2 },{ b: 2, a: 1 },];var sourceArr = [...meta, ... Array(1000000).fill({}).map(() => meta[Math.floor(Math.random() * meta.length)]),...meta2];
1.es6最简单的方式
console.time('ES6中Set耗时:');var res = [...new Set(sourceArr)];console.timeEnd('ES6中Set耗时:');// ES6中Set耗时:: 28.736328125msconsole.log(res);// 打印数组长度20: [false, "true", Infinity, true, 0, [], [], {b: 2, a: 1}, {b: 2, a: 1}, {}, {}, "false", "0", null, undefined, {a: 1, b: 2}, {a: 1, b: 2}, NaN, function(){}, function(){}]
配合Array.from
console.time('ES6中Set耗时:');var res = Array.from(new Set(sourceArr));console.timeEnd('ES6中Set耗时:');// ES6中Set耗时:: 28.538818359375msconsole.log(res);// 打印数组长度20:[false, "true", Infinity, true, 0, [], [], {b: 2, a: 1}, {b: 2, a: 1}, {}, {}, "false", "0", null, undefined, {a: 1, b: 2}, {a: 1, b: 2}, NaN, function(){}, function(){}]
优点:简洁方便,可以区分NaN;
缺点:无法识别相同对象和数组;
简单的场景建议使用该方法进行去重。
2. 使用indexOf
function unique(arr) {if (!Array.isArray(arr)) return;var result = [];for (var i = 0; i < arr.length; i++) {if (array.indexOf(arr[i]) === -1) {result.push(arr[i])}}return result;}console.time('indexOf方法耗时:');var res = unique(sourceArr);console.timeEnd('indexOf方法耗时:');// indexOf方法耗时:: 23.376953125msconsole.log(res);// 打印数组长度21: [false, "true", Infinity, true, 0, [], [], {b: 2, a: 1}, {b: 2, a: 1}, {}, {}, "false", "0", null, undefined, {a: 1, b: 2}, {a: 1, b: 2}, NaN,NaN, function(){}, function(){}]
优点:ES5以下常用方法,兼容性高,易于理解;
缺点:无法区分NaN;需要特殊处理;
可以在ES6以下环境使用。
3. 使用inculdes方法
function unique(arr) {if (!Array.isArray(arr)) return;var result = [];for (var i = 0; i < arr.length; i++) {if (!result.includes(arr[i])) {result.push(arr[i])}}return result;}console.time('includes方法耗时:');var res = unique(sourceArr);console.timeEnd('includes方法耗时:');// includes方法耗时:: 32.412841796875msconsole.log(res);// 打印数组长度20:[false, "true", Infinity, true, 0, [], [], {b: 2, a: 1}, {b: 2, a: 1}, {}, {}, "false", "0", null, undefined, {a: 1, b: 2}, {a: 1, b: 2}, NaN, function(){}, function(){}]
优点:可以区分NaN;
缺点:ES版本要求高,和indexOf方法相比耗时较长;
4. 使用filter和indexOf方法
这种方法比较巧妙,通过判断当前的index值和查找到的index是否相等来决定是否过滤元素:
function unique(arr) {if (!Array.isArray(arr)) return;return arr.filter(function(item, index, arr) {//当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素return arr.indexOf(item, 0) === index;});}console.time('filter和indexOf方法耗时:');var res = unique(sourceArr);console.timeEnd('filter和indexOf方法耗时:');// includes方法耗时:: 24.135009765625msconsole.log(res);// 打印数组长度19:[false, "true", Infinity, true, 0, [], [], {b: 2, a: 1}, {b: 2, a: 1}, {}, {}, "false", "0", null, undefined, {a: 1, b: 2}, {a: 1, b: 2}, function(){}, function(){}]
优点:利用高阶函数代码大大缩短;
缺点:由于indexOf无法查找到NaN,因此NaN被忽略。
这种方法很优雅,代码量也很少,但和使用Set结构去重相比还是美中不足。
5. 利用reduce+includes
同样是两个高阶函数的巧妙使用:
var unique = (arr) => {if (!Array.isArray(arr)) return;return arr.reduce((prev,cur) => prev.includes(cur) ? prev : [...prev,cur],[]);}var res = unique(sourceArr);console.time('reduce和includes方法耗时:');var res = unique(sourceArr);console.timeEnd('reduce和includes方法耗时:');// reduce和includes方法耗时:: 100.47802734375msconsole.log(res);// 打印数组长度20:[false, "true", Infinity, true, 0, [], [], {b: 2, a: 1}, {b: 2, a: 1}, {}, {}, "false", "0", null, undefined, {a: 1, b: 2}, {a: 1, b: 2}, NaN, function(){}, function(){}]
优点:利用高阶函数代码大大缩短;
缺点:ES版本要求高,速度较慢;
同样很优雅,但如果这种方法能用,同样也能用Set结构去重。
6. 利用Map结构
使用map实现:
function unique(arr) {if (!Array.isArray(arr)) return;let map = new Map();let result = [];for (let i = 0; i < arr.length; i++) {if(map .has(arr[i])) {map.set(arr[i], true);} else {map.set(arr[i], false);result.push(arr[i]);}}return result;}console.time('Map结构耗时:');var res = unique(sourceArr);console.timeEnd('Map结构耗时:');// Map结构耗时:: 41.483154296875msconsole.log(res);// 打印数组长度20:[false, "true", Infinity, true, 0, [], [], {b: 2, a: 1}, {b: 2, a: 1}, {}, {}, "false", "0", null, undefined, {a: 1, b: 2}, {a: 1, b: 2}, NaN, function(){}, function(){}]
7. 双层嵌套,使用splice删除重复元素
这个也比较常用,对数组进行双层遍历,挑出重复元素:
function unique(arr){if (!Array.isArray(arr)) return;for(var i = 0; i < arr.length; i++) {for(var j = i + 1; j< arr.length; j++) {if(Object.is(arr[i], arr[j])) {// 第一个等同于第二个,splice方法删除第二个arr.splice(j,1);j--;}}}return arr;}console.time('双层嵌套方法耗时:');var res = unique(sourceArr);console.timeEnd('双层嵌套方法耗时:');// 双层嵌套方法耗时:: 41500.452880859375msconsole.log(res);// 打印数组长度20: [false, "true", Infinity, true, 0, [], [], {b: 2, a: 1}, {b: 2, a: 1}, {}, {}, "false", "0", null, undefined, {a: 1, b: 2}, {a: 1, b: 2}, NaN, function(){}, function(){}]
8. 利用sort方法
这个思路也很简单,就是利用sort方法先对数组进行排序,然后再遍历数组,将和相邻元素不相同的元素挑出来:
function unique(arr) {if (!Array.isArray(arr)) return;arr = arr.sort((a, b) => a - b);var result = [arr[0]];for (var i = 1; i < arr.length; i++) {if (arr[i] !== arr[i-1]) {result.push(arr[i]);}}return result;}console.time('sort方法耗时:');var res = unique(sourceArr);console.timeEnd('sort方法耗时:');// sort方法耗时:: 936.071044921875msconsole.log(res);// 数组长度357770,剩余部分省略// 打印:(357770) [Array(0), Array(0), 0...]
优点:无;
缺点:耗时长,排序后数据不可控;
不推荐使用,因为使用sort方法排序无法对数字类型0和字符串类型’0’进行排序导致大量的冗余数据存在。
上面的方法只是针对基础数据类型,对于对象数组函数不考虑,下面再看下如何去重相同的对象。
Object
下面的这种实现和利用Map结构相似,这里使用对象的key不重复的特性来实现
9. 利用hasOwnProperty和filter
使用filter和hasOwnProperty方法:
function unique(arr) {if (!Array.isArray(arr)) return;var obj = {};return arr.filter(function(item, index, arr) {return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)})}console.time('hasOwnProperty方法耗时:');var res = unique(sourceArr);console.timeEnd('hasOwnProperty方法耗时:');// hasOwnProperty方法耗时:: 258.528076171875msconsole.log(res);// 打印数组长度13: [false, "true", Infinity, true, 0, [], {}, "false", "0", null, undefined, NaN, function(){}]
优点:代码简洁,可以区分相同对象数组函数;
缺点:版本要求高,因为要查找整个原型链因此性能较低;
该方法利用对象key不重复的特性来实现区分对象和数组,但上面是通过类型+值做key的方式,所以{a: 1, b: 2}和{}被当做了相同的数据。因此该方法也有不足。
10. 利用对象key不重复的特性
这种方法和使用Map结构类似,但key的组成有所不同:
function unique(arr) {if (!Array.isArray(arr)) return;var result = [];var obj = {};for (var i = 0; i < arr.length; i++) {var key = typeof arr[i] + JSON.stringify(arr[i]) + arr[i];if (!obj[key]) {result.push(arr[i]);obj[key] = 1;} else {obj[key]++;}}return result;}console.time('对象方法耗时:');var res = unique(sourceArr);console.timeEnd('对象方法耗时:');// 对象方法耗时:: 585.744873046875msconsole.log(res);// 打印数组长度15: [false, "true", Infinity, true, 0, [], {b: 2, a: 1}, {}, "false", "0", null, undefined, {a: 1, b: 2}, NaN, function(){}]
这种方法是比较成熟的,去除了重复数组和重复对象,但对于像{a: 1, b: 2}和{b: 2, a: 1}这种就无法区分,原因在于将这两个对象进行JSON.stringify()之后得到的字符串分别是{“a”:1,”b”:2}和{“b”:2,”a”:1}, 因此两个值算出的key不同。加一个判断对象是否相等的方法就好了,改写如下:
function isObject(obj) {return Object.prototype.toString.call(obj) === '[object Object]';}function unique(arr) {if (!Array.isArray(arr)) return;var result = [];var obj = {};for (var i = 0; i < arr.length; i++) {// 此处加入对象和数组的判断if (Array.isArray(arr[i])) {arr[i] = arr[i].sort((a, b) => a - b);}if (isObject(arr[i])) {let newObj = {}Object.keys(arr[i]).sort().map(key => {newObj[key]= arr[i][key];});arr[i] = newObj;}var key = typeof arr[i] + JSON.stringify(arr[i]) + arr[i];if (!obj[key]) {result.push(arr[i]);obj[key] = 1;} else {obj[key]++;}}return result;}console.time('对象方法耗时:');var res = unique(sourceArr);console.timeEnd('对象方法耗时:');// 对象方法耗时:: 793.142822265625msconsole.log(res);// 打印数组长度14: [false, "true", Infinity, true, 0, [], {b: 2, a: 1}, {}, "false", "0", null, undefined, NaN, function(){}]
结论
| 方法 | 优点 | 缺点 |
|---|---|---|
| ES6中Set | 简单优雅,速度快 | 基础类型推荐使用。版本要求高,不支持对象数组和NaN |
| 使用indexOf | ES5以下常用方法,兼容性高,易于理解 | 无法区分NaN;需要特殊处理 |
| 使用inculdes方法 | 可以区分NaN | ES版本要求高,和indexOf方法相比耗时较长 |
| 使用filter和indexOf方法 | 利用高阶函数代码大大缩短; | 由于indexOf无法查找到NaN,因此NaN被忽略。 |
| 利用reduce+includes | 利用高阶函数代码大大缩短; | ES7以上才能使用,速度较慢; |
| 利用Map结构 | 无明显优点 | ES6以上, |
| 双层嵌套,使用splice删除重复元素 | 兼容性高 | 性能低,时间复杂度高,如果不使用Object.is来判断则需要对NaN特殊处理,速度极慢。 |
| 利用sort方法 | 无 | 耗时长,排序后数据不可控; |
| 利用hasOwnProperty和filter | :代码简洁,可以区分相同对象数组函数 | 版本要求高,因为要查找整个原型链因此性能较低; |
| 利用对象key不重复的特性 | 优雅,数据范围广 | Object推荐使用。代码比较复杂。 |
数组对象
/*** 数组对象去重* 设置cur默认类型为数组,并且初始值为空的数组*/let obj = {};arrList = arrList.reduce((cur,next) => {obj[next.value] ? "" : obj[next.value] = true && cur.push(next);return cur;},[]);// 这里得出去重后的数据console.log(arrList);
reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值
语法array.reduce(function(total, currentValue, currentIndex, arr), initialValue)参数 描述total 必需。初始值, 或者计算结束后的返回值。currentValue 必需。当前元素currentIndex 可选。当前元素的索引arr 可选。当前元素所属的数组对象。initialValue 可选。传递给函数的初始值
2. 冒泡排序法
for (var i = 0; i < arr.length - 1; i++) {for (var j = i + 1; j < arr.length; j++) {console.log(i,j)if (arr[i].city == arr[j].city) {arr.splice(j, 1);j--; // 因为数组长度减小1,所以直接 j++ 会漏掉一个元素,所以要 j--}}}console.log(arr); // [{id: 1,city: '南京'},{id: 3,city: '杭州'},{id: 4,city: '广州'}]
3. 双重循环
var newArr = [];arr.forEach((item) => {var check = newArr.every((b) => {return item.city !== b.city;})check ? newArr.push(item) : '';})console.log(newArr); // [{id: 1,city: '南京'},{id: 3,city: '杭州'},{id: 4,city: '广州'}]
4. ES6 Map对象
let formatArr = () => {let map = new Map();for (let item of arr) {if (!map.has(item.city)) {map.set(item.city, item);}}return [...map.values()];}let newArr = formatArr(); // [{id: 1,city: '南京'},{id: 3,city: '杭州'},{id: 4,city: '广州'}]
js判断对象是数组类型还是对象类型
一.判断值是否是对象
**toString **方式【常用】
Object.prototype.toString.call(val) === '[object Object]'// true 代表为对象
注意:这里要使用 call 方法改变作用域
- constructor 方式
val?.constructor === Object // true 代表为对象
这里使用了 null 传导符(?.) 以防止出错
- typeof 与 instanceof
typeof 与 instanceof 并不能完全判断一个值为对象
typeof 的取值有:
- "undefined"——如果这个值未定义;- "boolean"——如果这个值是布尔值;- "string"——如果这个值是字符串;- "number"——如果这个值是数值;- "object"——如果这个值是对象(包括数组)或null;- "function"——如果这个值是函数;- "symbol"——如果这个值是Symbol- instanceof 操作符对于数组和对象都返回 true- [] instanceof Object // true- new Object instanceof Object // true
proto 方式【不推荐】
proto属性,用来读取或设置当前对象的 prototype 对象,此属性未纳入标准,不建议使用。
val.proto === Object.prototype // true 代表为对象
- Object.getPrototypeOf 方式
Object.getPrototypeOf(),用来读取对象的 prototype 对象。
Object.getPrototypeOf(val) === Object.prototype // true 代表为对象
二.判断值是否为数组
- toString 方式
Object.prototype.toString.call(val) === ‘[object Array]’ // true 代表为数组
注意:这里要用 Object 的 toString 方法,Array 的 toString 返回的是拼接的字符串
var colors = [‘red’, ‘blue’, ‘green’];
console.log(colors.toString()); // red,blue,green
- Array.isArray 方法【推荐】
ES5中提供了 isArray 方法用来判断值是否为数组
Array.isArray(val) // true 代表为数组
- instanceof 方式
val instanceof Array // true 代表为数组
为什么 instanceof 可以用来判断数组而不可以判断对象呢?因为数组本身就是一个类似于列表的高阶对象。
- constructor 方式
val?.constructor === Array // true 代表为数组
- proto 方式【不推荐】
val.proto === Array.prototype // true 代表为数组
- Object.getPrototypeOf 方式
Object.getPrototypeOf(val) === Array.prototype // true 代表为数组
- isPrototypeOf 方式
isPrototypeOf() 方法用于测试一个对象是否存在于另一个对象的原型链上。
Array.prototype.isPrototypeOf(val) // true 代表为数组
该方式不能用来判断对象!
[
](https://blog.csdn.net/qq_39025670/article/details/110233270)
获取复杂对象指定key的value值
// 判断是否为对象const isObject = (obj) => {return Object.prototype.toString.call(obj) === "[object Object]";};// 获取嵌套对象属性的值const getValue = (data, target) => {if (!data) {console.log("data不能为空");return}//数组对象if (data instanceof Array) {const datas = []for (const iterator of data) {const result = getValue(iterator, target)if (result) {datas.push(result)}continue}if (datas.length > 0) {return [...new Set(datas)];}}//普通对象if (data instanceof Object) {for (const key of Object.keys(data)) {console.log(key);if (key === target) {return data[key];}const result = getValue(data[key], target);if (result) {return result;}}}};const test = {sname: 'lzx',data: [{demo: "13"}, {demo: "123"},{demo: "1234",name: 'fsdfsss'}],hello: {df: "fff"}}console.log(getValue(test, 'hello'));
JS去除字符串中的中括号或是中括号及其中间内容
var str = '这是一个字符串[html]语句;[html]字符串很常见' ;alert(str.replace(/\[|]/g, '' )); //移除字符串中的所有[]括号(不包括其内容)//输出:这是一个字符串html语句;html字符串很常见alert(str.replace(/\[.*?\]/g, '' )); //移除字符串中的所有[]括号(包括其内容)//输出:这是一个字符串语句;字符串很常见
文件批量下载
- a标签 & location.href
a标签及href指向的如果是一个下载链接,那么相当于下载文件,对于单文件下载还是ok的,不过快速点击几个下载按钮,有的下载会被Cancelled。
H5 新特性,HTML 5 里面为 标签添加了一个 download 的属性,我们可以轻易的利用它来实现下载功能。download 的属性值是可选的,它用来指定下载文件的文件名。<a href="http://somehost/somefile.zip" download="filename.zip">Download file</a>
let files = ['url1', 'url2'] // 所有文件files.forEach(url => {if (this.isIE()) { // IEwindow.open(url, '_blank')} else {let a = document.createElement('a') // 创建a标签let e = document.createEvent('MouseEvents') // 创建鼠标事件对象e.initEvent('click', false, false) // 初始化事件对象a.href = url // 设置下载地址a.download = '' // 设置下载文件名a.dispatchEvent(e)}})
- window.open
window.open可以打开一个新窗口下载文件,不过会快速打开一个新窗口并且关闭,体验非常不好。
- iframe
export const downloadFile = (url) => {const iframe = document.createElement("iframe");iframe.style.display = "none"; // 防止影响页面iframe.style.height = 0; // 防止影响页面iframe.src = url;document.body.appendChild(iframe); // 这一行必须,iframe挂在到dom树上才会发请求// 5分钟之后删除(onload方法对于下载链接不起作用,就先抠脚一下吧)setTimeout(()=>{iframe.remove();}, 5 * 60 * 1000);}
中划线转驼峰
```javascript //-中划线转驼峰 const toHump=(key)=>{ return key.replace(/-(\w)/g,(all,letter)=>{ return letter.toUpperCase(); }) }
// 驼峰转换下划线 const toLine=(key)=> { return key.replace(/([A-Z])/g,”-$1”).toLowerCase(); }
<a name="JBuLh"></a># 复制单行内容到粘贴板```javascript/*** 复制单行内容到粘贴板* content : 需要复制的内容*/function copyToClip(content) {var aux = document.createElement("input");aux.setAttribute("value", content);document.body.appendChild(aux);aux.select();document.execCommand("copy");document.body.removeChild(aux);if (content) {message.success('复制成功!');}}
保留任意小数位数
function round(number, precision) {return Math.round(+number + 'e' + precision) / Math.pow(10, precision);//same as://return Number(Math.round(+number + 'e' + precision) + 'e-' + precision);}
