变量的类型与计算

123 阅读3分钟

题目

  • typeof 能判断哪些类型

  • 何时使用 == 何时使用 ===

  • 值类型和引用类型的区别

    js

    // 值类型和引用类型的区别
    const obj1 = { x: 100, y: 200 }
    const obj2 = obj1
    let x1 = obj1.x
    obj2.x = 101
    x1 = 102
    console.log(obj1) // 这里打印出什么?
    
  • 手写深拷贝

知识点

变量类型

回顾JS的变量类型有哪些?

值类型与引用类型

js

// 值类型
let a = 100
let b = a
a = 200
console.log(b) // 100

js

// 引用类型
let a = { age: 20 }
let b = a
b.age = 21
console.log(a.age) // 21

值类型与引用类型有什么区别?

值类型直接定在内存栈中, 引用类型将值定义在内存堆中并通过引用地址表示

哪些是值类型? 哪些是引用类型?

  • 常见值类型

    js

    const a // undefined
    const s = 'abc'
    const n = 100
    const b = true
    const s = Symbol('s')
    
  • 常见引用类型

    js

    const obj = { x: 100 }
    const arr = ['a', 'b', 'c']
    const n = null // 特殊引用类型,指针指向为空地址
    function fn() {} // 特殊引用类型,但不用于存储数据,所以没有“拷贝、复制函数”这一说
    

如何判断类型?

typeof -> 能判断所有值类型、能判断函数、能识别引用类型

js

// 判断所有值类型
let a
console.log(a) // 'undefined'
const str = 'abc'
typeof str  // 'string'
const n = 100
typeof n // 'number'
const b = true
typeof b // 'boolean'
const s = Symbol('s')
typeof s // 'symbol'

js

// 能判断函数
typeof console.log // 'function'
typeof function () {} // 'function'

// 能识别引用类型(不能再继续识别)
typeof null // 'object'
typeof ['a', 'b'] // 'object'
typeof { x: 100 } // 'object'

变量计算

变量计算一般用于值类型,引用类型会通过 API 来修改数据。

  • 数字 加减乘除
  • 字符串 拼接
  • 逻辑运算 && || ! == if-else

这其中,会隐含比较大的坑 —— 强制类型转换

字符串拼接( + 号)

js

const a = 100 + 10   // 110
const b = 100 + '10' // '10010'
const c = true + '10' // 'true10'

== 和 ===

js

// == 会尝试强制类型转换
100 == '100'   // true
0 == ''  // true
0 == false // true
false == '' // true
null == undefined  // true

总之,== 会尝试进行强制类型转换,至于转换的规则大家没必要,只需要记住一点

  • 所有的地方都用 ===
  • 除了判断是 null 或者 undefined 时用 if (obj.a == null) —— 这也是 jQuery 源码中的方式

js

const obj = { x: 100 }
if (obj.a == null) { }
// 相当于:
if (obj.a === null || obj.a === undefined) { }

深拷贝

面试中经常会遇到浅拷贝与深拷贝有什么区别? 重点就是在于一个引用类型的考察以及对类型判断递归的使用

js

// 深拷贝
function deepClone(obj = {}) {
    if (typeof obj !== 'object' || obj == null ) {
        // 不是对象或者数组形式,或是 null ,直接返回
        return obj
    }

    // 初始化返回结果
    let result
    if (obj instanceof Array) {
        result = []
    } else {
        result = {}
    }

    // 变量
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            // 保证不是原型属性(原型和原型链部分会讲解)

            // 递归调用
            result[key] = deepClone(obj[key])
        }
    }

    // 返回结果
    return result
}

const obj1 = { x: 100, y: 200 }
const obj2 = deepClone(obj1)
obj1.x = 101
console.log(obj2) // x: 100

题目解答

JS中使用typeof能得到的哪些类型

针对这个题目,可以通过以下程序进行验证

js

typeof undefined // 'undefined'
typeof 'abc' // 'string'
typeof 123 // 'number'
typeof true // 'boolean'
typeof Symbol('s') // 'symbol'
typeof {}  // 'object'
typeof [] // 'object'
typeof null // 'object'
typeof console.log // 'function'

何时使用=== 何时使用==

  • 所有的地方都用 ===
  • 除了判断是 null 或者 undefined 时用 if (obj.a == null) —— 这也是 jQuery 源码中的方式

js

const obj = { x: 100 }
if (obj.a == null) { }
// 相当于:
if (obj.a === null || obj.a === undefined) { }

值类型和引用类型的区别

js

// 值类型和引用类型的区别
const obj1 = { x: 100, y: 200 }
const obj2 = obj1
let x1 = obj1.x
obj2.x = 101
x1 = 102
console.log(obj1) // { x: 101, y: 200 }