【前端造火箭🚀】JavaScript 合集 1(变量类型)

90 阅读3分钟

JavaScript 合集 1(变量类型)

1. typeof 能判断哪些类型

判断所有值类型

  • undefined
  • string
  • number
  • boolean
  • symbol

例如

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

console.log(typeof a)    // undefined
console.log(typeof str)    // string
console.log(typeof n)    // number
console.log(typeof b)    // boolean
console.log(typeof s)    // symbol

判断函数

  • function

例如

console.log(typeof console.log)    // function
console.log(typeof function() {})    // function

识别引用类型

  • object

注意:typeof 无法识别具体引用类型

例如

typeof null;    // 'object'
typeof ['a', 'b'];    // 'object'
typeof {x: 100};    // 'object'

使用 instanceof 识别具体引用类型

const a = null
const b = ['aa', 'bb']
const c = { x: 100 }
const d = () => {}

console.log(a == null)    // true
console.log(b instanceof Array)    // true
console.log(c instanceof Object)    // true
console.log(d instanceof Function)    // true

2. == 和 === 的区别和使用场景

背景

类型转换

字符串拼接
const a = 100 + 10
const b = 100 + '10'
const c = true + '10'

console.log(a)    // 110
console.log(b)    // '10010'
console.log(c)    // 'true10'
==
console.log(100 == '100')    // true
console.log(0 == '')    // true
console.log(0 == false)    // true
console.log(false == '')    // true
console.log(null == undefined)    // true
if 语句和逻辑判断
  • truly 变量:!!a === true
  • falsely 变量:!!a === false
例如
console.log(!!0 === false)    // true
console.log(!!NaN === false)    // true
console.log(!!'' === false)    // true
console.log(!!null === false)    // true
console.log(!!undefined === false)    // true
console.log(!!false === false)    // true

除了以上 falsely 变量之外,其它都是 truly 变量

if 语句

truly 变量

// truly 变量
const aa = true
if (aa) {}

const bb = 10
if (bb) {}

falsely 变量

const cc = ''
if (cc) {}

const dd = null
if (dd) {}

let ee
if (ee) {}
逻辑判断
console.log(10 && 0)    // 0
console.log('' || 'abc')    // 'abc'
console.log(!window.abc)    // true

使用场景

除了判断 null,使用 == null(等价于 === null || === undefined)之外,其他一律都用 ===

3. 常见的值类型和引用类型及其区别

值类型

  • undefined
  • string 字符串
  • number 数值
  • boolean 布尔值

引用类型

  • Object 对象
  • Array 数组
  • Function 函数

值类型和引用类型的区别(※)

存储位置不一样

  • 值类型的 变量 会保存在 内存中
  • 引用类型的 内存地址 保存在 内存中, 存储在 内存中

拷贝方式不一样

  • 值类型的变量直接赋值就是 深拷贝, 如 var a = 10; var b = a; 修改 b 的值不会影响 a
  • 引用类型的变量直接赋值是传递引用,是 浅拷贝

比较

  • 值类型的比较是 的比较
  • 引用类型的比较是 引用地址 的比较

例如

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 }

4. 深拷贝和浅拷贝的区别(※ ※)

假设 b 复制了 a,当修改 a 时

  • 如果 b 也跟着变了,就是 浅拷贝
  • 如果 b 没变,就是 深拷贝

5. 实现深拷贝

/**
 * 深拷贝 1
 * @param {Object} obj 
 * @returns 
 */
function deepClone(obj) {
 if (typeof obj !== 'object' || 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
}

/**
 * 深拷贝 2(4行代码实现)
 * @param {Object} obj 
 * @returns 
 */
function deepClone1(obj) {
  if (typeof obj !== "object" || obj === null) return obj
  let cloneObj = new obj.constructor()
  Object.keys(obj).forEach(v => cloneObj[v] = deepClone1(obj[v]))
  return cloneObj
}

// 功能测试
const obj1 = {
 age: 20,
 name: 'xxx',
 address: {
   city: 'shenzhen'
 },
 arr: ['a', 'b', 'c']
}

const obj2 = deepClone(obj1)
obj2.address.city = '深圳'
obj2.arr[0] = 'a1'
console.log(obj1.address.city)
console.log(obj1.arr[0])