JS的6个”假”值

null false undefined 0 ''(空字符串) NaN

typeof的结果

  1. typeof(null) //"object"
  2. typeof(undefined) //"undefined"
  3. typeof(NaN) //"number"
  4. typeof(0) // "number"
  5. typeof('aaa') //"string"
  6. typeof(function fn(){}) //"function"
  7. typeof(false) //"boolean"
  8. typeof({}) //"object"
  9. typeof(new Date()) //"object"
  10. typeof(new String('a')) //"object"

number排序

  1. const sortNumbers = (...numbers) => numbers.sort(); //排序,只适合正数
  2. [1,2,3,4].sort((a, b) => a - b); // [1, 2,3,4],默认是升序
  3. [1,2,3,4].sort((a, b) => b - a); // [4,3,2,1] 降序

一维数组去重思路

  1. const s = new Set();
  2. [2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));
  3. for (let i of s) {
  4. console.log(i);
  5. }
  6. // 2 3 5 4
  7. -----------------------------------
  8. const set = new Set([1, 2, 3, 4, 4]);
  9. [...set]
  10. //[1,2,3,4]
  11. -----------------------------------
  12. [...new Set('ababbc')].join('')
  13. -----------------------------------
  14. // 数组去重
  15. [...new Set(arr)]
  16. -----------------------------------
  17. let arr = [1, 2, 2, 3, 4, 5, 5, 6];
  18. let newArr =Array.from(new Set(arr))
  19. console.log(newArr)
  20. // "abc"

数组对象去重

  1. const uniqueElementsBy = (arr, fn) =>arr.reduce((acc, v) => {if (!acc.some(x => fn(v, x))) acc.push(v);return acc;}, []);
  2. uniqueElementsBy([{id: 1, name: 'Jhon'}, {id: 2, name: 'sss'}, {id: 1, name: 'Jhon'}], (a, b) => a.id == b.id)
  3. // [{id: 1, name: 'Jhon'}, {id: 2, name: 'sss'}]

生成连续数组

  1. //有起始
  2. function generateArray (start, end) {
  3. return Array.from(new Array(end + 1).keys()).slice(start)
  4. }
  5. //有最大值
  6. [...new Array(10).keys()] //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  7. Array.from({length:10},(item, index)=> index+1) //[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

删除数组一个元素

  1. const deleteFromArr = (arr, item) => {
  2. let index = arr.indexOf(item);
  3. return index !== -1 && arr.splice(index, 1);
  4. };
  5. deleteFromArr(arr, n);

根据条件删除数组元素

  1. const dropElements = (arr, func) => {
  2. while (arr.length > 0 && !func(arr[0])) arr = arr.slice(1);
  3. return arr;
  4. };
  5. dropElements([1, 2, 3, 4], n => n >= 3); // [3,4]

删除数组指定值(改变原数组)

使用 Array.filter()Array.includes() 来剔除指定的值。使用 Array.length = 0 将数组中的长度重置为零,并且通过 Array.push() 只使用 pulled 值重新填充数组。

  1. const pull = (arr, ...args) => {
  2. let argState = Array.isArray(args[0]) ? args[0] : args;
  3. let pulled = arr.filter((v, i) => !argState.includes(v));
  4. arr.length = 0;
  5. pulled.forEach(v => arr.push(v));
  6. };
  7. let myArray = ['a', 'b', 'c', 'a', 'b', 'c'];
  8. pull(myArray, 'a', 'c'); // myArray = [ 'b', 'b' ]

获取日期组合

创建过去七天的数组,如果将代码中的减号换成加号,你将得到未来7天的数组集合

  1. // 创建过去七天的数组
  2. [...Array(7).keys()].map(days => new Date(Date.now() - 86400000 * days));

生成随机ID,随机字符串

substring() 的第二个参数控制取多少位 (最多可取13位)

  1. // 生成长度为11的随机字母数字字符串
  2. Math.random().toString(36).substring(2);
  3. // hg7znok52x

生成指定范围随机数

  1. /**
  2. * @param { number } min
  3. * @param { number } max
  4. */
  5. export const RandomNum = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;

获取URL的查询参数

  1. ?foo=bar&baz=bing => {foo: bar, baz: bing}
  2. // 获取URL的查询参数
  3. q={};location.search.replace(/([^?&=]+)=([^&]+)/g,(_,k,v)=>q[k]=v);q;

本地时间

  1. // 创建本地时间
  2. <body onload="setInterval(()=>document.body.innerHTML=new Date().toLocaleString().slice(10,19))"></body>

返回当前24小时制时间的字符串

  1. const getColonTimeFromDate = date => date.toTimeString().slice(0, 8);
  2. getColonTimeFromDate(new Date()); // "08:38:00"
  3. console.log(getColonTimeFromDate(new Date()).replace(/:/g,'-')) // 10-12-13 替换:为 -

数组混淆

随机更改数组元素顺序,混淆数组

  1. // 随机更改数组元素顺序,混淆数组
  2. (arr) => arr.slice().sort(() => Math.random() - 0.5)
  3. /*
  4. let a = (arr) => arr.slice().sort(() => Math.random() - 0.5)
  5. let b = a([1,2,3,4,5])
  6. console.log(b)
  7. */

数组清空

  1. const arr = [0, 1, 2];
  2. arr.length = 2;
  3. // arr => [0, 1]

解构交换赋值

  1. let a = 0;
  2. let b = 1;
  3. [a, b] = [b, a];
  4. // a b => 1 0

数组解构赋值

  1. var arr = ['bob',29,'student']
  2. const [name,age,type] = arr
  3. // name => bob

