JavaScript进阶

502 阅读3分钟

本文已参与掘金创作者训练营第三期「话题写作」赛道,详情查看:掘力计划|创作者训练营第三期正在进行,「写」出个人影响力

写在前面,兜兜转转,来来回回,从开始学习JS到现在已经工作这些来年,我和JS每天的生活可以用如胶似漆来形容。但自认为对他认识的还不够深刻。故从头再来,从基础开始。Go!!!

内置类型

  • JS 中分为七种内置类型,七种内置类型⼜分为两⼤类型:基本类型和对象( Object )。

  • 基本类型有六种: null , undefined , boolea n, number ,string ,symbol。

  • 其中 JS的数字类型是浮点类型的,没有整型。并且浮点类型基于IEEE 754 标准实现,在使⽤中会遇到某些 Bug。NaN 也属于 number 类型,并且NaN 不等于⾃身。

  • 对于基本类型来说,如果使⽤字⾯量的⽅式,那么这个变量只是个字⾯量,只有在必要的时候才会转换为对应的类型。

let a = 111 // 这只是字⾯量,不是 number 类型

a.toString() // 使⽤时候才会转换为对象类型

对象( Object )是引⽤类型,在使⽤过程中会遇到浅拷⻉和深拷⻉的问题。

let a = { name: 'FE' }

let b = a

b.name = 'EF'

console.log(a.name) // EF

Typeof

typeof 对于基本类型,除了null都可以显示正确的类型

typeof 1 // 'number'

typeof '1' // 'string'

typeof undefined // 'undefined'

typeof true // 'boolean'

typeof Symbol() // 'symbol'

typeof b // b 没有声明,但是还会显示 undefined

typeof 对于对象,除了函数都会显示object

typeof [] // 'object'

typeof {} // 'object'

typeof console.log // 'function'

对于 null 来说,虽然它是基本类型,但是会显示 object ,这是⼀个存在很久了的 Bug

typeof null // 'object'

PS:为什么会出现这种情况呢?因为在 JS 的最初版本中,使⽤的是 32 位系统,为了性能考虑使⽤低位存储了变量的类型信息, 000 开头代表是对象,然⽽ null 表示为全零,所以将它错误的判断为 object 。虽然现在的内部类型判断代码已经改变了,但是对于这个 Bug 却是⼀直流传下来。

  • 如果我们想获得⼀个变量的正确类型,可以通过Object.prototype.toString.call(xx)。这样我们就可以获得类似[object Type]的字符串
let a

// 我们也可以这样判断 undefined

a === undefined

// 但是 undefined 不是保留字,能够在低版本浏览器被赋值

let undefined = 1

// 这样判断就会出错

// 所以可以⽤下⾯的⽅式来判断,并且代码量更少

// 因为 void 后⾯随便跟上⼀个组成表达式

// 返回就是 undefined

a === void 0

类型转换

转Boolean

在条件判断时,除了undefined , null , false ,NaN , '' ,0 , -0 ,其他所有值都转为 true ,包括所有对象

对象转基本类型

对象在转换基本类型时,⾸先会调⽤ valueOf 然后调⽤toString 。并且这两个⽅法你是可以重写的

let a = {
    valueOf() {
        return 0
    }
}

四则运算符

只有当加法运算时,其中⼀⽅是字符串类型,就会把另⼀个也转为字符串类型。其他运算只要其中⼀⽅是数字,那么另⼀⽅就转为数字。并且加法运算会触发三种类型转换:将值转换为原始值,转换为数字,转换为字符串

1 + '1' // '11'

2 * '2' // 4

[1, 2] + [2, 1] // '1,22,1'

// [1, 2].toString() -> '1,2'

// [2, 1].toString() -> '2,1'

// '1,2' + '2,1' = '1,22,1'

对于加号需要注意这个表达式 'a' + + 'b'

'a' + + 'b' // -> "aNaN"

// 因为 + 'b' -> NaN

// 你也许在⼀些代码中看到过 + '1' -> 1

== 操作符

这⾥来解析⼀道题⽬ [] == ![] // -> true,下⾯是这个表达式为何为true 的步骤

// [] 转成 true,然后取反变成 false

[] == false

// 根据第 8 条得出

[] == ToNumber(false)

[] == 0

// 根据第 10 条得出

ToPrimitive([]) == 0

// [].toString() -> ''

'' == 0

// 根据第 6 条得出

0 == 0 // -> true

⽐较运算符

  • 如果是对象,就通过 toPrimitive 转换对象

  • 如果是字符串,就通过 unicode 字符索引来⽐较

END---