前端开发小技巧
js篇
一.数值型
-
格式化金钱
- 考虑两位小数,if判断
export function formatNumber(n) {
var b = parseInt(n).toString();
var len = b.length;
if (len <= 3) {
return b;
}
var r = len % 3;
return r > 0 ? b.slice(0, r) + "," + b.slice(r, len).match(/\d{3}/g).join(",") : b.slice(r, len).match(/\d{3}/g).join(",");
}
- 每隔三位数加一个,区分小数
export function formatNumber2(number) {
if (number) {
var num = number.toString()
var numArr = num.split('.')
var [num, dotNum] = numArr
var operateNum = num.split('').reverse()
var result = [],
len = operateNum.length
for (var i = 0; i < len; i++) {
result.push(operateNum[i])
if (((i + 1) % 3 === 0) && (i !== len - #### 1)) {
result.push(',')
}
}
if (dotNum) {
result.reverse().push('.', ...dotNum)
return result.join('')
} else {
return result.reverse().join('')
}
}else{
return 0;
}
}
- 考虑两位小数,正则+replace方法,最实用
const ThousandNum = num => num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
const money = ThousandNum(20190214);
// money => "20,190,214"
-
精确小数
const RoundNum = (num, decimal) => Math.round(num * 10 ** decimal) / 10 ** decimal;
const num = RoundNum(1.69, 1);
// num => 1.7
-
取最小最大值
-
简单数组取最大值-推荐Math.min Math.max
const arr = [0, 1, 2];
const min = Math.min(...arr);
const max = Math.max(...arr);
// min max => 0 2
-
复杂数组,内部包含对象
aa = [{name:"张三",age:18},{name:"李四",age:21},{name:"王五",age:45}];
var bb = new Array();
for(var i=0;i
-
简单数组取最大值的索引-推荐indexOf
var a = [1,2,3,4,5,6,7,7,6,5,4,3,2,1];
// for循环
var indexOfMax = 0;
var tempMax = a[0];
for(let i = 0; i < a.length; i ++){
if(a[i] > tempMax){
tempMax = a[i];
indexOfMax = i;
}
}
// indexOf
var max = Math.max(...a);
var indexOfMax = a.indexOf(max);
// reduce
var indexOfMax = 0;
var max = a.reduce( (a,c,i) => c > a ? (indexOfMax = i,c) : a, 0)
-
复杂数组,内部包含对象-推荐reduce
// json格式
var a = [
{"sid":11478,"floor":1,"x":14,"y":78,"points":5463},
{"sid":13256,"floor":1,"x":32,"y":56,"points":9463},
{"sid":24765,"floor":1,"x":47,"y":65,"points":3256},
{"sid":48352,"floor":1,"x":83,"y":52,"points":7946},
{"sid":28643,"floor":1,"x":86,"y":43,"points":6492}
]
// 找出points最大对象所在的索引
var indexOfMax = 0;
var max = a.reduce( (a,c,i) => c.points > a ? (indexOfMax = i,c.points) : a, 0)
-
内含数组
// csv格式
var a = [
[11478,1,14,78,5463],
[13256,1,32,56,9463],
[17356,1,28,73,6319],
[75863,1,57,63,4257]
]
// 找出points,索引4最大对象所在的索引
var indexOfMax = 0;
var max = a.reduce( (a,c,i) => c[4] > a ? (indexOfMax = i,c[4]) : a, 0)
-
数值精度问题
所有利用IEEE754标准的64位双精度浮点数存储数值型的语言都有这个问题(如:Python),会出现:
console.log(0.1 + 0.2) // 0.30000000000000004
console.log(0.7 + 0.1) // 0.7999999999999999
// ......
可以这样解决
parseFloat((0.1 + 0.2).toFixed(1)) // 0.3
parseFloat((0.7 + 0.1).toFixed(1)) // 0.8
-
获取当前时间戳
由于+单元运算符会发生往数字型的类型转换,所以可以这样获取时间戳
+new Date()
/*
此外还有:
new Date() * 1
new Date().getTime()
Date.now()
*/
二.字符型
-
字符串倒序
字符串倒序就是把字符串倒着排序,可以用下列方法.split('').reverse().join('')
let str = 'abc'
let revStr = str.split('').reverse().join('')
console.log(revStr) // cba
三.数组
-
捣乱数组顺序
let arr = [1,2,3,4,5]
Array.prototype.shuffle = function() {
this.sort(function () {
return Math.random() - #### 0.5
})
}
arr.shuffle()
console.log(arr) // [4, 1, 2, 3, 5]
-
合并数组(数组拼接)
const arr1 = [0, 1, 2];
const arr2 = [3, 4, 5];
const arr = [...arr1, ...arr2];
// arr => [0, 1, 2, 3, 4, 5];
const union = (a, b) => Array.from(new Set([...a, ...b]));
// union([1,2,3], [4,3,2]) -> [1,2,3,4]
-
数组降维
let arr = [[1,2],[3,4]]
// 1
function flatten1(arr) {
return [].concat.apply([], arr)
}
// 2
function flatten2(arr) {
return arr.flat()
}
-
伪数组转真数组
如下所示的,就是一个伪数组
var arrLike = {
length:2,
0:'foo',
1: 'bar'
}
- 用ES6的Array.from
var arrLike = {
length:2,
0:'foo',
1: 'bar'
}
var arr = Array.from(arrLike) // ["foo", "bar"]
- ES5 Array.prototype.slice.call
var arrLike = {
length:2,
0:'foo',
1: 'bar'
}
var arr = Array.prototype.slice.call(arrLike) // ["foo", "bar"]
-
去重数组
const arr = [...new Set([0, 1, 1, null, null])];
// arr => [0, 1, null]
-
截断数组
const arr = [0, 1, 2];
arr.length = 2;
// arr => [0, 1]
-
查找对象在数组里的index
利用findIndex方法
let arr = [
{
name: '小明'
},
{
name: '小红'
}
]
let index = arr.findIndex(item => {
return item.name === '小明'
})
// index 为 0
-
数组浅拷贝(克隆数组)(简单数组,一维数组)
- 推荐...
const _arr = [0, 1, 2];
const arr = [..._arr];
// arr => [0, 1, 2]
- 利用slice()方法
let ls1 = [1,2,3]
let ls2 = ls1.slice()
console.log(ls2 === ls1) // false
- 利用Array.from方法
let ls1 = [1,2,3]
let ls2 = Array.from(ls1)
console.log(ls2 === ls1) // false
- 利用map()方法
let ls1 = [1,2,3]
let ls2 = ls1.map(i=>i)
console.log(ls2 === ls1) // false
- 利用filter()方法
let ls1 = [1,2,3]
let ls2 = ls1.filter(_=>true)
console.log(ls2 === ls1) // false
- 利用values()方法
let ls1 = [1,2,3]
let ls2 = [...ls1.values()]
console.log(ls2 === ls1) // false
- 利用Symbol.iterator方法
let ls1 = [1,2,3]
let ls2 = [...ls1[Symbol.iterator]()]
console.log(ls2 === ls1) // false
注意:以上这些方法深拷贝的只是最外层的数组,如果数组里面有数组或者对象,那些是不会被深拷贝的,所以这些方法只适用于简单的数组
-
reduce简单用法(求和,求乘积)
var arr = [1, 2, 3, 4];
var sum = arr.reduce((x,y)=>x+y)
var mul = arr.reduce((x,y)=>x*y)
// console.log( sum ); //求和,10
// console.log( mul ); //求乘积,2
-
reduce其他高级用法
// (1)计算数组中每个元素出现的次数
返回对象,展示所以的元素出现的次数以key-value保存
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
let nameNum = names.reduce((pre,cur)=>{
if(cur in pre){
pre[cur]++
}else{
pre[cur] = 1
}
return pre
},{})
// console.log(nameNum); //{Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}
返回num,查询单个元素出现的次数
const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0);
// countOccurrences([1,1,2,1,2,3], 1) -> 3
// (2)数组去重 推荐用set
let arr = [1,2,3,4,4,1]
let newArr = arr.reduce((pre,cur)=>{
if(!pre.includes(cur)){
return pre.concat(cur)
}else{
return pre
}
},[])
// console.log(newArr);// [1, 2, 3, 4]
// (3)将二维数组转化为一维 推荐用flat
let arr = [[0, 1], [2, 3], [4, 5]]
let newArr = arr.reduce((pre,cur)=>{
return pre.concat(cur)
},[])
// console.log(newArr); // [0, 1, 2, 3, 4, 5]
// (3)将多维数组转化为一维 推荐用flat
let arr = [[0, 1], [2, 3], [4,[5,6,7]]]
const newArr = function(arr){
return arr.reduce((pre,cur)=>pre.concat(Array.isArray(cur)?newArr(cur):cur),[])
}
// console.log(newArr(arr)); //[0, 1, 2, 3, 4, 5, 6, 7]
// 深度平铺数组,使用递归。 通过空数组([]) 使用 Array.concat() ,结合 展开运算符( ... ) 来平铺数组。 递归平铺每个数组元素。
const deepFlatten = arr => [].concat(...arr.map(v => Array.isArray(v) ? deepFlatten(v) : v));
// deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5]
// 根据指定的 depth 平铺数组,每次递归,使 depth 减 1 。使用 Array.reduce() 和 Array.concat() 来合并元素或数组。默认情况下, depth 等于 1 时停递归。省略第二个参数 depth ,只能平铺1层的深度 (单层平铺)。
const flattenDepth = (arr, depth = 1) =>
depth != 1 ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth(v, depth - 1) : v), [])
: arr.reduce((a, v) => a.concat(v), []);
// flattenDepth([1,[2],[[[3],4],5]], 2) -> [1,2,[3],4,5]
// (4)对象数组里的属性求和
var result = [
{
subject: 'math',
score: 10
},
{
subject: 'chinese',
score: 20
},
{
subject: 'english',
score: 30
}
];
var sum = result.reduce(function(prev, cur) {
return cur.score + prev;
}, 0);
// console.log(sum) //60
// (5)求数字数组的平均数
const average = arr => arr.reduce((acc, val) => acc + val, 0) / arr.length;
// average([1,2,3]) -> 2
Median of array of numbers (获取数字数组的中值)
找到数字数组的中间值,使用 Array.sort()
对值进行排序。如果 length
是奇数,则返回中间值数字,否则返回两个中间值数值的平均值。
JavaScript 代码:
const median = (arr) => {
const mid = Math.floor(arr.length / 2),
nums = arr.sort((a, b) => a - b);
return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2;
};
// median([5,6,50,1,-5]) -> 5
// median([0,10,-2,7]) -> 3.5
-
Array difference (数组比较 得到a存在b不存在的元素)
根据数组 b
创建一个 Set
对象,然后在数组 a
上使用 Array.filter()
方法,过滤出数组 b
中不包含的值。
JavaScript 代码:
const difference = (a, b) => {
const s = new Set(b);
return a.filter((x) => !s.has(x));
};
// difference([1,2,3], [1,2]) -> [3]
-
Array intersection (数组交集 得到ab都存在的元素)
根据数组 b
创建一个 Set
对象,然后在数组 a
上使用 Array.filter()
方法,只保留数组 b
中也包含的值。
JavaScript 代码:
const intersection = (a, b) => {
const s = new Set(b);
return a.filter((x) => s.has(x));
};
// intersection([1,2,3], [4,3,2]) -> [2,3]
const similarity = (arr, values) => arr.filter(v => values.includes(v));
// similarity([1,2,3], [1,2,4]) -> [1,2]
Compact (过滤掉数组中所有假值元素)
使用 Array.filter()
过滤掉数组中所有 假值元素 (false
, null
, 0
, ""
, undefined
, and NaN
)。
JavaScript 代码:
const compact = (arr) => arr.filter((v) => v);
// compact([0, 1, false, 2, '', 3, 'a', 'e'*23, NaN, 's', 34]) -> [ 1, 2, 3, 'a', 's', 34 ]
Pick(提取)
使用 Array.reduce()
只 过滤 / 萃取 出 arr 参数指定 key (如果 key 存在于 obj 中) 的属性值,。
JavaScript 代码:
const pick = (obj, arr) =>
arr.reduce(
(acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc),
{}
);
// pick({ 'a': 1, 'b': '2', 'c': 3 }, ['a', 'c']) -> { 'a': 1, 'c': 3 }
Shuffle array (随机排列数组)
使用 Array.sort()
来重新排序元素,比较器中使用 Math.random()
。
JavaScript 代码:
const shuffle = (arr) => arr.sort(() => Math.random() - 0.5);
// shuffle([1,2,3]) -> [2,3,1]
四.数据类型
-
判断js的数据类型
- 第一种
function DataType(tgt, type) {
const dataType = Object.prototype.toString.call(tgt).replace(/\[object (\w+)\]/, "$1").toLowerCase();
return type ? dataType === type : dataType;
}
DataType("young"); // "string"
DataType(20190214); // "number"
DataType(true); // "boolean"
DataType([], "array"); // true
DataType({}, "array"); // false
- 第二种
function getType(x){
return Object.prototype.toString.call(x).slice(8,-1)
}
- 具体类型
Is array(是否为数组)
使用 Array.isArray()
来检查一个值是否为一个数组。
JavaScript 代码:
const isArray = (val) => !!val && Array.isArray(val);
// isArray(null) -> false
// isArray([1]) -> true
Is boolean(是否为布尔值)
使用 typeof
来检查一个值是否为一个布尔值。
JavaScript 代码:
const isBoolean = (val) => typeof val === "boolean";
// isBoolean(null) -> false
// isBoolean(false) -> true
Is function(是否为函数)
使用 typeof
来检查一个值是否为一个函数。
JavaScript 代码:
const isFunction = (val) => val && typeof val === "function";
// isFunction('x') -> false
// isFunction(x => x) -> true
Is number(是否为数字)
使用 typeof
来检查一个值是否为一个数字。
JavaScript 代码:
const isNumber = (val) => typeof val === "number";
// isNumber('1') -> false
// isNumber(1) -> true
Is string(是否为字符串)
使用 typeof
来检查一个值是否为一个字符串。
JavaScript 代码:
const isString = (val) => typeof val === "string";
// isString(10) -> false
// isString('10') -> true
Is symbol(是否为 symbol)
使用 typeof
来检查一个值是否为一个 symbol 。
JavaScript 代码:
const isSymbol = (val) => typeof val === "symbol";
// isSymbol('x') -> false
// is
-
是否为空对象
const obj = {};
const flag = DataType(obj, "object") && !Object.keys(obj).length;
// flag => true
其他
-
交换赋值 使用的是ES6解构的知识
let a = 0;
let b = 1;
[a, b] = [b, a];
// a b => 1 0
-
克隆对象
const _obj = { a: 0, b: 1, c: 2 }; // 以下方法任选一种
const obj = { ..._obj };
const obj = JSON.parse(JSON.stringify(_obj));
// obj => { a: 0, b: 1, c: 2 }
-
合并对象
const obj1 = { a: 0, b: 1, c: 2 };
const obj2 = { c: 3, d: 4, e: 5 };
const obj = { ...obj1, ...obj2 };
// obj => { a: 0, b: 1, c: 3, d: 4, e: 5 }
-
数组内的值求和 推荐使用reduce
export function sumArr(arr) {
if(arr&&arr.length>0){
var a=0
for(let b of arr){
a+=b
}
return a;
}else{
return 0
}
}
var sum = arr.reduce((x,y)=>x+y) // 求和
var sum = arr.reduce((x,y)=>x*y) // 求积
-
大数截取个位数的数据(结合类名实现布局效果)
isShow(obj) {
obj = obj.toString();
// 只取个位数
let str = obj.charAt(obj.length - #### 1);
let arry = ["0", "2", "4", "6", "8", "10"];
if (arry.indexOf(str) > -1) {
return true;
} else {
return false;
}
}
&.device_cell1 {
background-color: #f0f4f5;
}
-
随机验证码
- 四位数字
Math.random().toString().slice(2,6)
// or
(Math.random() * 9999).toFixed()
- 四位数字加字母
Math.random().toString(16).slice(2,6).toUpperCase()
-
Number to array of digits (将数字转化为整数数组)
将数字转换为字符串,使用 split()
来转换构建一个数组。 使用 Array.map()
和 parseInt()
将每个值转换为整数。
JavaScript 代码:
const digitize = (n) => ("" + n).split("").map((i) => parseInt(i));
// digitize(2334) -> [2, 3, 3, 4]
-
URL parameters(网址参数)
通过适当的正则表达式,使用 match()
来获得所有的键值对, Array.reduce()
来映射和组合成一个单一的对象。将 location.search
作为参数传递给当前 url
。
JavaScript 代码:
const getUrlParameters = (url) =>
url
.match(/([^?=&]+)(=([^&]*))/g)
.reduce(
(a, v) => (
(a[v.slice(0, v.indexOf("="))] = v.slice(v.indexOf("=") + 1)), a
),
{}
);
// getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'}
-
UUID generator (UUID 生成器)
使用 crypto
API 生成符一个 UUID,符合 RFC4122 版本 4 。
JavaScript 代码:
const uuid = (_) =>
([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) =>
(
c ^
(crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))
).toString(16)
);
// uu