解构赋值综合

  1. var a, b, rest;
  2. [a, b] = [10, 20];
  3. console.log(a); // 10
  4. [a, b, ...rest] = [10, 20, 30, 40, 50];
  5. console.log(a); // 10
  6. console.log(b); // 20
  7. console.log(rest); // [30, 40, 50]
  8. //对象解构
  9. ({ a, b } = { a: 10, b: 20 });
  10. console.log(a); // 10
  11. //结构别名
  12. const obj = {
  13. name: 'bob',
  14. age: 22
  15. }
  16. const { name: userName, age: userAge } = obj;
  17. console.log(userName, userAge); // bob 22
  18. // Stage 4(已完成)提案中的特性
  19. ({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
  20. console.log(a); // 10
  21. console.log(b); // 20
  22. console.log(rest); // {c: 30, d: 40}
  23. //传给函数的参数
  24. const person = {
  25. name: 'bob',
  26. age: 22
  27. }
  28. function introduce({ name, age }) {
  29. console.log(`我是 ${name} ,今天 ${age} 岁了!`);
  30. }
  31. console.log(introduce(person));// 我是 bob ,今天 22 岁了!

对象 和数组转换

  1. Object.keys({name:'张三',age:14}) //['name','age']
  2. Object.values({name:'张三',age:14}) //['张三',14]
  3. Object.entries({name:'张三',age:14}) //[[name,'张三'],[age,14]]
  4. Object.fromEntries([name,'张三'],[age,14]) //ES10的api,Chrome不支持 , firebox输出{name:'张三',age:14}

生成随机十六进制代码(生成随机颜色)

使用JavaScript简洁代码生成随机十六进制代码

  1. // 生成随机十六进制代码 如:'#c618b2'
  2. const RandomColor = () => "#" + Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, "0");
  3. const color = RandomColor();
  4. // color => "#f03665"

filter() 过滤不符合项

  1. let arr = [1,2,3]
  2. let newArr = arr.filter(item => item>=3)
  3. console.log(newArr)

filter() 去掉空字符串、undefined、null

  1. let arr = ['','1','2',undefined,'3.jpg',undefined]
  2. let newArr = arr.filter(item => item)
  3. console.log(newArr)

filter 过滤空值:undefined、null、””、0、false、NaN

  1. const arr = [undefined, null, "", 0, false, NaN, 1, 2].filter(Boolean);
  2. // arr => [1, 2]

filter过滤数组空位

  1. [1,2,3,4,5,,6,,7].length //9
  2. [1,2,3,4,5,,6,,7].filter(el=> el).length //7

filter() 数组去重

  1. let arr = [1, 2, 2, 3, 4, 5, 5, 6];
  2. let newArr = arr.filter((x, index,self)=>self.indexOf(x)===index)
  3. console.log(newArr)

set数组去重

  1. function dedupe(array) {
  2. return Array.from(new Set(array));
  3. }
  4. dedupe([1, 1, 2, 3]) // [1, 2, 3]
  5. const distinctValuesOfArray = arr => [...new Set(arr)];
  6. distinctValuesOfArray([1, 2, 2, 3, 4, 4, 5]); // [1,2,3,4,5]

filter() 筛选数组对象

  1. let arr = [
  2. {a:'苹果',b:'面包',c:'吃'},
  3. {a:'香蕉',b:'面包',c:'不吃'},
  4. {a:'香蕉',b:'苹果',c:'吃'},
  5. {a:'苹果',b:'香蕉',c:'不吃'},
  6. ]
  7. console.log(arr.filter(item => item.a=== '苹果' ))//[{a:'苹果',b:'面包',c:'吃'},{a:'苹果',b:'香蕉',c:'不吃'}]

map数组映射 // from 也可以

  1. var users = [
  2. { name : "Yagyu",weapon:"shuriken"},
  3. { name : "Yoshi",weapon:"katana"},
  4. { name : "Kuma",weapon:"wakizashi"}
  5. ];
  6. const mapUsers = users.map(obj => obj.name) // [ 'Yagyu', 'Yoshi', 'Kuma' ]
  7. const fromUsers = Array.from(users, ({name}) => name) // [ 'Yagyu', 'Yoshi', 'Kuma' ]

window.location.search 转 JS 对象

  1. //`https://www.baidu.com?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=js&rsv_pq=a86b5e5f0007bceb&rsv_t=1e1fAVan%2BVlnkhJHFB0BIGLdLM2slszYMJBTTfFkmyyBUzBpw0ggeuVDE50&rqlang=cn&rsv_enter=0&inputT=1287&rsv_sug3=5&rsv_sug1=3&rsv_sug7=101&rsv_sug2=0&rsv_sug4=1907`
  2. const searchObj = search => JSON.parse(`{"${decodeURIComponent(search.substring(1)).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"')}"}`);
  3. let search = '?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=js&rsv_pq=a86b5e5f0007bceb&rsv_t=1e1fAVan%2BVlnkhJHFB0BIGLdLM2slszYMJBTTfFkmyyBUzBpw0ggeuVDE50&rqlang=cn&rsv_enter=0&inputT=1287&rsv_sug3=5&rsv_sug1=3&rsv_sug7=101&rsv_sug2=0&rsv_sug4=1907'
  4. let obj = searchObj(search)
  5. {
  6. ie: 'utf-8',
  7. f: '8',
  8. rsv_bp: '1',
  9. rsv_idx: '1',
  10. tn: 'baidu',
  11. wd: 'js',
  12. rsv_pq: 'a86b5e5f0007bceb',
  13. rsv_t: '1e1fAVan+VlnkhJHFB0BIGLdLM2slszYMJBTTfFkmyyBUzBpw0ggeuVDE50',
  14. rqlang: 'cn',
  15. rsv_enter: '0',
  16. inputT: '1287',
  17. rsv_sug3: '5',
  18. rsv_sug1: '3',
  19. rsv_sug7: '101',
  20. rsv_sug2: '0',
  21. rsv_sug4: '1907'
  22. }

直接获取location.search某参数

  1. const params = new URLSearchParams(location.search.replace(/\?/ig, "")); // location.search = "?name=yajun&sex=female"
  2. params.has("yajun"); // true
  3. params.get("sex"); // "female"

JS 对象转 url 查询字符串

  1. const objectToQueryString = (obj) => Object.keys(obj).map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`).join('&');
  2. objectToQueryString({name: 'Jhon', age: 18, address: 'beijing'})
  3. // name=Jhon&age=18&address=beijing

一维数组交集

  1. const similarity = (arr, values) => arr.filter(v => values.includes(v));
  2. similarity([1, 2, 3], [1, 2, 4]); // [1,2]

二维对象数组交集/差集

  1. let a = [
  2. { id: 1, name: '1' },
  3. { id: 2, name: '2' },
  4. { id: 3, name: '3' },
  5. { id: 4, name: '4' },
  6. { id: 5, name: '5' },
  7. { id: 6, name: '6' },
  8. { id: 7, name: '7' },
  9. { id: 8, name: '8' },
  10. { id: 9, name: '9' },
  11. { id: 10, name: '10' }
  12. ];
  13. let b = [
  14. { id: 4, name: '4' },
  15. { id: 5, name: '5' },
  16. { id: 6, name: '6' },
  17. { id: 7, name: '7' },
  18. { id: 8, name: '8' }
  19. ];
  20. const c = (arr1, arr2, id) => {
  21. let arr = [];
  22. for(let item of arr1){
  23. if(arr2.find(v => v[id] === item[id])) {
  24. arr.push(item);
  25. }
  26. }
  27. return arr;
  28. }
  29. const d = (arr1, arr2, id) => {
  30. let arr = [];
  31. for(let item of arr1){
  32. if(arr2.find(v => v[id] === item[id])) {
  33. continue;
  34. }
  35. arr.push(item);
  36. }
  37. return arr;
  38. }
  39. console.log(c(a, b, 'id')); //交集
  40. console.log(d(a, b, 'id')); //差集

二维纯数组交集

  1. //方法1
  2. const similar = function(arrs) {
  3. var arr = arrs.shift();
  4. for(var i=arrs.length;i--;){
  5. var p = {"boolean":{}, "number":{}, "string":{}}, obj = [];
  6. arr = arr.concat(arrs[i]).filter(function (x) {
  7. var t = typeof x;
  8. return !((t in p) ? !p[t][x] && (p[t][x] = 1) : obj.indexOf(x) < 0 && obj.push(x));
  9. });
  10. if(!arr.length) return null;
  11. }
  12. return arr;
  13. }
  14. //方法2
  15. const similar = function getTheSame(arr) {
  16. return arr.reduce(function(a, b) {
  17. return a.filter(function(item) {
  18. return b.includes(item);
  19. });
  20. });
  21. }
  22. console.log(similar([[1,2,3,5], [2,3,4], [2,3], [2,3,6,7]])) //[2,3]
  23. console.log(similar([[0,1,2,3,5],[-1,1,4,5,6,7],[1,2,3,5,6]])) //[1,5]

两(yyyy-MM-dd)日期时间差

  1. const getDaysDiffBetweenDates = (dateInitial, dateFinal) => (dateFinal - dateInitial) / (1000 * 3600 * 24);
  2. getDaysDiffBetweenDates(new Date('2017-12-13'), new Date('2017-12-22'));
  3. // 9

判断dom是否有某个className

  1. const hasClass = (el, className) => new RegExp(`(^|\\s)${className}(\\s|$)`).test(el.className);

是否为空数组

  1. const arr = [];
  2. const flag = Array.isArray(arr) && !arr.length;
  3. // flag => true

是否为数组

  1. function isArray(obj){
  2. return Object.prototype.toString.call(obj) === '[object Array]' ;
  3. }

数组首部插入成员

  1. let arr = [1, 2]; // 以下方法任选一种
  2. arr.unshift(0);
  3. arr = [0].concat(arr);
  4. arr = [0, ...arr];
  5. // arr => [0, 1, 2]

统计数组成员个数

  1. const arr = [0, 1, 1, 2, 2, 2];
  2. const count = arr.reduce((t, c) => {
  3. t[c] = t[c] ? ++ t[c] : 1;
  4. return t;
  5. }, {});
  6. // count => { 0: 1, 1: 2, 2: 3 }

是否为空对象

  1. const obj = {};
  2. const flag = DataType(obj, "object") && !Object.keys(obj).length;
  3. // flag => true

isType

  1. let isType = type => obj => {
  2. return Object.prototype.toString.call( obj ) === '[object ' + type + ']';
  3. }
  4. isType('String')('123'); // true
  5. isType('Array')([1, 2, 3]); // true
  6. isType('Number')(123); // true

多重三元

  1. export function toString (val: any): string {
  2. return val == null
  3. ? ''
  4. : typeof val === 'object'
  5. ? JSON.stringify(val, null, 2)
  6. : String(val)
  7. }
  8. //解析
  9. export function toString (val: any): string {
  10. return 当变量值为 null
  11. ? 返回空字符串
  12. : 否则,判断当变量类型为 object
  13. ? 返回 JSON.stringify(val, null, 2)
  14. : 否则 String(val)
  15. }

Object.is()判断两个值是否相等

  1. Object.is('foo', 'foo'); // true
  2. Object.is(window, window); // true
  3. Object.is('foo', 'bar'); // false
  4. Object.is([], []); // false
  5. var foo = { a: 1 };
  6. var bar = { a: 1 };
  7. Object.is(foo, foo); // true
  8. Object.is(foo, bar); // false
  9. Object.is(null, null); // true
  10. // 特例
  11. Object.is(0, -0); // false
  12. Object.is(0, +0); // true
  13. Object.is(-0, -0); // true
  14. Object.is(NaN, 0/0); // true

判断数据类型

undefined、null、string、number、boolean、array、object、symbol、date、regexp、function、asyncfunction、arguments、set、map、weakset、weakmap

  1. function DataType(tgt, type) {
  2. const dataType = Object.prototype.toString.call(tgt).replace(/\[object /g, "").replace(/\]/g, "").toLowerCase();
  3. return type ? dataType === type : dataType;
  4. }
  5. DataType("yajun"); // "string"
  6. DataType(19941112); // "number"
  7. DataType(true); // "boolean"
  8. DataType([], "array"); // true
  9. DataType({}, "array"); // false

判断是否null或undefined

  1. const isNil = val => val === undefined || val === null;
  2. isNil(null); // true
  3. isNil(undefined); // true

验证是否json字符串

  1. const isValidJSON = str => {
  2. try {
  3. JSON.parse(str);
  4. return true;
  5. } catch (e) {
  6. return false;
  7. }
  8. };

对象字面量(获取环境变量时必用此方法)

  1. const env = "prod";
  2. const link = {
  3. dev: "Development Address",
  4. test: "Testing Address",
  5. prod: "Production Address"
  6. }[env];
  7. // link => "Production Address"

对象变量属性(可变属性名1)

  1. const flag = false;
  2. const obj = {
  3. a: 0,
  4. b: 1,
  5. [flag ? "c" : "d"]: 2
  6. };
  7. // obj => { a: 0, b: 1, d: 2 }

动态属性名(可变属性名2)

  1. const dynamic = 'email';
  2. let user = {
  3. name: 'John',
  4. [dynamic]: 'john@doe.com'
  5. }
  6. console.log(user); // outputs { name: "John", email: "john@doe.com" }

有条件的对象属性

  1. nst getUser = (emailIncluded) => {
  2. return {
  3. name: 'John',
  4. surname: 'Doe',
  5. ...emailIncluded && { email : 'john@doe.com' }
  6. }
  7. }
  8. const user = getUser(true);
  9. console.log(user); // outputs { name: "John", surname: "Doe", email: "john@doe.com" }
  10. const userWithoutEmail = getUser(false);
  11. console.log(userWithoutEmail); // outputs { name: "John", surname: "Doe" }

对象匹配赋值 ,obj2属性值来自obj1相同属性的值

  1. var obj1 = {
  2. name:'bob',
  3. age:21,
  4. gender:1,
  5. hobby:'song'
  6. }
  7. var obj2 = {
  8. name:'',
  9. age:''
  10. }
  11. Object.keys(obj1).forEach((key) => {
  12. if(key in obj2) {
  13. obj2[key] = obj1[key]
  14. }
  15. })
  16. console.log(obj2)
  17. //{ name: 'bob', age: 21 }
  18. //在确定需要哪些属性值的情况下,针对属性值数量上的不同可以采取解构赋值的方法
  19. let obj3 = { name:userName,age } = obj1
  20. console.log(userName) //bob
  21. console.log(age) //21
  22. let obj4 = {...obj1,isLogin:false} //浅拷贝并添加新属性
  23. //{ name: 'bob', age: 21, gender: 1, hobby: 'song', isLogin: false }
  24. let {hobby,...filterInfo} = obj1 //去除hobby
  25. console.log(filterInfo) //{ name: 'bob', age: 21, gender: 1 }

删除对象无用属性(扩展运算符)

  1. const obj = { a: 0, b: 1, c: 2 }; // 只想拿b和c
  2. const { a, ...rest } = obj;
  3. // rest => { b: 1, c: 2 }

es6隐式返回值

  1. const Func = function(name) {
  2. return "I Love " + name;
  3. };
  4. // 换成
  5. const Func = name => "I Love " + name;

检测非空参数

创建方法时方式使用者忽略掉必要的参数

  1. function IsRequired() {
  2. throw new Error("param is required");
  3. }
  4. function Func(name = IsRequired()) {
  5. console.log("I Love " + name);
  6. }
  7. Func(); // "param is required"
  8. Func("雅君妹纸"); // "I Love 雅君妹纸"

优雅处理错误信息

  1. try {
  2. Func();
  3. } catch (e) {
  4. location.href = "https://stackoverflow.com/search?q=[js]+" + e.message;
  5. }

优雅处理Async/Await参数

  1. function AsyncTo(promise) {
  2. return promise.then(data => [null, data]).catch(err => [err]);
  3. }
  4. const [err, res] = await AsyncTo(Func());

存取LocalStorage:反序列化取,序列化存(JSON)

  1. const love = JSON.parse(localStorage.getItem("love"));
  2. localStorage.setItem("love", JSON.stringify("I Love 雅君妹纸"));

自调用函数

  1. (function(){
  2. // 置于此处的代码将自动执行
  3. })();
  4. (function(a,b){
  5. var result = a+b;
  6. return result;
  7. })(10,20)

从数组种随机获取成员

  1. var items = [12, 548 , 'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' , 2145 , 119];
  2. var randomItem = items[Math.floor(Math.random() * items.length)];

字符串去空格

  1. String.prototype.trim = function(){return this.replace(/^\s+|\s+$/g, "");};

获取数组最大/最小值

  1. var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];
  2. var maxInNumbers = Math.max.apply(Math, numbers);
  3. var minInNumbers = Math.min.apply(Math, numbers);
  4. const maxElementsFromArray = (array, number = 1) => [...array].sort((x, y) => y -x).slice(0, number)
  5. // 事例
  6. maxElementsFromArray([1, 2, 3, 4, 5]) // [5]
  7. maxElementsFromArray([7, 8, 9, 10, 10], 2) // [10, 10]

不要直接从数组中delete或remove元素

精确到指定位数的小数

  1. const round = (n, decimals = 0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`)
  2. round(1.345, 2) // 1.35
  3. round(1.345, 1) // 1.3

