typeof 运算符与深拷贝
typeof 运算符
首先我们来探究 typeof 究竟能判断出来哪些数据类型。
-
判断值类型
let a; const b = 'abc'; const c = 100; const d = true; const e = Symbol('d'); typeof(a) // "undefined" typeof(b) // "string" typeof(c) // "number" typeof(d) // "boolean" typeof(e) // "symbol" -
判断函数
function foo() { console.log('foo') } typeof foo; // "function" -
判断引用类型(不可细分)
const a = null; const obj = { name: 'zhangsan' }; const arr = [1, 2, 3, 4]; const set = new Set(arr); const map = new Map(); typeof a // "object" typeof obj // "object" typeof arr // "object" typeof set // "object" typeof map // "object"
总结
由此可以总结出:typeof 运算符可以返回五种值类型,函数类型,引用类型,注意这里的引用类型不可细分为数组、集合等。
深拷贝
先来看一个浅拷贝:
const obj1 = {
name: 'xxx',
age: 20,
address: {
city: 'beijing'
},
arr: [1, 2, 3, 4]
};
const obj2 = obj1;
obj2.name = 'yyy';
console.log(obj1.name); // yyy
这里 obj2 直接引用了 obj1 的地址,所以修改 obj2.name 后 obj1.name 会跟着改变。
很多时候我们并不希望得到这样的结果,但是细想为什么 javascript 甚至更多的语言在设计的时候不直接设置为深拷贝的数据呢?
其实原因很简单,设想这些语言在设计时,引用类型数据赋值后直接是深拷贝数据,那么就会特别消耗内存,当代码初始化执行时,遇到一个很大的对象时可能就会卡死。所以出于多种因素,引用类型的传递都是地址传递。
所以当我们需要得到一个引用类型数据的深拷贝时,就要通过算法来实现。这里提供两个深拷贝方法:
JSON.stringify() 和 JSON.parse()
const obj1 = {
name: 'xxx',
age: 20,
address: {
city: 'beijing'
},
arr: [1, 2, 3, 4]
};
// 使用 JSON.parse() 和 JSON.stringify() 实现深拷贝
const obj2 = JSON.parse(JSON.stringify(obj1));
obj2.name = 'yyy';
console.log(obj1.name); // xxx
obj2.address.city = 'shanghai';
console.log(obj1.address.city); // beijing
以上代码中我们先用方法 JSON.stringify() 方法将 obj1 对象转换为 JSON 格式的字符串,再使用 JSON.parse() 解析 JSON 格式的字符串得到对象赋值给 obj2,此时就实现了一个深拷贝。
递归
const obj1 = {
name: 'xxx',
age: 20,
address: {
city: 'beijing'
},
arr: [1, 2, 3, 4]
};
const obj2 = deepClone(obj1);
obj2.name = 'yyy';
console.log(obj1.name); // xxx
obj2.address.city = 'shanghai';
console.log(obj1.address.city); // beijing
function deepClone(obj = {}) {
// 如果传进来的对象不是对象、数组或者是 null、undefined,则直接返回。
if (typeof obj !== "object" || obj == null) {
return obj;
}
// 定义一个准备返回的深克隆的变量,其类型取决于传进来的数据类型。
const result = obj instanceof Array ? [] : {};
// 循环遍历数组或对象,使用递归,逐层克隆数据。
for (let key in obj) {
// 保证 key 不是原型的属性
if (obj.hasOwnProperty(key)) {
// 递归调用
result[key] = deepClone(obj[key]);
}
}
return result;
}
至此我们就使用了两种方法完成了对数组、对象的深克隆。
本文详细介绍了JavaScript中的typeof运算符如何判断基本数据类型、函数及引用类型,并探讨了深拷贝的概念及其重要性。提供了使用JSON.stringify()和JSON.parse()以及递归函数实现深拷贝的具体方法。
563

被折叠的 条评论
为什么被折叠?



