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() + 1
m = m < 10 ? '0' + m : m
return y + '-' + m
}
const formatDate = (inputTime) => {
var date = new Date(inputTime)
var y = date.getFullYear()
var m = date.getMonth() + 1
m = m < 10 ? '0' + m : m
var d = date.getDate()
d = d < 10 ? '0' + d : d
return y + '-' + m + '-' + d
}
const formatDateTime = (inputTime) => {
var date = new Date(inputTime)
var y = date.getFullYear()
var m = date.getMonth() + 1
m = m < 10 ? '0' + m : m
var d = date.getDate()
d = d < 10 ? '0' + d : d
var h = date.getHours()
h = h < 10 ? '0' + h : h
var minute = date.getMinutes()
var second = date.getSeconds()
minute = minute < 10 ? '0' + minute : minute
second = second < 10 ? '0' + second : second
return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second
}
const formatDateRange = (inputTime) => {
var date = new Date(inputTime)
var y = date.getFullYear()
var m = date.getMonth() + 1
m = m < 10 ? '0' + m : m
var start = y + '-' + m + '-01'
var lastDay = new Date(y, m, 0)
var d = lastDay.getDate()
var end = y + '-' + m + '-' + d
return [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 转 rgba
const 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 = 20
else if (precent > 20 && precent <= 40) precent = 40
else if (precent > 40 && precent <= 60) precent = 60
else if (precent > 60 && precent <= 80) precent = 80
else precent = 100
precent /= 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 = 1
arr[flag.index].rowspan = flag.length
for (let i = 1; i < flag.length; i++) {
if ((flag.index + i) % size === 0) {
arr[flag.index + i].colspan = 1
arr[flag.index + i].rowspan = flag.length - i
} else {
arr[flag.index + i].colspan = 0
arr[flag.index + i].rowspan = 0
}
}
flag.projectId = item.projectId
flag.index = index
flag.length = 1
arr[index].colspan = 1
arr[index].rowspan = flag.length
} else {
flag.projectId = item.projectId
// 考虑只筛选出一条任务的情况
if (arr[flag.index].colspan === 0 || arr[flag.index].rowspan === 0) {
arr[flag.index].colspan = 1
arr[flag.index].rowspan = flag.length
}
}
}
if (index === arr.length - 1 && flag.length > 1) {
arr[index - flag.length + 1].colspan = 1
arr[index - flag.length + 1].rowspan = flag.length
for (let i = 0; i < flag.length - 1; i++) {
arr[index - i].colspan = 0
arr[index - i].rowspan = 0
if ((flag.index + i + 1) % size === 0) {
arr[flag.index + i + 1].colspan = 1
arr[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.736328125ms
console.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.538818359375ms
console.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.376953125ms
console.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.412841796875ms
console.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.135009765625ms
console.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.47802734375ms
console.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.483154296875ms
console.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.452880859375ms
console.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.071044921875ms
console.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.528076171875ms
console.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.744873046875ms
console.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.142822265625ms
console.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()) { // IE
window.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);
}