数字补零操作

  1. const addZero1 = (num, len = 2) => (`0${num}`).slice(-len)
  2. const addZero2 = (num, len = 2) => (`${num}`).padStart( len , '0')
  3. addZero1(3) // '03'
  4. addZero2(32,4) // '0032'

统计数组中相同项的个数

  1. var cars = ['BMW','Benz', 'Benz', 'Tesla', 'BMW', 'Toyota'];
  2. var carsObj = cars.reduce(function (obj, name) {
  3. obj[name] = obj[name] ? ++obj[name] : 1;
  4. return obj;
  5. }, {});
  6. carsObj; // => { BMW: 2, Benz: 2, Tesla: 1, Toyota: 1 }

接收函数返回的多个结果

  1. async function getFullPost(){
  2. return await Promise.all([
  3. fetch('/post'),
  4. fetch('/comments')
  5. ]);
  6. }
  7. const [post, comments] = getFullPost();

将数组平铺到指定深度

  1. const flatten = (arr, depth = 1) =>
  2. depth != 1
  3. ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flatten(v, depth - 1) : v), [])
  4. : arr.reduce((a, v) => a.concat(v), []);
  5. flatten([1, [2], 3, 4]); // [1, 2, 3, 4]
  6. flatten([1, [2, [3, [4, 5], 6], 7], 8], 2); // [1, 2, 3, [4, 5], 6, 7, 8]

