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])