基本类型与转换
1.1 几个基本类型
- 简单数据类型(原始类型): String、Number、Boolean、Null、Undefined、Symbol、BigInt
- 复杂数据类型(对象类型): Object
简单数据类型与复杂数据类型在数据存储上有什么区别?
- 简单数据类型以栈的形式存储,存储的是值
- 复杂数据类型以堆的形式存储,地址(指向堆中的值)存储在栈中。
1.2 ==比较与隐式转换
运算规则
== 相等操作中,如果两边的操作数不同的话,都会进行类型转换,而且优先转为数字,几个规则例子如下。
1. undefined == null // true,且他俩与所有其它值比较的结果都是false
2. String == Boolean // 需要两个操作数同时转为Number
3. String/Boolean == Number // String/Boolean转为Number
4. Object == Primitive // 需要Object转为Primitive(具体通过valueOf和toString方法)。
对于非基本类型的比较,会通过调用valueOf来转换为基本类型,如果valueOf返回不为基本类型,就会继续调用toString方法转换。Boolean
一般都是要转成 Number
的,
如何实现 **a == 1 && a == 2 && a == 3**
为 **true**
?
const a = {
num: 0,
valueOf: function() {
return this.num +=;
}
}
a == 1 && a == 2 && a == 3 // true
为什么**[] == ![]**
是 **true**
?
[] == ![]; // true
// 1. ! 运算符优先级高于 ==
[] == false;
// 2. false 需转换成number 也就是toNumber(false)
[] == 0;
// 3. []会调用valueOf或toString转换成基本类型
"" == 0;
// 4. "" 需转成Number类型 也就是0
0 == 0; // true
关于 [] + {}
得到’’[object Object’]’而{} + []
得到 0
- 当
{}
在 + 后面时,表示对象{}
- 当
{}
位于 + 前面时,{}
表示一个独立的「空代码块」,所以{} + []
操作相当于进行的是+[]
(一元操作符转换操作) 将[]
转为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调用栈(执行栈),所有的任务都会被放到调用栈等待主线程执行。
- 主线程执行完所有任务,执行栈,检查微任务队列(microTask)
- 一次性执行完微任务队列(microTask),将微任务队列(microTask)置为null,检查宏任务队列(macroTask)
- 执行完宏任务队列(macroTask),循环第一步
理解await/async
await/async
在底层转换成了promise
和 then
回调函数。
也就是说,这是 promise
的语法糖。
每次我们使用 await
, 解释器都创建一个 promise
对象,然后把剩下的 async
函数中的操作放到 then
回调函数中。async/await
的实现,离不开 Promise
。从字面意思来理解,async
是“异步”的简写,而 await
是 async wait
的简写可以认为是等待异步方法执行完成。
当p
本身就是一个Promise
时,
在Chrome 73以下版本中,resolve(promise)
是返回一个新Promise
包括了p
,会是其在microTask队列中时序变慢
在Chrome 73版本中,resolve(promise)
是直接返回p
本身,直接加入到microTask队列中
// 一个例子
async function f() {
await p
console.log('ok')
}
// 简单理解为
function f() {
return RESOLVE(p).then(() => {
console.log('ok')
})
}
编程题
题一
// 下面代码在什么情况下会打印1
var a = ?
if (a == 1 && a == 2 && a == 3) {
console.log(1)
}
考察知识点:1. Object toString 2. 双等号的含义
实现方式:
var a = {
id: 1,
toString () {
return this.id++
}
}
参考