JavaScript一些新奇的使用

1、判断是否为数字

const isNum = num => !Number.isNaN(Number.parseFloat(num)) && Number.isFinite(num);

2、判断nums中全部为有效数字

const isNums = (...nums) => !!nums.length && nums.every(i => isNum(i));
console.log(isNums(1, 2, 3));      // true
console.log(isNums());             // false
console.log(isNums(1, null, 3));   // false
console.log(isNums(1, null, "3")); // false

3、判断两个数字的符号是否相同

const isA = (m, n) => isNums(m, n) && (m ^ n) >= 0;
console.log(isA(1, -2));                // false
console.log(isA(-1, 2));                // false
console.log(isA(-1, -2));               // true
console.log(isA(1, 2));                 // true
console.log(isA(null, undefined));      // false

4、数组去重

let arr0 = [3, 5, 3, 6, 3, 9];
let arr1 = [...new Set(arr0)];
console.log(arr1); // [ 3, 5, 6, 9 ]

5、数组合并

let arr2 = [8, 5];
console.log([...arr2, 0, 1, ...[3, 2, 4]]) // [ 8, 5, 0, 1, 3, 2, 4 ]

6、判断一个数字是2的整数幂

const isB = n => isNum(n) && (n & (n - 1)) === 0;
console.log(isB(2));    // true
console.log(isB("4"));  // true
console.log(isB(6));    // false
console.log(isB(8));    // true

7、函数重载

const fnMap = new Map();
function overLoadFunc(...params){
    let key = params.map(p => typeof p).join(",");
    let fn = fnMap.get(key);
    if(fn){
        return fn.apply(this, params);
    }else{
        throw new Error("no such function");
    };
};
overLoadFunc.addImpl = (...params) => {
    let fn = params.pop();
    if(fn && typeof fn == "function"){
        fnMap.set(params.join(","), fn);
    }
};
overLoadFunc.addImpl("string", "string", (s1, s2) => {console.log("string", "string", s1, s2)});
overLoadFunc.addImpl("string", "number", (s, num) => {console.log("string", "number", s, num)});
overLoadFunc.addImpl(() => {console.log("empty")});
overLoadFunc("a", "b");  // string string a b
overLoadFunc("a", 1);    // string number a 1
overLoadFunc();          // empty

8、倒序遍历

普通方式
let arr = [1, 2];
for (let i = arr.length - 1; i >= 0; i--) {
  console.log(arr[i]); // 2 1
}
另一种方式
for (let i = arr.length; i--;) {
  console.log(arr[i]); // 2 1
}

9、巧用splice

const rate = n => "★★★★★☆☆☆☆☆".slice(5 - n, 10 - n);
console.log("三星级", rate(3)); // 三星级 ★★★☆☆

10、信号1/0来回切换

普通方式
let _signal = 1;
for (let i = 0; i < 5; i++) {
    console.log(_signal++ % 2);  // 1 0 1 0 1 
}
另一种方式
let signal = 0;
for (let i = 0; i < 5; i++) {
  console.log(signal ^= 1);  // 1 0 1 0 1 
}

11、对象初始化简写

let a = 1;
let b = 2;
let c = { a, b };
console.log(c); // { a: 1, b: 2 }

12、对象取值

let d = { username: "张三", age: "3" };
let { username, age } = d;
console.log(username, age); // 张三 3

13、求一个数字的整数部分

let testNum = 2.66;
console.log(~~testNum);    // 2
console.log(testNum | 0);  // 2
console.log(testNum >> 0); // 2
console.log(testNum << 0); // 2

14、短路赋值计算

const g = n => (n = +n || 0) && n * 4;
console.log(g());           // 0
console.log(g(null));       // 0
console.log(g(undefined));  // 0
console.log(g("3.1"));      // 12.4
console.log(g(3));          // 12

15、一个数乘以2的n次幂

const calculate = (m, n) => m << n;
console.log(calculate(1, 3)); // 8
console.log(calculate(5, 2)); // 20

16、流式计算

let students = [{ un: "张三", sc: 64 }, { un: "张三", sc: 61 }]
const aver = students.length && students.reduce((pre, item) => pre += item.sc, 0) / students.length;
console.log(aver);  // 平均分:62.5

17、增加逗号间隔

const formatNum = n => n.replace(/(?=\B(\d{3})+$)/g, ',');
console.log(formatNum("1000000000")); // 1,000,000,000

18、Symbol消除魔法字符串

const MY_TYPE = {
    TYPE_1: Symbol("这是一个描述TYPE_1,可为空"),
    TYPE_2: Symbol("这是一个描述TYPE_2,可为空")
};
const doSomething = type => {
    switch (type) {
        case MY_TYPE.TYPE_1:
            console.log("执行TYPE_1");
            break;
        case MY_TYPE.TYPE_2:
            console.log("执行TYPE_2");
            break;
    };
};
doSomething(MY_TYPE.TYPE_1); // 执行TYPE_1
doSomething(MY_TYPE.TYPE_2); // 执行TYPE_2

19、字符码元截取和码点的计算

码元:针对存在单字符为32位长度,即单字符占用两个码元;其他单字符为16位长度,即占用一个码元;

码点:对应码元位置的字符编码,如"a".codePointAt(0)=97,97就是码点;emoji表情的码点都超过了16位即码点大于0xffff

码元 码元 码元 码元 码元 码元 码元 码元 码元 码元 码元 码元
a b c c
String.prototype.customLength = function () {
    let len = 0;
    for (let i = 0; i < this.length;) {
        i += this.codePointAt(i) > 0xffff ? 2 : 1;
        len++;
    }
    return len;
}
String.prototype.customPointAt = function (index) {
    let currentIdx = 0;
    let code;
    if (index < this.customLength()) {
        for (let i = 0; i < this.length;) {
            code = this.codePointAt(i);
            i += code > 0xffff ? 2 : 1;
            if (index == currentIdx) {
                return String.fromCodePoint(code);
            }
            currentIdx++;
        }
    }
    return null;
}
String.prototype.customSub = function (start, end) {
    let len = this.customLength();
    start = (start = ~~start) && start > -1 && start < len + 1 ? start : 0;
    end = (end = ~~end) && end > start && end < len + 1 ? end : len;
    let str = "";
    for (let i = start; i < end; i++) {
        str += this.customPointAt(i);
    }
    return str;
};
let testStr = "abcc";
// length= 12 customLength=8
console.log("length=", testStr.length, "customLength=" + testStr.customLength());
// index= � customPointAt=
console.log("index=", testStr[0], "customPointAt=" + testStr.customPointAt(0));
// substring= a� customLength=ab
console.log("substring=", testStr.substring(0, 4), "customLength=" + testStr.customSub(0, 4));

20、层叠样式表配合Js使用var

css
    
html
    <div class="block" >
        点击切换颜色
    div>
javascript
    let signal = 1;
    document.querySelector("div.block").onclick = function () {
        this.style.setProperty("--r", (signal ^= 1) ? "green" : "gray");
    }
效果

JavaScript一些新奇的使用_第1张图片

21、字符转日期对象

new Date(“2023-07-17”)会默认转为 23/07/17 08:00,所以不使用’-‘,改为’/',这样转才正确;字符错误时date会转为Invalid Date,所以加isNaN判断。

function parseDate(dateStr) {
      var _date = dateStr && new Date(dateStr.replace(/-/g, "/"));
      return _date && !isNaN(_date.getTime()) ? _date : null;
}

你可能感兴趣的:(前端随记,javascript,前端,开发语言)