otype[Symbol.toStringTag];// "WeakSet"
WeakMap.prototype[Symbol.toStringTag];// "WeakMap"
ArrayBuffer.prototype[Symbol.toStringTag];// "ArrayBuffer"
4. 扩展:如何实现一个深浅拷贝
4-1. 浅拷贝
4-1-1. 定义
创建一个新对象,复制已有对象中非对象属性的值和对象属性的引用。
本质:只能拷贝一层对象,对于嵌套对象无能为力。
4-1-2. 代码实现
通常有5种方式可以完成浅拷贝:Object.assign(目标对象, 拷贝原对象), 扩展运算符..., concat拷贝数组, slice拷贝数组,自己手撕一个浅拷贝实现。
4-1-2.(1). Object.assign(目标对象, 拷贝原对象)
原理:Object.assign 循环遍历原对象的属性,通过复制的方式将其赋值给目标对象的相应属性。它不会拷贝对象的继承属性、不可枚举属性。
代码例子:
let target = {};
let source = { a: { b: 'CS阿吉' } };
Object.defineProperty(source, 'innumerable' ,{
value:'不可枚举属性',
enumerable:false
});
Object.assign(target, source);
source.a.b = '阿吉';
console.log(source); // { a: { b: '阿吉' }, innumerable: "不可枚举属性" };
console.log(target); // { a: { b: '阿吉' } };
4-1-2.(2). 扩展运算符...
原理:同Object.assign。
代码例子:
let sourceObj = { a: 1,b: { c: 1 } };
let targetObj = { ...obj };
let sourceArray = [1, 2];
let targetArray = [ ...sourceArray ];
4-1-2.(3). concat拷贝数组
原理:只能用于数组的拷贝。新数组改变,不影响原数组。
代码例子:
let sourceArray = [1, 2];
let targetArray = sourceArray.slice();
targetArray[0] = 0;
console.log(sourceArray); // [1, 2]
console.log(targetArray); // [0, 2]
4-1-2.(4). slice拷贝数组
原理:只能用于数组的拷贝。新数组改变,不影响原数组。
代码例子:
let sourceArray = [1, 2];
let targetArray = sourceArray.concat();
targetArray[0] = 0;
console.log(sourceArray); // [1, 2]
console.log(targetArray); // [0, 2]
4-1-2.(5). 手动实现
原理:利用类型判断,对于引用类型的对象进行for循环遍历对象属性,赋值给目标对象的属性。
代码实现如下:
const shallowClone = (target) => {