数组扁平化

  1. let arr = [1,2,3,[4,5,6,[7,8]]]
  2. let arrStr = JSON.stringgify(arr)
  3. arr.flat(Infinity) // [1, 2, 3, 4, 5, 6, 7, 8]
  4. arrStr.replace(/(\[|\])/g,'').split(',') // [1, 2, 3, 4, 5, 6, 7, 8]
  5. //只要有一个元素有数组,那么循环继续
  6. while (ary.some(Array.isArray())) {
  7. ary = [].concat(...ary);
  8. }

reduce求和

  1. result = [
  2. {subject: 'math',score: 88},
  3. {subject: 'chinese',score: 95},
  4. {subject: 'english',score: 90}
  5. ];
  6. var sum = result.reduce(function(prev, cur) {
  7. return cur.score + prev;
  8. }, 0);

reduce求和1

  1. let shoppingCart = [
  2. { productTitle: "Product 1", amount: 10 },
  3. { productTitle: "Product 2", amount: 30 },
  4. { productTitle: "Product 3", amount: 20 },
  5. { productTitle: "Product 4", amount: 60 }
  6. ];
  7. const sumAmount = (currentTotalAmount, order) => currentTotalAmount + order.amount;
  8. const getTotalAmount = (shoppingCart) => shoppingCart.reduce(sumAmount, 0);
  9. getTotalAmount(shoppingCart); // 120

eval对一维数组求和的骚操作

  1. eval(arr.join("+"))

数组中某元素出现次数

  1. function countOccurrences(arr, value) {
  2. return arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0);
  3. }
  4. let arr = [1,2,3,4,1,2,4]
  5. countOccurrences(arr, 1) // 2

