哪些我不知道的知识点

188 阅读2分钟

本文是作者的小笔记,会持续更新一些关于日常发现的有趣的知识点;可能是看到的某些文章中对某个已知知识点的新用法,也可能是ES6每年更新的一些新API。

数组对象解构

以前觉得解构这方面已经拿捏了,没想到在某个掘友的文章中看到的新的用法:将某个数组/对象的属性提取到另一个数组或对象中

let arr = [12, '长安'];

let user = {
    name: '李白'
}

let person = {
    name: '杜甫',
    age: 24,
    skill: ['吟诗', '饮酒'],
    sayName(){
        return this.name;
    }
}

// 将数组内容添加为对象属性值 —— 花括号必须加,奇怪的写法
{ [user.age, user.address] = arr };

// 给 user 添加 person 上的两个属性 —— 必须用小括号括起来,且前面要加分号,奇怪的写法
;({ skill: user.skill, sayName: user.sayName } = person);

// 可以直接用于函数
user.drinkArea = function (min, max){
    [this.min, this.max] = [min,max]
}

user.drinkArea('半斤', '五斤');

数组负数下标选择器

// 没什么好解释的,直接用就美滋滋
var arr = ['White', 'Anna', 'Jhon', 'Nancy', 'Carrie'];
console.log(arr.at(-2)); // 'Nancy'
console.log(arr.at(-3)); // 'Jhon'

空值去除器

之前只用过 &&||,没想到又看到了 A ?? B,当且仅当A为 undefinednull 的时候会执行B

let a;
undefined ?? (a=1);
// a: 1
null ?? (a=2);
// a: 2
true ?? (a=6);
// a: 2
NaN ?? (a=9);
// a: 2

对应的有一个短路语句赋值简写

let a;
// a = a ?? false   类似于 a ?? (a=false) 简写为:
a ??= false;

// a = a || 8;   类似于 a || (a=8) 简写为:
a ||= 8;

// a = a && 'hello'  类似于  a && (a='hello')  简写为:
a &&= 'hello';

位操作符

详细看这个文章

可以用于实现奇偶数判断

n & 1 ? '奇数' : '偶数';

可选链

可选的链接 ?.obj?.key 如果 objundefinednull 则则直接返回 undefined,不会导致报错

let user = { 
    friend: {
        name: "李白"
    }
}
// 在不知道user上是否有friend,friend是否有name的情况下获取name的值
// 原来的写法:
user && user.friend && user.friend.name

// 简化写法
user?.friend?.name

过滤数组中虚假的值

const array = [5, 0, 9, 4, null, '', false]; 
let arr = array.filter(Boolean); 
console.log(arr); // [5, 9, 4]

数字精度问题

// 加
function add(arg1, arg2) {
  let digits1, digits2, maxDigits;
  try {
    digits1 = arg1.toString().split('.')[1].length || 0;
  } catch {
    digits1 = 0;
  }
  try {
    digits2 = arg2.toString().split('.')[1].length || 0;
  } catch {
    digits2 = 0;
  }
  maxDigits = 10 ** Math.max(digits1, digits2);
  return (mul(arg1, maxDigits) + mul(arg2, maxDigits)) / maxDigits;
}

// 减
function sub(arg1, arg2) {
  let digits1, digits2, maxDigits;
  try {
    digits1 = arg1.toString().split('.')[1].length || 0;
  } catch {
    digits1 = 0;
  }
  try {
    digits2 = arg2.toString().split('.')[1].length || 0;
  } catch {
    digits2 = 0;
  }
  maxDigits = 10 ** Math.max(digits1, digits2);
  return (mul(arg1, maxDigits) - mul(arg2, maxDigits)) / maxDigits;
}

// 乘
function mul(arg1, arg2) {
  let digits = 0;
  const s1 = arg1.toString();
  const s2 = arg2.toString();
  try {
    digits += s1.split('.')[1].length;
  } catch {}
  try {
    digits += s2.split('.')[1].length;
  } catch {}
  return (Number(s1.replace(/\./, '')) * Number(s2.replace(/\./, ''))) / 10 ** digits;
}

function div(arg1, arg2) {
  let int1 = 0;
  let int2 = 0;
  let digits1;
  let digits2;
  try {
    digits1 = arg1.toString().split('.')[1].length || 0;
  } catch (e) {
    digits1 = 0;
  }
  try {
    digits2 = arg2.toString().split('.')[1].length || 0;
  } catch (e) {
    digits2 = 0;
  }
  int1 = Number(arg1.toString().replace(/\./, ''));
  int2 = Number(arg2.toString().replace(/\./, ''));
  return ((int1 / int2) * 10) ** (digits2 - digits1 || 1);
}