项目中必用的js方法汇总
- 一:常用函数
- 1、过滤电话号和身份证号用****
- 2、银行卡输入时四位加一个空格显示
- 3、处理价格数据,每三位加逗号,并留两位小数点(整数留 .00)
- 4、处理后端返回的数组数据遍历为一个数组里面包括多个对象形式
- 5、数组里面多个对象,取出对象一样的,并计数多少组,单独出一个数组出来
- 6、js 中日期2020-12-08 或 2020-12-08 12:30:00 转换成时间戳
- 7、把字符串转为key值相同的对象
- 8、JS的JSON.parse数字转换精度问题
- 9、js截取小数点后n位
- 10、树形结构数据
- 11、vue中取出url地址中的location.hash/href里面的值
- 12、当前时间的日期和时间
- 13、时间的判定(刚刚、分钟前、小时前、1天前)
- 14、首字母大写
- 15、数字千位的分隔
- 16、时间的年月日 月份月初、月底、当前
- 17、取出a.b.d.m的值
- 18、两个数组合并为一个数组对象
- 19、取出嵌套数组中的对象
- 20、用 apply 将数组各项添加到另一个数组
- 21、 递归数组降为一维
- 22、数组降维(二维降一维)
- 23、按属性对object分类
- 24、计算数组中每个元素出现的次数
- 25、检测数组对象中是否有空值
- 26、将带有分割符的字符串转化成一个n维数组
- 27、JS中去掉array中重复元素(里面是字符串格式)
- 27、JS中去掉array中重复元素(里面是对象格式)
- 28、防抖函数
- 29、树形结构加层级
- 30、递归对树形结构扁平化处理
- 31、递归对树形结构数据处理 -- js模糊查询
- 32、生成树状结构数据
- 33、数组中去重对象
- 34,取出数组的对应值的下标
- 35,将数组里面string数字字符全部转为number数字
- 36,将数组里面number数字字符全部转为string数字
- 37、将某个值从数组中删除,并得到删除后的值
- 38、计算上传文件大小和单位
- 39、去掉两个数组重复部分(对象或者简单数据类型)
- 40、数字千位加逗号处理
- 41、树形数据查找父子元素之间的数据关系
- 42、获取cookie方法
- 43、树形结构 根据子节点id 获取上一级 父节点的数据
- 44、从一个数组中删除另一个数组中存在的元素
- 45、给树形结构下面的子集数据添加某个属性
- 二:常用时间函数
- 三、JS算法
一:常用函数
1、过滤电话号和身份证号用****
这里用于vue项目中过滤器使用,可以根据情况来写
filters:{
replaceStar(str,frontLen,endLen){
// str:字符串,frontLen:前面保留位数,endLen:后面保留位数。
if(frontLen == 3 && endLen == 4){
var substr = str.substr(frontLen, endLen)
var repNum = str.replace(substr,'****')
return repNum
}
if(frontLen == 6 && endLen == 18){
var substr = str.substr(frontLen,endLen)
var repNum = str.replace(substr,'************')
return repNum
}
}
},
改写上面那种写法:
function hiddenXing(str, frontLen, endLen) {
var len = str.length - frontLen - endLen;
var xing = '';
for (var i = 0; i < len; i++) {
xing += '*';
}
return str.substring(0, frontLen) + xing + str.substring(str.length - endLen);
}
// 使用
console.log(hiddenXing('411设计隐私0558', 4, 4));
2、银行卡输入时四位加一个空格显示
// 银行卡四位空格 格式化卡号显示,每4位加空格
formatCardNumber (e) {
// 获取input的dom对象
const input = e.target
// 获取当前光标的位置
const cursorIndex = input.selectionStart
// 字符串中光标之前空格的个数
const lineNumOfCursorLeft = (e.target.value.slice(0, cursorIndex).match(/\s/g) || []).length
// 去掉所有空格的字符串
const noLine = e.target.value.replace(/\s/g, '')
// 去除格式不对的字符并重新插入空格的字符串
const newCardNum = noLine.replace(/\D+/g, '').replace(/(\d{4})/g, '$1 ').replace(/\s$/, '')
// 改后字符串中原光标之前空格的个数
const newLineNumOfCursorLeft = (newCardNum.slice(0, cursorIndex).match(/\s/g) || []).length
// 光标在改后字符串中应在的位置
const newCursorIndex = cursorIndex + newLineNumOfCursorLeft - lineNumOfCursorLeft
// 赋新值,nextTick保证空格不能手动输入或删除,只能按照规则自动填入
this.$nextTick(() => {
this.entity.bankCardNumber = newCardNum
// 修正光标位置,nextTick保证在渲染新值后定位光标
this.$nextTick(() => {
// selectionStart、selectionEnd分别代表选择一段文本时的开头和结尾位置
input.selectionStart = newCursorIndex
input.selectionEnd = newCursorIndex
})
})
}
<div class="flex-center">
<div class="text-info">银行卡号</div>
<div class="flex1 pd-300 bd-bot">
<input type="text" placeholder="请输入银行卡" class="input-box"
maxlength="23" minlength="12"
v-model="entity.bankCardNumber"
@input="formatCardNumber"
ref="cardInput"
>
</div>
</div>
3、处理价格数据,每三位加逗号,并留两位小数点(整数留 .00)
let value = 123123.23
Number(value).toLocaleString('en-US') // 结果:123,123.23
但是发现如果是整数或者后面小数不是两位的话,就不一样了。
function changeTwoDecimal_f(x) {
var f_x = parseFloat(x);
if (isNaN(f_x))
{
return 0;
}
var f_x = Math.round(x*100)/100;
var s_x = f_x.toString();
var pos_decimal = s_x.indexOf('.');
if (pos_decimal < 0)
{
pos_decimal = s_x.length;
s_x += '.';
}
while (s_x.length <= pos_decimal + 2)
{
s_x += '0';
}
// 三位加一个逗号
s_x = Number(s_x).toLocaleString('en-US')
return s_x;
}
let value = 123123.123
let value1 = 123123
changeTwoDecimal_f(value) // "123123123.12"
changeTwoDecimal_f(value1) // "123123123.00"
4、处理后端返回的数组数据遍历为一个数组里面包括多个对象形式
let activeName = ["某某1","某某2","某某3","某某4"]
let activeVal = ["value1","value2","value3","value4"]
let actionArr = []
for(let i=0; i<activeName.length; i++){
let activeObj = {}
for(let j=0 ; j < activeName.length; j++){
if(i==j){
activeObj.name = activeName[i]
activeObj.value = activeVal[j]
actionArr.push(activeObj)
}
}
}
console.log(actionArr)
5、数组里面多个对象,取出对象一样的,并计数多少组,单独出一个数组出来
let list=[
{
id:1,
name:'apple',
num:2
},
{
id:1,
name:'apple',
num:3
},
{
id:2,
name:'orange',
num:2
},
{
id:1,
name:'apple',
num:2
},
]
list = list.reduce((obj, item) => {
let find = obj.find(i => i.id === item.id)
let _d = {
...item,
frequency: 1
}
find ? (find.num+=item.num,find.frequency++ ): obj.push(_d)
return obj
}, [])
6、js 中日期2020-12-08 或 2020-12-08 12:30:00 转换成时间戳
let date = new Date("2020-12-08 12:30:00") //date日期类型
let time = date.getTime(); //毫秒时间戳
7、把字符串转为key值相同的对象
var arr = []
labelList.split(',').forEach((item, index) => {
let dataObj = {}
dataObj.laberName = item
arr.push(dataObj)
})
onsole.log(arr)
8、JS的JSON.parse数字转换精度问题
var data = '{"success":"true","projectId":730107215209299968}';
//匹配projectId对于的key
var newResponseString = data.replace(/\"projectId\":(\d+)/,'"projectId": "$1"');
var resultObj = JSON.parse(newResponseString);
console.log(resultObj.projectId);
9、js截取小数点后n位
// getPointNum 函数传入两个参数
// 参数1为要处理的小数,参数2为取到小数点后几位
function getPointNum(num,n){
let str = String(num);
let index = str.indexOf(".");
let str1 = str.substring(0,index+n+1);
str1 = Number(str1);
return str1;
}
getPointNum(3.1415926, 4); //输出结果:3.1415
10、树形结构数据
11、vue中取出url地址中的location.hash/href里面的值
function getQueryString(){
var obj={},params='';
(params=window.location.search.substr(1))||(params=window.location.hash.split('?')[1])
params.split(/&/g).forEach(function(item){
obj[(item=item.split('='))[0]]=item[1];
})
return obj
}
12、当前时间的日期和时间
function parseTime(time, cFormat) {
if (arguments.length === 0 || !time) {
return null
}
const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if ((typeof time === 'string')) {
if ((/^[0-9]+$/.test(time))) {
// support "1548221490638"
time = parseInt(time)
} else {
// support safari
// https://stackoverflow.com/questions/4310953/invalid-date-in-safari
time = time.replace(new RegExp(/-/gm), '/')
}
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
const value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
return value.toString().padStart(2, '0')
})
return time_str
}
// let date = parseTime(new Date())
let date = parseTime(new Date().getTime())
console.log(new Date()); // 获取当前时间 例如Sat Mar 06 2021 12:57:46 GMT+0800 (中国标准时间)
console.log(new Date().getTime()); // 获取时间戳 1615006666597
console.log(date); // 2021-03-06 12:57:46
13、时间的判定(刚刚、分钟前、小时前、1天前)
function formatTime(time, option) {
if (('' + time).length === 10) {
time = parseInt(time) * 1000
} else {
time = +time
}
const d = new Date(time)
const now = Date.now()
const diff = (now - d) / 1000
if (diff < 30) {
return '刚刚'
} else if (diff < 3600) {
// less 1 hour
return Math.ceil(diff / 60) + '分钟前'
} else if (diff < 3600 * 24) {
return Math.ceil(diff / 3600) + '小时前'
} else if (diff < 3600 * 24 * 2) {
return '1天前'
}
if (option) {
return parseTime(time, option)
} else {
return (
d.getMonth() +
1 +
'月' +
d.getDate() +
'日' +
d.getHours() +
'时' +
d.getMinutes() +
'分'
)
}
}
// let date = formatTime(new Date()) //输入时间
// let date = formatTime(new Date().getTime()) //输入时间戳格式
console.log(new Date().getTime());
let date = formatTime(1615008130122) //输入某个时间戳
// let date = formatTime(new Date('2021-3-6 13:10:25'))
console.log(date); // 打印你想要的时间 比如 10分钟前 、3小时前 或者日期
14、首字母大写
function uppercaseFirst(string) {
return string.charAt(0).toUpperCase() + string.slice(1)
}
let num = uppercaseFirst('fqniu')
console.log(num); // Fqniu
15、数字千位的分隔
function toThousandFilter(num) {
return (+num || 0).toString().replace(/^-?\d+/g, m => m.replace(/(?=(?!\b)(\d{3})+$)/g, ','))
}
let num1 = toThousandFilter(10020)
let num2 = toThousandFilter(103450200)
console.log(num1); // 10,020
console.log(num2); // 103,450,200
16、时间的年月日 月份月初、月底、当前
function parseTime(time, cFormat) {
if (!time || arguments.length === 0) {
return null
}
const format = cFormat || '{y}-{m}-{d} {h}:{i}'
let date
if (typeof time === 'object') {
date = time
} else {
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
time = parseInt(time)
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
const value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') {
return ['日', '一', '二', '三', '四', '五', '六'][value]
}
return value.toString().padStart(2, '0')
})
return time_str
}
// 测试如下:
// 获取月份月初的年月日
let data1 = parseTime(new Date().setDate(1), '{y}-{m}-{d}')
console.log(data1); // 2021-03-01
// 获取当天的年月日
let data2 = parseTime(new Date(), '{y}-{m}-{d} {h}:{i}:{s} {a}')
console.log(data2); // 2021-03-26 11:39:55 五
// 获取当前月底年月日
let date = new Date()
yy = date.getFullYear()
mm = date.getMonth() + 1
let data3 = parseTime(new Date(yy, mm, 0), '{y}-{m}-{d}')
console.log(data3); // 2021-03-31
// 输入年月可以得到当前月份的月初, 当new Date()为空时,可以获取当前月初
function monthStart(year, month) {
var time = new Date(year + '-' + month)
time.setDate(1)
return parseTime(time, '{y}-{m}-{d}')
}
// 输入年 月 可以得到当前月份的最后月底
function monthEnd(year, month) {
let end_date = new Date(year + '-' + month)
let yy = end_date.getFullYear()
let mm = end_date.getMonth() + 1
return parseTime(new Date(yy, mm, 0), '{y}-{m}-{d}')
}
let date = new Date()
let currentDate = date.toLocaleDateString()
console.log(currentDate); // 2021/5/10
17、取出a.b.d.m的值
var o ={
a:{
b:{
c:{
m:10
}
}
}
}
var str = 'a.b.c.m';
function parsePath(str) {
var segments = str.split('.');
return (obj) => {
for (let i = 0; i < segments.length; i++) {
if(!obj) return ;
obj = obj[segments[i]]
}
return obj;
}
}
var fn = parsePath(str)
var a = fn(o);
console.log(a); //10
function lookup(dataObj, keyname) {
// console.log(dataObj, keyname);
// 看看keyname 有没有点符号 但是不能是 . 本身
if (keyname.indexOf('.') !== -1 && keyname !== '.') {
var keys = keyname.split('.')
// 用这个temp变量作为中间值 临时变量 用于周转 , 一层一层去找
var temp = dataObj;
// 每找一层设置为新的临时变量
for (let i = 0; i < keys.length; i++) {
temp = temp[keys[i]];
}
return temp
}
// 如果这里没有点符号
return dataObj[keyname];
}
18、两个数组合并为一个数组对象
var arr1 = [{
"id": 1,
"color": "白",
"invStatusName": "正品",
"bactualQty": 77,
"brealyQty": 12,
"bavailQty": 23
}, {
"id": 2,
"color": "灰",
"invStatusName": "正品",
"bactualQty": 11,
"brealyQty": 6,
"bavailQty": -5
}];
var arr2 = [{
"price": "2399"
}, {
"price": "999"
}];
var arr = arr1.map((item,index) => {
return {...item, ...arr2[index]};
});
console.log(arr);
19、取出嵌套数组中的对象
let arr = [[[[[{ i:1 }]]]]]
while(Array.isArray(arr)){
arr = arr[0]
}
console.log(arr.i);
20、用 apply 将数组各项添加到另一个数组
const array = ['a', 'b'];
const elements = [0, 1, 2];
console.log(array.concat(elements)); // ["a", "b", 0, 1, 2]
console.log(array, elements); // ["a", "b"] , [0, 1, 2]
array.push.apply(array, elements); // 会改变array原来的数组
console.log(array, elements); // ["a", "b", 0, 1, 2] , [0, 1, 2]
21、 递归数组降为一维
let children = [1, [2, 3],
[4, [5, 6, [7, 8]]],
[9, 10]
];
function simpleNormalizeChildren(children) {
for (let i = 0; i < children.length; i++) {
if (Array.isArray(children[i])) {
children = Array.prototype.concat.apply([], children);
simpleNormalizeChildren(children)
}
}
return children;
}
console.log(simpleNormalizeChildren(children)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
22、数组降维(二维降一维)
function simpleNormalizeChildren(children) {
for (let i = 0; i < children.length; i++) {
if (Array.isArray(children[i])) {
return Array.prototype.concat.apply([], children)
}
}
return children
}
let arrs = [
['1'],
['3']
];
const arr = simpleNormalizeChildren(arrs);
console.log(arr); // ['1','3']
23、按属性对object分类
let people = [
{
name: 'niuniu',
age: 18
},
{
name: 'fqniu',
age: 25
},
{
name: 'niufuqiang',
age: 25
}
];
function groupBy(objectArray, property) {
return objectArray.reduce(function (acc, obj) {
let key = obj[property];
if (!acc[key]) {
acc[key] = [];
}
acc[key].push(obj);
return acc;
}, {});
}
const groupedPeople = groupBy(people, 'age');
console.log(groupedPeople);
24、计算数组中每个元素出现的次数
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
let countedNames = names.reduce(function (allNames, name) {
if (name in allNames) {
allNames[name]++;
} else {
allNames[name] = 1;
}
return allNames;
}, {});
console.log(countedNames); // { Alice: 2, Bob: 1, Tiff: 1, Bruce: 1 }
25、检测数组对象中是否有空值
const data = [{
name: "fqniu",
age: "25"
},
{
name: "niuniu",
age: ""
}
]
const arr = data.filter(item =>
Object.values(item).includes('')
);
console.log(arr.length > 0 ? "有空值" : "无空值"); // 有空值
26、将带有分割符的字符串转化成一个n维数组
const str = "A-2-12";
const str1 = str.split('-');
console.log(str1);
const arr = str1.reverse().reduce((pre, cur, i) => {
if (i == 0) {
pre.push(cur)
return pre
}
return [cur, pre]
}, [])
console.log(arr) // ["A", ["2", ["12"]]]
27、JS中去掉array中重复元素(里面是字符串格式)
filter是一个常用的操作,它用于把Array的某些元素过滤掉,然后返回剩下的元素。和map()类似,Array的filter()也接收一个函数。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素。
因为Array中的indexOf总是返回第一次出现某一个元素的位置,后续的重复元素位置与indexOf返回的位置不相等,因此被filter滤掉了。
// 示例:点击按钮添加元素到数组中,不能添加重复的元素
let arr =['fqniu','niuniu','niuer','强仔','富强','niuer']
arr = arr.filter((elm, i, self) => {
console.log(elm,i, self);
return self.indexOf(elm) === i;
})
console.log('arr=', arr);
// vue中写法
selectedArea(item){
this.selectedAreaArr.push(item)
this.selectedAreaArr = this.selectedAreaArr.filter((elm, i, self) => {
return self.indexOf(elm) === i;
})
},
27、JS中去掉array中重复元素(里面是对象格式)
// 2、数组去重对象
objUnique = (data) => {
let unique = {};
data.forEach(function (item) {
unique[JSON.stringify(item, ['id', 'name', 'pid', 'isExpand', 'isChecked', 'children', 'createTime'])] = item; //键名顺序问题
})
data = Object.keys(unique).map(function (u) {
//Object.keys()返回对象的所有键值组成的数组,map方法是一个遍历方法,返回遍历结果组成的数组.将unique对象的键名还原成对象数组
return JSON.parse(u);
})
return data;
}
其中 ['id', 'name', 'pid', 'isExpand', 'isChecked', 'children', 'createTime']
代表数据中key值
function unquieArr(arr) {
let newArr = [];
let obj = {};
for (let i = 0; i < arr.length; i++) {
//将arr[i].id作为对象属性进行判断
if (!obj[arr[i].id]) {
newArr.push(arr[i]);
obj[arr[i].id] = true;
// { key1: true, key2: true }
}
}
return newArr
}
28、防抖函数
// 防抖函数
debounce: function (fun, delay) {
let timer = null
// 接收调用函数时传入的参数的值 ...args 可多个
return function (...args) {
if (tiemr) return
timer = setTimeout(() => {
fun.apply(this, args)
}, delay);
}
}
const refresh = debounce(xxx, 500)
refresh('参数1', '参数2', '参数3')
29、树形结构加层级
function arrayTreeAddLevel(array, levelName = 'level', childrenName = 'children') {
if (!Array.isArray(array)) return []
var recursive = (item, level = 0) => {
level++
return item.map(v => {
v[levelName] = level
var child = v[childrenName]
if (child && child.length) recursive(child, level)
return v
})
}
return recursive(array)
}
console.log(arrayTreeAddLevel(array));
30、递归对树形结构扁平化处理
function handleTree(arr) {
let result = []
for (let item of arr) {
var res = JSON.parse(JSON.stringify(item)) // 先克隆一份数据作为第一层级的填充
delete res['children']
result.push(res)
if (item.children instanceof Array && item.children.length > 0) { // 如果当前children为数组并且长度大于0,才可进入flag()方法
result = result.concat(handleTree(item.children))
}
}
return result
}
31、递归对树形结构数据处理 – js模糊查询
const rebuildData = (value, arr) => {
let newarr = [];
arr.forEach(element => {
if (element.children && element.children.length) {
const ab = rebuildData(value, element.children);
const obj = {
...element,
children: ab
};
if (ab && ab.length) {
newarr.push(obj);
}
} else {
if (element.name.indexOf(value) > -1) {
newarr.push(element);
}
}
});
return newarr;
};
const rebuildData = (value, arr) => {
if (!arr) {
return []
}
let newarr = [];
arr.forEach(element => {
if (element.name.indexOf(value) > -1) {
const ab = rebuildData(value, element.children);
const obj = {
...element,
children: ab
}
newarr.push(obj);
} else {
if (element.children && element.children.length > 0) {
const ab = rebuildData(value, element.children);
const obj = {
...element,
children: ab
};
if (ab && ab.length > 0) {
newarr.push(obj);
}
}
}
});
return newarr;
};
32、生成树状结构数据
第一种写法:
// 格式化树形结构
function formateRouterTree(data) {
let parents = data.filter(p => p.pid == 0),
children = data.filter(c => c.pid != 0);
dataToTree(parents, children)
function dataToTree(parents, children) {
parents.map(p => {
children.map((c, i) => {
if (c.pid == p.id) {
let _c = JSON.parse(JSON.stringify(children))
_c.splice(i, 1);
dataToTree([c], _c)
if (p.children) {
p.children.push(c)
} else {
p.children = [c]
}
}
})
})
}
return parents
}
第二种写法:
/*
* 构造树形菜单
* @param {Array} data 需要处理的扁平数组
* @param {String} pid 父级id
* @return
* */
function toTreeData(data, pid) {
function tree(id) {
let arr = []
data.filter(item => {
return item.parentID === id
}).forEach(item => {
arr.push({
id: item.functionID,
code: item.functionCode,
name: item.functionName,
path: item.url,
key: item.functionCode,
parentId: item.parentID,
children: tree(item.functionID),
meta: {}
})
})
return arr
}
return tree(pid)
}
// 解析
function toTreeData(data, pid) {
function tree(id) {
let arr = []
// 这里是为了取得传入的id和当前数据的parentID 一致的数据
let filterArr = data.filter(item => {
return item.parentID === id
})
// 用于循环筛选后的数据 当filterArr为空数组时,不在继续循环 forEach
filterArr.forEach(item => {
let obj = { ...item }
// 传入下一级的id 继续循环 tree 函数
obj.children = tree(item.functionID)
arr.push(obj)
})
return arr
}
return tree(pid)
}
33、数组中去重对象
let arr = [{
id: '01',
value: 'fqniu'
}, {
id: '02',
value: 'niuer'
}, {
id: '03',
value: 'niufuqiang'
}, {
id: '04',
value: 'niuniu'
}, {
id: '01',
value: 'fqniu'
}];
// 方法1:利用对象访问属性的方法,判断对象中是否存在id 通过如下 方式 {01: true, 02: true, 03: true, 04: true}
function objUnique(arr) {
let result = [];
let obj = {};
// for (var i = 0; i < arr.length; i++) {
// if (!obj[arr[i].id]) {
// result.push(arr[i]);
// obj[arr[i].id] = true;
// }
// }
if(!(arr instanceof Array)) return '类型错误'
arr.forEach((element, i) => {
if (!obj[arr[i].id]) {
result.push(arr[i]);
obj[arr[i].id] = true;
}
});
return result
}
console.log(objUnique(arr));
// 方法2:利用reduce方法遍历数组,reduce第一个参数是遍历需要执行的函数,第二个参数是item的初始值
function objUnique(arr) {
let obj = {};
return arr.reduce(function (item, next) {
obj[next.id] ? '' : obj[next.id] = true && item.push(next);
return item;
}, []);
}
console.log(objUnique(arr));
34,取出数组的对应值的下标
// 采用prototype原型实现方式,查找元素在数组中的索引值
Array.prototype.getArrayIndex = function (elm) {
// console.log(this); // 这里的this指的是当前传入的数组元素
for (var i = 0; i < this.length; i++) {
if (this[i] === elm) {
return i
}
}
return -1
}
arr.getArrayIndex('xxx')
// while循环查询 返回值
function getArrayIndex(arr, elm) {
var i = arr.length;
while (i--) {
if (arr[i] === elm) {
return i;
}
}
return -1;
}
getArrayIndex(arr, xxx)
35,将数组里面string数字字符全部转为number数字
let arr = ['1', '2', '3'];
// map 遍历返回一个新的数组
// map遍历arr默认给Number(num)传入一个arr 中的项目,Number()中返回转换后的字符
arr.map(Number);
console.log(arr); // [1, 2, 3]
36,将数组里面number数字字符全部转为string数字
let arr = [1, 2, 3];
// map 遍历返回一个新的数组
// map遍历arr默认给String(num)传入一个arr 中的项目,String()中返回转换后的字符
arr.map(String);
console.log(arr); // ['1', '2', '3'];
37、将某个值从数组中删除,并得到删除后的值
function remove(arr, item) {
if (arr.length) {
const index = arr.indexOf(item)
if (index > -1) {
return arr.splice(index, 1)
}
}
}
let arr = [1, 2, 3, 4, 5]
remove(arr, 4)
console.log(arr); // [1, 2, 3, 5]
// console.log(remove(arr, 4)); // [4]
38、计算上传文件大小和单位
function bytesToSize(bytes) {
if (bytes === 0) return '0 B';
var k = 1000, // or 1024
sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
i = Math.floor(Math.log(bytes) / Math.log(k));
return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i];
}
39、去掉两个数组重复部分(对象或者简单数据类型)
let arr1 = [{
id: '1',
name: 'fqniu'
}, {
id: '2',
name: 'niuniu'
}]
let arr2 = [{
id: '1',
name: 'fqniu',
age: '26'
}, {
id: '2',
name: 'niuniu',
age: '18'
}, {
id: '3',
name: 'niuer',
age: '22'
}]
//ES6的方法
let list1 = arr2.filter(item => !arr1.some(ele => ele.id === item.id));
cosnole.log(list1);
//ES5的方法
for (var i = 0; i < arr2.length; i++) {
for (var j = 0; j < arr1.length; j++) {
if (arr2[i].id == arr1[j].id) {
arr2.splice(i, 1);
}
}
}
let arr3 = [a, b, c, ];
let arr4 = [a, b, c, d];
let list2 = arr4.filter(items => {
if (!arr3.includes(items)) return items;
})
console.log(list);
40、数字千位加逗号处理
function toThousandFilter(value) {
if (!value) return ''
value = value.toString()
return value.replace(value.indexOf('.') > -1 ? /(\d)(?=(\d{3})+\.)/g : /(\d)(?=(?:\d{3})+$)/g, '$1,')
}
console.log(toThousandFilter(300000000)); // 300,000,000
41、树形数据查找父子元素之间的数据关系
var data = [
{
id: 1,
label: '一级 1',
children: [{
id: 4,
label: '二级 1-1',
children: [{
id: 9,
label: '三级 1-1-1'
}, {
id: 10,
label: '三级 1-1-2'
}]
}]
},
{
id: 2,
label: '一级 2',
children: [{
id: 5,
label: '二级 2-1'
}, {
id: 6,
label: '二级 2-2'
}]
},
{
id: 3,
label: '一级 3',
children: [{
id: 7,
label: '二级 3-1'
}, {
id: 8,
label: '二级 3-2'
}]
}
]
// 查找当前元素的父元素
function getParentId(list, id) {
for (let i in list) {
if (list[i].id == id) {
return [list[i]]
}
if (list[i].children) {
let node = getParentId(list[i].children, id)
if (node !== undefined) {
// delete list[i].children
return node.concat(list[i])
}
}
}
}
//查找 id = 10 的所有父级节点
let fatherElm = getParentId(JSON.parse(JSON.stringify(data)), 10) // 打印出来就是想要的数据
console.log(fatherElm)
//查找当前元素(里面包括元素的children)
function getId(list, id) {
for (let i in list) {
if (list[i].id == id) {
return [list[i]]
}
if (list[i].children) {
let node = getParentId(list[i].children, id)
if (node !== undefined) {
return node
}
}
}
}
let currentElm = getId(JSON.parse(JSON.stringify(data)), 4) // 打印出来就是想要的数据
console.log(currentElm)
//查找当前元素的子元素
function getNodeId(list, newNodeId = []) {
for (let i in list) {
newNodeId.push(list[i])
if (list[i].children) {
getNodeId(list[i].children, newNodeId)
// 添加下面代码可以删除元素下面的children
// delete list[i].children
}
}
return newNodeId
}
//查找 id = 4 的所有子级节点 查到的子级节点里面有children
let elmArr = getId(JSON.parse(JSON.stringify(data)), 4)
let childArr = getNodeId(JSON.parse(JSON.stringify(elmArr))) // 打印出来就是想要的数据
console.log(elmArr, childArr);
42、获取cookie方法
function getCookieValue(key) {
const regex = new RegExp(`${key}=([^;]+)`);
const match = document.cookie.match(regex);
return match && match[1];
}
console.log(getCookieValue('username'));
// 假设当前 Cookie 中有键为 'username',且其值为 'fqniu',则输出 'fqniu'
// 先安装 js-cookie 库,安装命令: npm install js-cookie
import Cookies from 'js-cookie';
// 获取键为 'username' 的 Cookie
let username = Cookies.get('username');
// 设置一个名为 'password' 的 Cookie
Cookies.set('password', 'password123456', { expires: 7 });
// 删除键为 'username' 的 Cookie
Cookies.remove('username');
43、树形结构 根据子节点id 获取上一级 父节点的数据
// 获取上一级父节点元素
getParentNode(tree, targetId) {
function findParent(node, targetId) {
if (
node.children &&
node.children.some(child => child.id === targetId)
) {
return node
}
if (node.children) {
for (let child of node.children) {
const parent = findParent(child, targetId)
if (parent) return parent
}
}
return null
}
// 从树的根节点开始查找
return findParent(tree, targetId)
},
44、从一个数组中删除另一个数组中存在的元素
// 从一个数组中删除另一个数组中存在的元素 数组格式
let initArr = ['1', '2', '3']
let removeArr = ['2', '4']
initArr = initArr.filter(item => !removeArr.includes(item))
console.log(initArr, 111111) // ['1', '3']
// 从一个数组中删除另一个数组中存在的元素 数组对象格式
let new_arr1 = []
let new_arr2 = []
let originArr = [{ id: 11 }, { id: 22 }, { id: 33 }]
let to_remove = [{ id: 11 }, { id: 22 }, { id: 55 }]
// 从数组arr中删除数组to_remove中存在的元素
new_arr1 = originArr.filter((o) => !to_remove.some((item) => o.id === item.id))
new_arr2 = to_remove.filter((o) => !originArr.some((item) => o.id === item.id))
console.log(new_arr1, 22222) // [{ id: 33 }]
console.log(new_arr2, 22222) // [{ id:55 }]
45、给树形结构下面的子集数据添加某个属性
function addPropertyToTree(treeData, propertyName, propertyValue) {
// 递归函数给树形结构中的每个节点添加属性
function addProperty(nodes) {
nodes.forEach(node => {
// 添加属性
node[propertyName] = propertyValue;
// 递归处理子节点
if (node.children && node.children.length > 0) {
addProperty(node.children);
}
});
}
// 添加属性
addProperty(treeData);
return treeData;
}
// 示例树形结构数据
const treeData = [
{
id: '1',
name: 'Node1',
children: [
{
id: '1-1',
name: 'Node1-1',
children: []
}
]
},
{
id: '2',
name: 'Node2',
children: []
}
];
// 调用函数添加属性
const updatedTreeData = addPropertyToTree(treeData, 'newProp', 'newValue');
console.log(updatedTreeData); // 子集数据添加newProp属性和对应的属性值
二:常用时间函数
1、获取当前月份大写的写法
function month() {
return [
'一',
'二',
'三',
'四',
'五',
'六',
'七',
'八',
'九',
'十',
'十一',
'十二'
][new Date().getMonth()]
}
console.log(month()); // 八
2、获取某年的某月有多少天
function getDays(Y, M) {
let day = new Date(Y, M, 0).getDate()
return Y + '年' + M + '月' + '有' + day + '天'
}
console.log(getDays(2021, 10)); // 2021年10月有31天
3、获取当前年份和月份
function getDate() {
let now = new Date()
let year,month
year = now.getFullYear()
month = now.getMonth() + 1
return year + '年' + month + '月'
}
console.log(getDate()); // 2021年10月
4、获取某年和某月的第一天1号是周几
// 获取当前年份和月份的第一天1号是周几
function getWeek(Y, M) {
let now = new Date()
now.setFullYear(Y)
now.setMonth(M - 1)
now.setDate(1)
let week = now.getDay()
return Y + '年' + M + '月' + '的1号是周' + week
}
console.log(getWeek(2021, 9)); // 2021年9月的1号是周3
5、每个月最后一天的 00:00:00 和 23:59:59
// 每个月最后一天的00:00:00
function getLastDayStart(d, timestamp) {
if(!d) return
var current = new Date(d);
var currentMonth = current.getMonth();
var nextMonth = ++currentMonth;
var nextMonthDayOne = new Date(current.getFullYear(), nextMonth, 1);
var minusDate = 1000 * 60 * 60 * 24;
if(!timestamp){
return new Date(nextMonthDayOne.getTime() - minusDate); // 2021-12-31 00:00:00
} else {
return new Date(nextMonthDayOne.getTime() - minusDate).valueOf(); // 1640880000000
}
}
// 每个月最后一天的23:59:59 flag为true
function getLastDayEnd(d, timestamp) {
if(!d) return
var current = new Date(d);
var currentMonth = current.getMonth();
var nextMonth = ++currentMonth;
var nextMonthDayOne = new Date(current.getFullYear(), nextMonth, 1);
var minusDate = 1000;
// timestamp 时间戳
if(!timestamp){
return new Date(nextMonthDayOne.getTime() - minusDate); // 2021-12-31 23:59:59
} else {
return new Date(nextMonthDayOne.getTime() - minusDate).valueOf(); // 1640966399000
}
}
6、某个月第一天的 00:00:00 和 23:59:59
// 某月第一天 00:00:00
function getCurrentMonthFirstStart(time) {
var date = new Date(time)
date.setDate(1)
var oneDay = 1000 * 60 * 60 * 24
// 返回时间戳
// return new Date(new Date(date).toLocaleDateString()).getTime()
// parseTime函数格式化(文章上面封装有)
return parseTime(new Date(new Date(date).toLocaleDateString()).getTime(), '{y}-{m}-{d} {h}:{i}:{s}')
}
// 某月第一天 23:59:59
function getCurrentMonthFirstEnd(time) {
var date = new Date(time)
date.setDate(1)
// 返回时间戳
// return new Date(new Date(date).toLocaleDateString()).getTime()
// parseTime函数格式化(文章上面封装有)
return parseTime(new Date(new Date(date).toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1, '{y}-{m}-{d} {h}:{i}:{s}')
}
// 某月最后一天 00:00:00
function getCurrentMonthLastStart(time) {
var date = new Date(time)
var currentMonth = date.getMonth()
var nextMonth = ++currentMonth
var nextMonthFirstDay = new Date(date.getFullYear(), nextMonth, 1)
var oneDay = 1000 * 60 * 60 * 24
// 返回时间戳
// return (new Date(nextMonthFirstDay - oneDay).getTime())
// parseTime函数格式化(文章上面封装有)
return parseTime((new Date(nextMonthFirstDay - oneDay).getTime()) , '{y}-{m}-{d} {h}:{i}:{s}')
}
// 某月最后一天 23:59:59
function getCurrentMonthLastEnd(time) {
var date = new Date(time)
var currentMonth = date.getMonth()
var nextMonth = ++currentMonth
var nextMonthFirstDay = new Date(date.getFullYear(), nextMonth, 1)
var oneDay = 1000 * 60 * 60 * 24
// 返回时间戳
// return (new Date(nextMonthFirstDay - oneDay).getTime()) + 24 * 60 * 60 * 1000 - 1
// parseTime函数格式化(文章上面封装有)
return parseTime((new Date(nextMonthFirstDay - oneDay).getTime()) + 24 * 60 * 60 * 1000 - 1, '{y}-{m}-{d} {h}:{i}:{s}')
}
console.log(getCurrentMonthFirstStart('2021-12-28'), getCurrentMonthFirstEnd('2021-12-28'));
console.log(getCurrentMonthLastStart('2021-12-28'), getCurrentMonthLastEnd('2021-12-28'));
7、计算两个时间段的时间间隔(x天x时x分x秒)
/**
* params 格式必须如下:
* startTime = '2022-09-21 15:29:20'
* endTime = '2022-10-22 16:59:30'
* */
function getFormatSeconds(startTime, endTime) {
var s1 = new Date(startTime.replace(/-/g, "/"))
var s2 = new Date(endTime.replace(/-/g, "/"))
var runTime = parseInt((s2.getTime() - s1.getTime()) / 1000)
// 86400 24*60*60
var year = Math.floor(runTime / 86400 / 365)
runTime = runTime % (86400 * 365)
var month = Math.floor(runTime / 86400 / 30)
runTime = runTime % (86400 * 30)
var day = Math.floor(runTime / 86400)
runTime = runTime % 86400
var hour = Math.floor(runTime / 3600)
runTime = runTime % 3600
var minute = Math.floor(runTime / 60)
runTime = runTime % 60
var second = runTime
if (year > 0) {
return `${year}年${month}月${day}天${hour}时${minute}分${second}秒`
} else if (month > 0) {
return `${month}月${day}天${hour}时${minute}分${second}秒`
} else if (day > 0) {
return `${day}天${hour}时${minute}分${second}秒`
} else if (hour > 0) {
return `${hour}时${minute}分${second}秒`
} else if (minute > 0) {
return `${minute}分${second}秒`
} else if (second > 0) {
return `${second}秒`
} else if (second == 0) {
return `1秒`
}
}
三、JS算法
1、for循环一秒执行一次
function time(val) {
for (var i = val; i < 10; i++) {
console.log(i);
setTimeout("time(" + ++i + ")", 1000)
break;
}
}
time(0)
function time(val) {
for (var i = val; i < 10; i++) {
console.log(i);
setTimeout(function () {
time(++i)
}, 1000)
break;
}
}
time(0)
或者不用for
let i = 0;
function a() {
if (i < 10) {
setTimeout(function () {
console.log(i);
i++;
a();
}, 1000)
}
};
a();