数组分页算法

  1. data.slice([每页数据量 *(当前页码 - 1), 每页数据量 *(当前页码 - 1 + 每页数据量])

根据数组中某一属性排序

  1. // 本例根据publishTime排序
  2. let data = [
  3. {
  4. id: 1,
  5. publishTime: "2019-05-14 18:10:29"
  6. },
  7. {
  8. id: 2,
  9. publishTime: "2019-05-14 18:17:29"
  10. },
  11. {
  12. id: 3,
  13. publishTime: "2019-05-14 15:09:25"
  14. }]
  15. data.sort((a, b) => b.publishTime - a.publishTime);
  16. // 0: {id: 2, publishTime: "2019-05-14 18:17:29"}
  17. // 1: {id: 1, publishTime: "2019-05-14 18:10:29"}
  18. // 2: {id: 3, publishTime: "2019-05-14 15:09:25"}

对象合并

  1. //ES6方法
  2. let obj1 = {
  3. a:1,
  4. b:{
  5. b1:2
  6. }
  7. }
  8. let obj2 = {
  9. c:3,
  10. d:4
  11. }
  12. console.log({...obj1, ...obj2}) // {a: 1, b: {…}, c: 3, d: 4}
  13. // Obj.assign():可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象
  14. let o1 = { a: 1 };
  15. let o2 = { b: 2 };
  16. let obj = Object.assign(o1, o2);
  17. console.log(obj); // { a: 1, b: 2 }
  18. console.log(o1); // { a: 1, b: 2 }, 且 **目标对象** 自身也会改变(也就是assign第一个对象)
  19. console.log(o2); // { b: 2 } 不改变
  20. // 备注:Object.assign() 拷贝的是属性值。假如源对象的属性值是一个指向对象的引用,它也只拷贝那个引用值
  21. // 备注:数组合并用 concat() 方法

对象数组每一项添加新属性

  1. var arry= [{a:11,b:22,c:33,d:44},{a:11,b:0,c:0,d:44},{a:11,b:22,c:99,d:99}];
  2. var arry2=[];
  3. arry.map(((item, index)=> {
  4. arry2.push(Object.assign({},item,{mess1:item.c,mess2:item.d}))
  5. }))
  6. // arry2 -> [{"a":11,"b":22,"c":33,"d":44,"mess1":33,"mess2":44},{"a":11,"b":0,"c":0,"d":44,"mess1":0,"mess2":44},{"a":11,"b":22,"c":99,"d":99,"mess1":99,"mess2":99}]
  7. var users = [
  8. { name : "Yagyu",weapon:"shuriken"},
  9. { name : "Yoshi",weapon:"katana"},
  10. { name : "Kuma",weapon:"wakizashi"}
  11. ];
  12. const addNewArgs = users.map((el,index) => {
  13. return Object.assign(el,{age:20})
  14. })
  15. //addNewArgs -> [{ name: 'Yagyu', weapon: 'shuriken', age: 20 },{ name: 'Yoshi', weapon: 'katana', age: 20 },{ name: 'Kuma', weapon: 'wakizashi', age: 20 }]

根据键值将一个对象的值映射到另一个数组对象中

  1. var obj ={
  2. apple: 1,
  3. banana:2,
  4. li:30
  5. }
  6. var arr = [
  7. {id:'1',text:'苹果',key:'apple', value:''},
  8. {id:'2',text:'梨', key:'li',value:''},
  9. {id:'3',text:'香蕉', key:'banana', value:''}
  10. ]
  11. const newArr = arr.map(o => {
  12. o.value = obj[o.key]
  13. return o
  14. })

根据索引将一个数组的值映射到另一个数组对象中

  1. var arr = [
  2. {id:'1',text:'苹果',key:'apple', value:''},
  3. {id:'2',text:'梨', key:'li',value:''},
  4. {id:'3',text:'香蕉', key:'banana', value:''}
  5. ]
  6. var arr1 = [1,2,1]
  7. arr.map((el,index)=>{
  8. el.value = arr1[index]
  9. })

将一个对象数组数据拿出来变成另一个对象

  1. var arry= [{a:11,b:22,c:33,d:44},{a:11,b:0,c:0,d:44},{a:11,b:22,c:99,d:99}];
  2. var arry2=[];
  3. arry.map(((item, index)=> {
  4. arry2.push(Object.assign({},{mess1:item.c,mess2:item.d}))
  5. }))
  6. // arry2 -> [{"mess1":33,"mess2":44},{"mess1":0,"mess2":44},{"mess1":99,"mess2":99}]

对象中属性个数

  1. let obj = {name: '朱昆鹏', age: 21}
  2. // ES6
  3. Object.keys(obj).length // 2
  4. // ES5
  5. let attributeCount = obj => {
  6. let count = 0;
  7. for(let i in obj) {
  8. if(obj.hasOwnProperty(i)) { // 建议加上判断,如果没有扩展对象属性可以不加
  9. count++;
  10. }
  11. }
  12. return count;
  13. }
  14. attributeCount(obj) // 2

全屏

  1. //进入全屏
  2. function launchFullscreen(element) {
  3. if (element.requestFullscreen) {
  4. element.requestFullscreen()
  5. } else if (element.mozRequestFullScreen) {
  6. element.mozRequestFullScreen()
  7. } else if (element.msRequestFullscreen) {
  8. element.msRequestFullscreen()
  9. } else if (element.webkitRequestFullscreen) {
  10. element.webkitRequestFullScreen()
  11. }
  12. }
  13. launchFullscreen(document.documentElement) // 整个页面进入全屏
  14. launchFullscreen(document.getElementById("id")) //某个元素进入全屏
  15. //退出全屏
  16. function exitFullscreen() {
  17. if (document.exitFullscreen) {
  18. document.exitFullscreen()
  19. } else if (document.msExitFullscreen) {
  20. document.msExitFullscreen()
  21. } else if (document.mozCancelFullScreen) {
  22. document.mozCancelFullScreen()
  23. } else if (document.webkitExitFullscreen) {
  24. document.webkitExitFullscreen()
  25. }
  26. }
  27. exitFullscreen()
  28. //全屏事件
  29. document.addEventListener("fullscreenchange", function (e) {
  30. if (document.fullscreenElement) {
  31. console.log('进入全屏')
  32. } else {
  33. console.log('退出全屏')
  34. }
  35. })

获取滚动条位置

  1. function getScrollPosition(el = window) {
  2. return {
  3. x: (el.pageXOffset !== undefined) ? el.pageXOffset : el.scrollLeft,
  4. y: (el.pageYOffset !== undefined) ? el.pageYOffset : el.scrollTop
  5. }
  6. }
  7. getScrollPosition() // {x: 0, y: 692}

检测设备类型

  1. const detectDeviceType = () =>/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|OperaMini/i.test(navigator.userAgent) ? 'Mobile' : 'Desktop';
  2. detectDeviceType() // "Desktop"

防抖

  1. //适应大部分场景普通防抖
  2. function debounce(fn) {
  3. let timeout = null; // 创建一个标记用来存放定时器的返回值
  4. return function () {
  5. clearTimeout(timeout); // 每当用户输入的时候把前一个 setTimeout clear 掉
  6. timeout = setTimeout(() => { // 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的 interval 间隔内如果还有字符输入的话,就不会执行 fn 函数
  7. fn.apply(this, arguments);
  8. }, 500);
  9. };
  10. }
  11. debounce(fn) // 使用
  12. //可配置时间防抖
  13. function debounce(fn, wait = 50) {
  14. // 通过闭包缓存一个定时器 id
  15. let timer = null
  16. // 将 debounce 处理结果当作函数返回
  17. // 触发事件回调时执行这个返回函数
  18. return function(...args) {
  19. // 如果已经设定过定时器就清空上一次的定时器
  20. if (timer) clearTimeout(timer)
  21. // 开始设定一个新的定时器,定时器结束后执行传入的函数 fn
  22. timer = setTimeout(() => {
  23. fn.apply(this, args)
  24. }, wait)
  25. }
  26. }
  27. //第一次立即执行,之后开始防抖
  28. // immediate 表示第一次是否立即执行
  29. function debounce(fn, wait = 50, immediate) {
  30. let timer = null
  31. return function(...args) {
  32. if (timer) clearTimeout(timer)
  33. // ------ 新增部分 start ------
  34. // immediate 为 true 表示第一次触发后执行
  35. // timer 为空表示首次触发
  36. if (immediate && !timer) {
  37. fn.apply(this, args)
  38. }
  39. // ------ 新增部分 end ------
  40. timer = setTimeout(() => {
  41. fn.apply(this, args)
  42. }, wait)
  43. }
  44. }
  45. // 执行 debounce 函数返回新函数
  46. const betterFn = debounce(() => console.log('fn 防抖执行了'), 1000, true)
  47. // 第一次触发 scroll 执行一次 fn,后续只有在停止滑动 1 秒后才执行函数 fn
  48. document.addEventListener('scroll', betterFn)

节流

  1. //适应大部分场景普通节流
  2. function throttle(fn) {
  3. let canRun = true; // 通过闭包保存一个标记
  4. return function () {
  5. if (!canRun) return; // 在函数开头判断标记是否为true,不为true则return
  6. canRun = false; // 立即设置为false
  7. setTimeout(() => { // 将外部传入的函数的执行放在setTimeout中
  8. fn.apply(this, arguments);
  9. // 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。当定时器没有执行的时候标记永远是false,在开头被return掉
  10. canRun = true;
  11. }, 500);
  12. };
  13. }
  14. throttle(fn) // 使用
  15. //可配置时间节流
  16. const throttle = (fn, wait = 50) => {
  17. // 上一次执行 fn 的时间
  18. let previous = 0
  19. // 将 throttle 处理结果当作函数返回
  20. return function(...args) {
  21. // 获取当前时间,转换成时间戳,单位毫秒
  22. let now = +new Date()
  23. // 将当前时间和上一次执行函数的时间进行对比
  24. // 大于等待时间就把 previous 设置为当前时间并执行函数 fn
  25. if (now - previous > wait) {
  26. previous = now
  27. fn.apply(this, args)
  28. }
  29. }
  30. }

计算函数执行时间

  1. const timeTaken = callback => {
  2. console.time('timeTaken');
  3. const r = callback();
  4. console.timeEnd('timeTaken');
  5. return r;
  6. };
  7. timeTaken(() => Math.pow(2, 10)); // 1024, (logged): timeTaken: 0.02099609375ms

去除空格(多种形式)

  1. /**
  2. * trim 去除空格
  3. * param1 string str 待处理字符串
  4. * param2 number type 去除空格类型 1-所有空格 2-前后空格 3-前空格 4-后空格 默认为1
  5. * return string str 处理后的字符串
  6. */
  7. function trim(str, type = 1) {
  8. if (type && type !== 1 && type !== 2 && type !== 3 && type !== 4) return;
  9. switch (type) {
  10. case 1:
  11. return str.replace(/\s/g, "");
  12. case 2:
  13. return str.replace(/(^\s)|(\s*$)/g, "");
  14. case 3:
  15. return str.replace(/(^\s)/g, "");
  16. case 4:
  17. return str.replace(/(\s$)/g, "");
  18. default:
  19. return str;
  20. }
  21. }

连字符/驼峰互转

  1. const camelizeRE = /-(\w)/g
  2. export const camelize = cached((str: string): string => {
  3. return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')
  4. })
  5. //camelize('aa-bb') // aaBb
  6. const hyphenateRE = /\B([A-Z])/g
  7. export const hyphenate = cached((str: string): string => {
  8. return str.replace(hyphenateRE, '-$1').toLowerCase()
  9. })

随机16进制颜色

  1. function hexColor() {
  2. let str = '#';
  3. let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 'B', 'C', 'D', 'E', 'F'];
  4. for (let i = 0; i < 6; i++) {
  5. let index = Number.parseInt(Math.random() * 16);
  6. str += arr[index]
  7. }
  8. return str;
  9. }

