基本类型与转换


1.1 几个基本类型

  • 简单数据类型(原始类型): String、Number、Boolean、Null、Undefined、Symbol、BigInt
  • 复杂数据类型(对象类型): Object

简单数据类型与复杂数据类型在数据存储上有什么区别?

  • 简单数据类型以的形式存储,存储的是
  • 复杂数据类型以的形式存储,地址(指向堆中的值)存储在中。

1.2 ==比较与隐式转换

运算规则
== 相等操作中,如果两边的操作数不同的话,都会进行类型转换,而且优先转为数字,几个规则例子如下。

  1. 1. undefined == null // true,且他俩与所有其它值比较的结果都是false
  2. 2. String == Boolean // 需要两个操作数同时转为Number
  3. 3. String/Boolean == Number // String/Boolean转为Number
  4. 4. Object == Primitive // 需要Object转为Primitive(具体通过valueOf和toString方法)。

对于非基本类型的比较,会通过调用valueOf来转换为基本类型,如果valueOf返回不为基本类型,就会继续调用toString方法转换。
Boolean 一般都是要转成 Number的,

如何实现 **a == 1 && a == 2 && a == 3****true**

  1. const a = {
  2. num: 0,
  3. valueOf: function() {
  4. return this.num +=;
  5. }
  6. }
  7. a == 1 && a == 2 && a == 3 // true

为什么**[] == ![]****true**

  1. [] == ![]; // true
  2. // 1. ! 运算符优先级高于 ==
  3. [] == false;
  4. // 2. false 需转换成number 也就是toNumber(false)
  5. [] == 0;
  6. // 3. []会调用valueOf或toString转换成基本类型
  7. "" == 0;
  8. // 4. "" 需转成Number类型 也就是0
  9. 0 == 0; // true

关于 [] + {}得到’’[object Object’]’而{} + [] 得到 0

  1. {} 在 + 后面时,表示对象{}
  2. {} 位于 + 前面时,{} 表示一个独立的「空代码块」,所以{} + [] 操作相当于进行的是 +[](一元操作符转换操作) 将 [] 转为0

参考
JavaScirpt的隐式类型转换
Javascript 隐式强制类型转换


执行上下文/作用域

2.1 this指向问题


事件循环

在JavaScript中,任务被分为两种,一种宏任务(MacroTask)也叫Task,一种叫微任务(MicroTask)。
MacroTask(宏任务)

  • script全部代码、setTimeout、setInterval、setImmediate(浏览器暂时不支持,只有IE10支持,具体可见MDN)、I/O、UI Rendering。

MicroTask(微任务)

  • Process.nextTick(Node独有)、Promise、Object.observe(废弃)、MutationObserver(具体使用方式查看这里

浏览器中的事件循环

Javascript有一个main thread主线程和call-stack调用栈(执行栈),所有的任务都会被放到调用栈等待主线程执行。

  1. 主线程执行完所有任务,执行栈,检查微任务队列(microTask)
  2. 一次性执行完微任务队列(microTask),将微任务队列(microTask)置为null,检查宏任务队列(macroTask)
  3. 执行完宏任务队列(macroTask),循环第一步

理解await/async

await/async在底层转换成了promisethen 回调函数。
也就是说,这是 promise 的语法糖。
每次我们使用 await, 解释器都创建一个 promise 对象,然后把剩下的 async 函数中的操作放到 then 回调函数中。async/await 的实现,离不开 Promise。从字面意思来理解,async 是“异步”的简写,而 awaitasync wait的简写可以认为是等待异步方法执行完成。

p本身就是一个Promise时,
在Chrome 73以下版本中,resolve(promise)是返回一个新Promise包括了p,会是其在microTask队列中时序变慢
在Chrome 73版本中,resolve(promise)是直接返回p本身,直接加入到microTask队列中

  1. // 一个例子
  2. async function f() {
  3. await p
  4. console.log('ok')
  5. }
  6. // 简单理解为
  7. function f() {
  8. return RESOLVE(p).then(() => {
  9. console.log('ok')
  10. })
  11. }

参考
一次弄懂Event Loop(彻底解决此类面试问题)

编程题


题一

  1. // 下面代码在什么情况下会打印1
  2. var a = ?
  3. if (a == 1 && a == 2 && a == 3) {
  4. console.log(1)
  5. }

考察知识点:1. Object toString 2. 双等号的含义
image.png
image.png
实现方式:

  1. var a = {
  2. id: 1,
  3. toString () {
  4. return this.id++
  5. }
  6. }

参考