js积累

47 阅读2分钟

2022-12-23

  1. ??: 操作符,当其左边的值为null或者undefined时返回右边的值。
const result = null ?? 1; // 1
const result = undefined ?? 1; // 1
const result = 'str' ?? ''; // 'str'
  1. ?: 操作符。
const result = true ? 1 : 0; // 1
const result = false ? 1 : 0; // 0
const obj = {};
const result = obj?.name; // 不会报错,会返回undefined
  1. for in/ for of区别:
// for in适用于遍历对象,返回的是对象的key
const obj = { name: 'luoxijie', age:21 };
for(let key in obj){
    console.log(key); // name age
}
// for of适用于遍历可迭代对象(Array Map Set arguments String TypedArray)
const arr = [1, 2, 3];
for(let value of arr){
    console.log(value);// 1 2 3
}
  1. 对象取值:
const obj = {
    name: 'luoxijie',
    age: 21
};
// 某些情况只可以使用第二种方式取值
obj.name; // luoxijie
obj['age']; // 21

2022-12-26

  1. 发布订阅模式:
    class EventEmitter {
        constructor() {
          this.cache = {};
        }

        on(name, fn) {
          if (this.cache[name]) {
            if (!this.cache[name].includes(fn)) {
              this.cache[name].push(fn);
            } else {
              console.log("不需要重复订阅");
            }
          } else {
            this.cache[name] = [fn];
          }
        }

        off(name, fn) {
          if (!fn) {
            delete this.cache[name];
          }
          const tasks = this.cache[name];
          if (tasks) {
            const index = tasks.findIndex((f) => f === fn || f.callback === fn);
            if (index >= 0) {
              tasks.splice(index, 1);
            }
          }
        }

        emit(name, ...val) {
          if (this.cache[name]) {
            const tasks = this.cache[name].slice();
            for (let fn of tasks) {
              fn(...val);
            }
          } else {
            console.log(`不存在属性为${name}的发布者`);
          }
        }
      }
      const events = new EventEmitter();
      const task1 = (...value) => {
        console.log("task1", value);
      };
      const task2 = () => {
        console.log("task2");
      };

      events.on("task", task1);
      events.on("task", task2);
      events.on("task", task2); // 不需要重复订阅
      events.emit("task", "test", "test"); // task1 ['test', 'test'] task2

      console.log("--------");

      events.off("task", task1);
      events.emit("task"); // task2

      events.off("task");
      events.emit("task"); // 不存在属性为task的发布者
  1. 数组扁平化:
const department = {
    产品支持部: [1, 3, 4],
    设计部: [2, 5, 7],
    管理部: [6, 8, 9],
};
const result = Object.values(department).flat(Infinity);
console.log(result); // [1, 3, 4, 2, 5, 7, 6, 8, 9]

2022-12-29

  1. 多个判定条件可以使用includes():
// before
if(test === 'test1' || test === 'test2' || test === 'test3'){
    // ...
}

// after
const arr = ['test1', 'test2', 'test3'];
if(arr.includes(test)){
    // ...
}
  1. 不要太多的if嵌套,可以配合return使用:
// before
if(age > 18){
    if(sex === 'man'){
        // ... do something
    }else{
        // ... do something
    }
}else {
    // ... do something
}

// after
if(age <= 18){
    // ... do something
    return;
}
if(sex !== 'man'){
    // ... do something
    return;
}
// ... do something
  1. 判断输入框中的值是否为空:
// before
if(value !== null && value !== undefined && value !== ''){
    // ...
}

// after
if((value ?? '') !== ''){
    // ...
}
  1. Number常用方法:
// 补零
const fillZero = (num, len) => { 
    return num.toString().padStart(len, '0'); 
}
console.log(fillZero(150, 5)); // 00150

// 转数值
console.log(+null, +'', +false, +'150'); // 0 0 0 150