随机RGB颜色

  1. function RandomColor() {
  2. let r, g, b;
  3. r = Math.floor(Math.random() * 256);
  4. g = Math.floor(Math.random() * 256);
  5. b = Math.floor(Math.random() * 256);
  6. return "rgb(" +r + ',' +g+ ',' +b+ ")";
  7. }

统计指定文字出现次数

  1. /**
  2. * 关键词统计:统计一段文字中指定文字出现次数 keywordsCount
  3. * param1 string text 进行统计的文本
  4. * param2 string keywords 进行统计的关键词
  5. * return number count 关键词出现次数
  6. * tip:param1 document.body.innerText--全文统计
  7. */
  8. function keywordsCount(text, keywords) {
  9. return text.split(keywords).length - 1
  10. }

获取数组第N个元素

  1. const nthElement = (arr, n = 0) => (n > 0 ? arr.slice(n, n + 1) : arr.slice(n))[0];
  2. nthElement(['a', 'b', 'c'], 1); // 'b'
  3. nthElement(['a', 'b', 'b'], -3); // 'a'

返回数组指定元素的所有索引

  1. const indexOfAll = (arr, val) => arr.reduce((acc, el, i) => (el === val ? [...acc, i] : acc), []);
  2. indexOfAll([1, 2, 3, 1, 2, 3], 1); // [0,3]
  3. indexOfAll([1, 2, 3], 4); // []

设置CSS样式

  1. const setStyle = (el, ruleName, val) => (el.style[ruleName] = val);
  2. setStyle(document.querySelector('p'), 'font-size', '20px'); // The first <p> element on the page will have a font-size of 20px

获取CSS样式

  1. const getStyle = (el, ruleName) => getComputedStyle(el)[ruleName];
  2. getStyle(document.querySelector('p'), 'font-size'); // '16px'

