JS 妙用

# JS 妙用

[TOC]

# 一、数组相关

# 1.1 生成 0 - 99 整数的数组

[...Array(100).keys()]
[...Array.from({length: 100}).keys()]
1
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

# 二、

# 三、其他

# 3.1 延迟执行

function sleep(ms) {
    return new Promise(resolve =>setTimeout(resolve, ms))
}
sleep(1000).then(()=>{fn()})
1
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

# 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

# 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

# 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

# 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

# 3.7 简单的获取输入的方法

let age = prompt('tell me your age')
console.log(age)
1
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

# 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

# 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

# 3.12 小数的精度问题

alert( 0.1 + 0.2 );	//0.3 -> 0.300000000004
alert(0.2 + 0.7);	//0.9 -> 0.89999999999
1
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

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