快速搞定前端Javascript面试课程笔记(一)—JS基础—变量类型和计算

146 阅读3分钟

课程来源:coding.imooc.com/learn/list/…

题目

  • typeof能判断哪些类型
  • 何时使用===何时使用==
  • 值类型和引用类型的区别
  • 手写深拷贝

知识点

  • 变量类型
    • 值类型vs引用类型(堆栈模型)
    • typeof运算符
    • 深拷贝
  • 变量计算 - 类型转换
    • 字符串拼接
    • ==
    • if语句和逻辑运算(truly变量和falsely变量)

一、值类型和引用类型

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

juejin-1

// 引用类型
let a = { age: 20 }
let b = a
b.age = 21
console.log(a.age)  // 21
key value key value key value
a 内存地址1 a 内存地址1 a 内存地址1
b 内存地址1 b 内存地址1
内存地址1 { age: 20 } 内存地址1 { age: 20 } 内存地址1 { age: 20 }
key val key val key val

juejin-2

常见值类型

let a // undefined
const s = 'abc'
const n = 100
const b = true
const s = Symbol('s')

常见引用类型

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

二、typeof和深拷贝

typeof运算符

  • 识别所有值类型
  • 识别函数
  • 判断是否是引用类型(不可再细分)
// 判断所有值类型
let a;                  typeof a    // 'undefined'
const s = 'abc';	typeof str  // 'string'
const n = 100;		typeof n    // 'number'
const b = true; 	typeof b    // 'boolean'
const s = Symbol('s');  typeof s    // 'symbol'

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

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

深拷贝

// 深拷贝演示

const obj1 = {
    age: 20,
    name: 'xxx',
    address: {
        city: 'beijing'
    },
    arr: ['a', 'b', 'c']
}
// 浅拷贝
const obj2 = obj1
obj2.address.city = 'shanghai'
console.log(obj1.address.city)  // 'shanghai'

// 深拷贝
const obj2 = deepClone(obj1)
obj2.address.city = 'shanghai'
obj2.arr[0] = 'a1'
console.log(obj1.address.city)  // 'beijing'
console.log(obj1.arr[0])  //'a'

/**
 * 深拷贝
 * @param {Object} obj 要拷贝的对象
 */
function deepClone(obj = {}) {
    if(typeof obj !== 'object' || obj == null) {
        // obj是null,或者不是对象和数组,直接返回
        return obj
    }
    
    // 初始化返回结果
    let result
    if(obj instanceof Array) {
        result = []
    } else {
        result = {}
    }
    
    for(let key in obj) {
        // 保证key不是原型的属性
        if(obj.hasOwnProperty(key)) {
            // 递归调用!!!
            result[key] = deepClone(obj[key])
        }
    }
    
    // 返回结果
    return result
}

三、变量计算 - 类型转换

  • 字符串拼接
  • ==
  • if语句和逻辑运算

字符串拼接

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

== 运算符

100 == '100'  // true
0 == ''  // true
0 == false  // true
false == ''  // true
null == undefined  // true

// 除了 == null 之外,其他都一律用 === ,例如:
const obj = { x: 100 }
if(obj.a == null) {}
// 相当于:
// if(obj.a === null || obj.a === undefined) {}

if语句和逻辑运算

  • truly变量:!!a === true 的变量
  • falsely变量:!!a === false 的变量
// 以下是 falsely 变量。除此之外都是 truly 变量
!!0 === false
!!NaN === false
!!'' === false
!!null === false
!!undefined === false
!!false === false

// if语句
// truly 变量
const a = true
if(a) {
    //....
}
const b = 100
if(b) {
    //....
}

// falsely 变量
const c = ''
if(c) {
    //...
}
const d = null
if(d) {
    //...
}
let e
if(e) {
    //...
}

// 逻辑判断
console.log(10 && 0)  // 0
console.log('' || 'abc')  // 'abc'
console.log(!window.abc)  // true

四、问题补充解答

值类型和引用类型的区别

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

手写深拷贝

  • 注意判断值类型和引用类型
  • 注意判断是数组还是对象
  • 递归

——————————————————————————————