JS 妙用
# JS 妙用
[TOC]
# 一、数组相关
# 1.1 生成 0 - 99 整数的数组
[...Array(100).keys()]
[...Array.from({length: 100}).keys()]
1
2
2
Object.keys
返回一个所有元素为字符串的类数组,其元素来自于从给定的object
上面可直接枚举的属性。这些属性的顺序与手动遍历该对象属性时的一致。
# 1.2 随机排序数组
arr.sort(()=>Math.random()-0.5)`
1
# 1.3 生成指定元素指定长度的数组
new Arrary(8).fill(0)
1
# 1.4 对象数组排序
let arr = [
{key:1},
{key: 4},
{key: 3},
{key: 17}
]
function up(key) {
return (m,n) => {
return m[key] - n[key]
}
}
arr.sort(up('key'))
// [{key: 1},{key: 3},{key: 4},{key: 17}]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 二、
# 三、其他
# 3.1 延迟执行
function sleep(ms) {
return new Promise(resolve =>setTimeout(resolve, ms))
}
sleep(1000).then(()=>{fn()})
1
2
3
4
2
3
4
# 3.2 获取url Search参数
function getUrlSearch(url, name) {
var reg = new RegExp("(^|&?)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
var r = url.substr(1).match(reg); //匹配目标参数
if (r != null) return decodeURI(r[2]);
return null; //返回参数值
}
1
2
3
4
5
6
2
3
4
5
6
# 3.3 遍历对象进行改值操作
function deepForEachObject(data, cb) {
if (typeof data === 'object' && data) {
let val = Array.isArray(data) ? [] : {};
for (let i in data) {
val[i] = deepForEachObject(data[i], cb)
}
return val
} else {
if (cb) {
return cb(data)
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 3.4 将‘false'变为false
JSON.parse('false') // false
1
# 3.5 禁止浏览器自动填充密码
谷歌浏览器只要满足type="text"与type="password"的input标签紧邻时吗,就会自动填充。
推荐方法:修改readonly属性。
<input type="password" readonly onfocus="this.removeAttribute('readonly')" />
1
# 3.6 设备判断
# 3.6.1 判断是否是PC端访问
function isPC(){
var userAgentInfo = navigator.userAgent;
var Agents = new Array("Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod");
var flag = true;
for (var v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) { flag = false; break; }
}
return flag;
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 3.6.2 判断是否是安卓手机
let u = navigator.userAgent;
let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; // android终端
const ua = window.navigator.userAgent.toLocaleLowerCase();
const isIOS = /iphone|ipad|ipod/.test(ua);
const isAndroid = /android/.test(ua);。
1
2
3
4
5
6
2
3
4
5
6
# 3.6.3 判断是否是微信端
function isWeiXin() {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == "micromessenger") {
return true; // 是微信端
} else {
return false;
}
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 3.7 简单的获取输入的方法
let age = prompt('tell me your age')
console.log(age)
1
2
2
# 3.8 打电话
function call(phone) {
const link = document.createElement("a");
link.setAttribute("href", `tel:${phone}`);
const evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true);
link.dispatchEvent(evt);
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# 3.9 文件下载
const a = document.createElement('a'); // 创建a标签
a.setAttribute('download', '');// download属性
a.setAttribute('href', 'https://zhmc-s.yiyu.plus/down/智慧苗场.apk');// href链接
a.click();
1
2
3
4
2
3
4
# 3.10 导出表格
# 3.11 判断元素是否出现在视图里
function isInViewPort (el) {
const viewPortHeight = window.innerHeight || document.scrollingElement.clientHeight
const top = el.getBoundingClientRect() && el.getBoundingClientRect().top
console.log('top', top)
return top <= viewPortHeight + 100
}
1
2
3
4
5
6
2
3
4
5
6
# 3.12 小数的精度问题
alert( 0.1 + 0.2 ); //0.3 -> 0.300000000004
alert(0.2 + 0.7); //0.9 -> 0.89999999999
1
2
2
近似值 = 可能比正确要小,也可以要比正确要大。
// ECMAScript中,0.1加0.2的结果为什么不是0.3,而是0.30000000000000004?
var a = 0.1, b = 0.2, c;
c = a + b;
alert(c); //0.30000000000000004
/**
* 精确加法
*/
function add(num1, num2) {
const num1Digits = (num1.toString().split('.')[1] || '').length;
const num2Digits = (num2.toString().split('.')[1] || '').length;
const baseNum = Math.pow(10, Math.max(num1Digits, num2Digits));
return (num1 * baseNum + num2 * baseNum) / baseNum;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ECMAScript中,采用IEEE754格式来表示整数和浮点数值,由于保存浮点数值需要的内存空间是保存整数的两倍,因此ECMAScript会不失时机地将浮点数值转换为整数值进行计算,导致浮点数值计算会产生舍入误差,这是使用基于IEEE754数值的浮点计算的一个通病。
35.41 * 100 = 3540.9999999999995
1
解决方法:借用第三方库 - https://github.com/nefe/number-precision
解决方案:先转成整数进行计算。
function getMaxPower(arg1 = '',arg2 = '') {
let len1 = arg1.toString().split('.')[1]?.length || 0
let len2 = arg2.toString().split('.')[1]?.length || 0
let n = Math.max(len1,len2)
return Math.pow(10,n)
}
Number.prototype.add = function(arg) {
let pow = getMaxPower(this, arg)
return ((this*pow) + (arg*pow)) / pow
}
Number.prototype.sub = function(arg) {
let pow = getMaxPower(this, arg)
return (this*pow - arg*pow) / pow
}
Number.prototype.mul = function(arg) {
let pow = getMaxPower(this, arg)
return (this*pow) * (arg*pow) / (pow*pow)
}
Number.prototype.div = function(arg) {
let pow = getMaxPower(this, arg)
return (this*pow) / (arg*pow)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26