切换元素样式类

  1. const toggleClass = (el, className) => el.classList.toggle(className);
  2. toggleClass(document.querySelector('p.special'), 'special');
  3. // The paragraph will not have the 'special' class anymore

确保函数只被调用一次

使用一个闭包,使用一个成为 called 的标志,并在第一次调用该函数时将其设置为 true ,以防止它被再次调用。 为了允许函数改变它的 this 上下文(比如在一个事件监听器中),必须使用function 关键字,并且提供的函数必须应用上下文。 允许使用 rest(剩余)/spread(展开) (...) 运算符为函数提供任意数量的参数。

  1. const once = fn => {
  2. let called = false;
  3. return function(...args) {
  4. if (called) return;
  5. called = true;
  6. return fn.apply(this, args);
  7. };
  8. };
  9. //eg
  10. const startApp = function(event) {
  11. console.log(this, event); // document.body, MouseEvent
  12. };
  13. document.body.addEventListener('click', once(startApp)); // only runs `startApp` once upon click

初级表单验证

  1. [
  2. { selector: '#type', msg: '请选择请假类别' },
  3. { selector: '#start_datetime_picker', msg: '请选择开始日期' }
  4. // ...
  5. ].some(function (item) {
  6. if ($(item.selector).val() == "") {
  7. $.toast(item.msg)
  8. return true;
  9. }
  10. });

查看网页布局

  1. //控制台
  2. $$('*').forEach(a=>{a.style.outline='1px solid red'})

find() findIndex() some() includes()

  1. const array = [{ id: 1, checked: true }, { id: 2 }];
  2. arr.find(item => item.id === 2) // { id: 2 }
  3. arr.findIndex(item => item.id === 2) // 1
  4. arr.some(item => item.checked) // true
  5. [1,2,3,''].some(item => !item) //true //用于查找数组中是否有空值
  6. const numberArray = [1,2,3,4];
  7. numberArray.includes(2) // true

promise and await

  1. async function getItems() {
  2. try {
  3. const user = await getUser();
  4. const order = await getOrderByUser(user);
  5. const items = await getOrderItemsByOrder(order);
  6. return items;
  7. } catch(err) {
  8. // 在这里处理错误,建议返回某个值或者重新抛出错误
  9. }
  10. }
  11. getItems().then(items => {
  12. // 处理排序后的成员
  13. })

export 模块

  1. // math.js
  2. export function add(a,b) { return a + b; }
  3. export function sub(a,b) { return a - b; }
  4. export default mult(a,b) => a * b;
  5. // main.js
  6. import mult, { add, sub } from './math';
  7. mult(2, 4) // 8
  8. add(1,1) // 2
  9. sub(1,2) // -1

屏蔽生产环境的console.log

  1. console.log=function(){}

平滑滚动至页面指定位置

  1. const smoothScroll = element =>
  2. document.querySelector(element).scrollIntoView({
  3. behavior: 'smooth'
  4. });
  5. smoothScroll('#fooBar');
  6. smoothScroll('.fooBar');

h5 滚动至页面顶部,全面兼容

  1. const scrollToTop = () => {
  2. let scrollTop = document.documentElement.scrollTo || document.body.scrollTop
  3. if (scrollTop > 0) {
  4. window.requestAnimationFrame(scrollTop)
  5. window.scrollTop(0, scrollTop - scrollTo / 8)
  6. }
  7. }

访jquery链式操作css html

  1. function $ (option) {
  2. var t = typeof(option)
  3. if (t == 'function') {
  4. window.onload = option
  5. } else if (t.toLowerCase() == 'string') {
  6. var ele = option.substring(1, option.length)
  7. el = document.getElementById(ele)
  8. }
  9. var obj = {
  10. css: function (attr, val) {
  11. el.style[attr] = val
  12. return obj;
  13. },
  14. html: function (val) {
  15. el.innerHTML = val
  16. return obj
  17. }
  18. }
  19. return obj
  20. }
  21. $('#box').css('backgroundColor','red').html('hello');

一行代码获取当前 yyyy-MM-dd hh:mm:ss格式时间

  1. new Date().toJSON().split("T")[0] + ' ' + new Date().toJSON().split("T")[1].slice(0,-5)

什么是 IIFE(立即调用的函数表达式)

  1. (function IIFE(){
  2. console.log( "Hello!" );
  3. })();
  4. // "Hello!"
  5. //常常使用此模式来避免污染全局命名空间,因为在IIFE中使用的所有变量(与任何其他普通函数一样)在其作用域之外都是不可见的。

复杂判断优雅解决方式1

  1. const actions = newMap([
  2. ['guest_1', ()=>{/*do sth*/}],
  3. ['guest_2', ()=>{/*do sth*/}],
  4. ['guest_3', ()=>{/*do sth*/}],
  5. ['guest_4', ()=>{/*do sth*/}],
  6. ['guest_5', ()=>{/*do sth*/}],
  7. ['master_1', ()=>{/*do sth*/}],
  8. ['master_2', ()=>{/*do sth*/}],
  9. ['master_3', ()=>{/*do sth*/}],
  10. ['master_4', ()=>{/*do sth*/}],
  11. ['master_5', ()=>{/*do sth*/}],
  12. ['default', ()=>{/*do sth*/}],
  13. ])
  14. /**
  15. * 按钮点击事件
  16. * @param {string} identity 身份标识:guest客态 master主态
  17. * @param {number} status 活动状态:1 开团进行中 2 开团失败 3 开团成功 4 商品售罄 5 有库存未开团
  18. */const onButtonClick = (identity,status)=>{
  19. let action = actions.get(`${identity}_${status}`) || actions.get('default')
  20. action.call(this)
  21. }

上述方法的另一种玩法

  1. const actions = newMap([
  2. [{identity:'guest',status:1},()=>{/*do sth*/}],
  3. [{identity:'guest',status:2},()=>{/*do sth*/}],
  4. //...
  5. ])
  6. const onButtonClick = (identity,status)=>{
  7. let action = [...actions].filter(([key,value])=>(key.identity == identity && key.status == status))
  8. action.forEach(([key,value])=>value.call(this))
  9. }

console.table

  1. //console.table第一个参数为想要打印的对象,数组,类数组,第二个参数为需要的列名
  2. console.table(JSON.parse(JSON.stringify(this.tableData)), ["personnel"]); //此方法打印vue变量没有省略号

