JavaScript技能深入记录及学习——1

98 阅读5分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 13 天,点击查看活动详情

前言

今天是2023/2/15,由于一系列的所有原因,需要整理面经。

SO从这一篇文章开始callback JavaScript。整理下见过的遇到的js的面点、难点、知识点。


BEGIIN

数据类型

目前js有种数据类型:七个基本类型,1个引用类型:object

  1. String
  2. Boolean
  3. Number
  4. Null
  5. Undefined
  6. Symbol
  7. BigInt

typeof

typeof false
'boolean'
typeof 123  //  typeof NaN
'number'    //  'number'
typeof '123'
'string'
typeof undefined
'undefined'
typeof Symbol()
'symbol'
typeof null
'object'
typeof {}
'object'

Symbol

/*Symbol 值是唯一的,他能作为对象属性的标识符
  Symbol 不用new,直接用
*/
Symbol(123) === Symbol(123)
false

Symbol.for 有自己的一个注册池,使用 Symbol.for 时会看看注册池里有没有注册过,如果没有就 会注册一个 Symbol 值,并把这个值放入注册池,如果有,就把注册过的那个 Symbol 值拿出来使用

let smb2 = Symbol.for('abc') // 对全局进行注册并保存 
let smb3 = Symbol.for('abc') // 从全局注册中获取 
smb3 === smb2 // true

BigInt

BigInt,它提供了一种方法来表示大于 2^53 - 1 的整数。2^53 - 1是 Javascript 中可以用 Number 表示的最大数字。可以用 Number.MAX_SAFE_INTEGER(最大安全数)来得到2^53 - 1这个最大值。但是这个值再大之后就会导致Js计算不准确。BigInt 可以展示任意大的整数。可以解决这个问题。

EventLoop

JS是单线程(同一时间只能做一件事)

为撒不能多个线程

主要任务是:处理用户交互(响应Dom的增删改查),这决定了他必须是单线程,否则会出现问题。

如果是多线程:一条线修改内容,另一条线删除内容。这时浏览器就懵了。

事件循环机制

定义:分为两种:浏览器事件循环,node.js事件循环。目前JS的主要运行环境有两个:浏览器和Node.js

事件循环机制告诉了我们JS代码的执行顺序,是指浏览器或Node的一种解决JS单线程运行时不会阻塞的一种机制。

浏览器的事件循环又分为同步任务和异步任务

同步任务

在主线程上排队执行的任务,只有上一个任务执行完毕,才能执行下一个。形成一个函数调用栈(执行栈)

异步任务

不进入主线程,放在‘任务队列’,只有任务队列通知主线程,某个异步任务可以执行了,该任务才会执行。放在 *任务队列(task queue) 里,任务队列分为微任务宏任务

  • 微任务microTask
    • process.nextTick(Node 独有)
    • Promise.then()若同时存在promise和nextTick,则先执行nextTick
    • Object.observe(已废弃)
    • MutationObserver(H5新特性)
  • 宏任务macrotask
    • 整体代码
    • setTimeout
    • setInterval
    • setImmediate(Node独有)
    • requestAnimationFrame(浏览器独有)
    • I/O
    • UI rendering(浏览器独有)
  • 执行过程
    • 先同步代码
    • 遇到异步宏任务,把他放到宏任务队列中
    • 遇到异步微任务,把他放到微任务队列中
    • 同步代码执行完成,执行微任务
    • 执行完微任务,执行宏任务
    • 一直循环到所有任务完成

微任务的优先级大于宏任务

各种函数

reduce

Array.prototype.reduce()为数组中的每个元素依次执行callback,不包括数组中被删除或从未被赋值的元素.

注意:

  • arr为[]且没有设置initialValue 会报错:"TypeError: Reduce of empty array with no initial value"

arr.reduce(callback(previousValue,currentValue,index,arry), [initialValue])

  1. callback
    1. previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
    2. currentValue (数组中当前被处理的元素)
    3. index (当前元素在数组中的索引)
    4. array (调用 reduce 的数组)
  2. initialValue 第一次调用callback的第一个参数

求和,求乘积

const arr = [1, 2, 3, 4, 5];
const newArr = arr.reduce((pre, cur, index, arr) => {
  console.log('pre', pre, 'cur', cur, 'index', index, 'arr', arr);
  return pre * cur;
});
console.log(newArr);

image.png

将二维数组转成一维数组

let arr = [[0, 1], [2, 3], [4, 5]]
let newArr = arr.reduce((pre, cur) => pre.concat(cur), [])
console.log(newArr)

image.png

将多维数组转换为一维数组

let arr = [[0, 1], [2, 3], [4,[5,6,7]]]
let newArr = arr => arr.reduce((pre,cur) => pre.concat(Array.isArray(cur) ? newArr(cur) : cur), [])
newArr(arr)

image.png

数组去重

const arr = [1, 2, 3, 4, 5, 6, 3, 2, 3, 5, 6, 7, 3, 2, 1, 1, 1, 1, 1, 1];
const newArr = arr.reduce((pre, cur) => {
  if (pre.includes(cur)) {
    return pre;
  } else {
    return pre.concat(cur);
  }
}, []);
console.log(newArr);

image.png

计算每个元素出现的次数

const arr = [1, 2, 3, 4, 5, 6, 3, 2, 3, 5, 6, 7, 3, 2, 1, 1, 1, 1, 1, 1];
const newArr = arr.reduce((pre, cur) => {
  if (cur in pre) {
    pre[cur]++;
  } else {
    pre[cur] = 1;
  }
  return pre;
}, {});
console.log(newArr);

image.png

array.at()

at()方法接收一个整数值并返回该索引对应的元素,允许正数和负数。负整数从数组中的最后一个元素开始倒数。

const arr = [1, 2, 3, 4, 5, 6, 7];
console.log(arr.at(0));
console.log(arr.at(-1));

image.png

for in/for of

  • for in能够遍历对象和数组,对于对象得到的是key值, 对于数组得到的是索引index值。
  • for of无法遍历对象,能够遍历数组和带有iterator接口的,例如Set, Map, String, 得到的是value

for in

const arr = [1, 2, 3, 4, 5, 6, 7];

for (let i in arr) {
  console.info('for in ', arr[i], i);
}

image.png

for of

const arr = [1, 2, 3, 4, 5, 6, 7];

for (let i of arr) {
  console.info('for of ', i);
}

image.png

Object.assign()

作用:接收多个参数来合并对象,如果有相同的属性,后面的值覆盖前面的值,第一个参数如果是变量,值也会发生变化

const a = { name: '123' };
const b = { age: 18 };
const c = { sex: 'male' };

console.info(Object.assign(a, b, c));
console.info(Object.assign(10)); // 强制转成对象(包装类)
console.info(Object.assign([1, 2, 3], [4, 5])); // 可以是数组

image.png

应用:浅拷贝

Object.assign的特别注意事项:当定义的变量为参数之一,且变量里面有引用类型,且合并结果中的引用类型取的是变量中的引用类型地址。那么合并结果中引用类型的key和value会与原变量相互影响,因为他们指向同一个地址。

END

下一篇:JavaScript技能深入记录及学习——2