根据某属性过滤树形数据

  1. /*
  2. arr 需要被过滤的数组
  3. selectedKey 满足条件的树形值
  4. ieCheck 用于限定条件的属性
  5. */
  6. filterCheck(arr, selectedKey) {
  7. return arr.filter(item => item.isCheck !== selectedKey).map(item => {
  8. item = Object.assign({}, item)
  9. if (item.children) {
  10. item.children = this.filterCheck(item.children, selectedKey)
  11. }
  12. return item
  13. })
  14. },

是否全部验证通过every

  1. [true,true,false].every(el=>el==true) //false

递归搜索

  1. function find(arr, fn, result) {
  2. arr.forEach(item => {
  3. if (item.children) {
  4. find(item.children, fn, result)
  5. } else {
  6. if (fn(item)) {
  7. result.push(item)
  8. }
  9. }
  10. })
  11. }
  12. var result = []
  13. find(carr, item => {
  14. return item.name === '啦啦啦'
  15. }, result)

四则运算符

只有当加法运算时,其中一方是字符串类型,就会把另一个也转为字符串类型。其他运算只要其中一方是数字,那么另一方就转为数字。并且加法运算会触发三种类型转换:将值转换为原始值,转换为数字,转换为字符串。

  1. 1 + '1' // '11'
  2. 2 * '2' // 4
  3. [1, 2] + [2, 1] // '1,22,1'
  4. // [1, 2].toString() -> '1,2'
  5. // [2, 1].toString() -> '2,1'
  6. // '1,2' + '2,1' = '1,22,1'
  7. 对于加号需要注意这个表达式 'a' + + 'b'
  8. 'a' + + 'b' // -> "aNaN"
  9. // 因为 + 'b' -> NaN
  10. // 你也许在一些代码中看到过 + '1' -> 1

生成n个和为sum的数

  1. function randGenerator(n, sum) {
  2. var aryRet = [];
  3. var fSumTmp = sum;
  4. var iAcc = 0;
  5. for (var i = 0; i < (n -1); i++) {
  6. var iTmp = Math.ceil(Math.random() * (fSumTmp / 2));
  7. aryRet.push(iTmp);
  8. fSumTmp -= iTmp;
  9. iAcc += iTmp;
  10. }
  11. aryRet.push(sum-iAcc);
  12. return aryRet;
  13. }
  14. console.log(randGenerator(7, 100));

加法函数(精度丢失问题)

  1. /**
  2. * @param { number } arg1
  3. * @param { number } arg2
  4. */
  5. export function add(arg1, arg2) {
  6. let r1, r2, m;
  7. try { r1 = arg1.toString().split(".")[1].length } catch (e) { r1 = 0 }
  8. try { r2 = arg2.toString().split(".")[1].length } catch (e) { r2 = 0 }
  9. m = Math.pow(10, Math.max(r1, r2));
  10. return (arg1 * m + arg2 * m) / m
  11. }

减法函数(精度丢失问题)

  1. /**
  2. * @param { number } arg1
  3. * @param { number } arg2
  4. */
  5. export function sub(arg1, arg2) {
  6. let r1, r2, m, n;
  7. try { r1 = arg1.toString().split(".")[1].length } catch (e) { r1 = 0 }
  8. try { r2 = arg2.toString().split(".")[1].length } catch (e) { r2 = 0 }
  9. m = Math.pow(10, Math.max(r1, r2));
  10. n = (r1 >= r2) ? r1 : r2;
  11. return Number(((arg1 * m - arg2 * m) / m).toFixed(n));
  12. }

除法函数(精度丢失问题)

  1. /**
  2. * @param { number } num1
  3. * @param { number } num2
  4. */
  5. export function division(num1,num2){
  6. let t1,t2,r1,r2;
  7. try{
  8. t1 = num1.toString().split('.')[1].length;
  9. }catch(e){
  10. t1 = 0;
  11. }
  12. try{
  13. t2=num2.toString().split(".")[1].length;
  14. }catch(e){
  15. t2=0;
  16. }
  17. r1=Number(num1.toString().replace(".",""));
  18. r2=Number(num2.toString().replace(".",""));
  19. return (r1/r2)*Math.pow(10,t2-t1);
  20. }

乘法函数(精度丢失问题)

  1. /**
  2. * @param { number } num1
  3. * @param { number } num2
  4. */
  5. export function mcl(num1,num2){
  6. let m=0,s1=num1.toString(),s2=num2.toString();
  7. try{m+=s1.split(".")[1].length}catch(e){}
  8. try{m+=s2.split(".")[1].length}catch(e){}
  9. return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m);
  10. }

JSON数据分类

  1. function groupBy(array, f) {
  2. const groups = {};
  3. array.forEach(function(o) {
  4. const group = JSON.stringify(f(o));
  5. groups[group] = groups[group] || [];
  6. groups[group].push(o);
  7. });
  8. return Object.keys(groups).map(function(group) {
  9. return groups[group];
  10. });
  11. }
  12. groupBy(this.frsSSOInfo.user_list, el => {
  13. return [el.user_type];
  14. });

找出对象中属性值匹配的key

  1. const findKey = (obj, value, compare = (a, b) => a === b) => {
  2. return Object.keys(obj).find(k => compare(obj[k], value));
  3. };
  4. let { user_type, role_type, agency_code, agency_type } = this.currentUser;
  5. const conditionOpt = {
  6. 1: user_type == 1 && role_type == 4, //校长
  7. 2: user_type == 1 && role_type == 5, //班主任
  8. 3: agency_code && agency_type == 3, //县级
  9. 4: agency_code && agency_type == 2 //州级
  10. };
  11. return findKey(conditionOpt,true)

使用两个非

两个感叹号会确保参数为非值时只能为false,不会是0、空字符串、undefined等非值

  1. //在vue里
  2. if (options) {
  3. this.deep = !!options.deep;
  4. this.user = !!options.user;
  5. this.lazy = !!options.lazy;
  6. this.sync = !!options.sync;
  7. } else {
  8. this.deep = this.user = this.lazy = this.sync = false;
  9. }

async 返回值

async函数内部return语句返回的值,会成为then方法回调函数的参数。

  1. async function f() {
  2. return 'hello world';
  3. }
  4. f().then(v => console.log(v))
  5. // "hello world"

async函数内部抛出错误,会导致返回的 Promise 对象变为reject状态。抛出的错误对象会被catch方法回调函数接收到。

  1. async function f() {
  2. throw new Error('出错了');
  3. }
  4. f().then(
  5. v => console.log(v),
  6. e => console.log(e)
  7. )
  8. // Error: 出错了

浏览器停止滚动后执行操作

  1. var scrollTimer
  2. const timeout = 400
  3. function handler () {
  4. // ...
  5. }
  6. document.addEventListener('scroll', () => {
  7. clearTimeout(scrollTimer)
  8. scrollTimer = setTimeout(handler, timeout)
  9. })