js 数据类型
基本数据类型:字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、符号(Symbol)。
引用数据类型:对象(Object)、数组(Array)、函数(Function),还有两个特殊的对象:正则(RegExp)和日期(Date)。
var person = {name: '凯隆',hobby: ['玩耍', '学习', '造梦']};
一、赋值
赋值操作就是使用赋值运算符,将一个变量的值赋值给另一个变量。
对基本数据类型进行赋值很好理解,变量赋值如下:
let a = 0;let b = a// 这里 a 和 b 是两个变量a = 100;console.log(a, b); // 100, 0
使用赋值运算符对引用数据类型(对象类型)赋值,两者共用一个地址,互相牵连:
var person1 = person;person1.name = '杰哥';console.log(person); // {name: '杰哥', hobby: Array(3)};console.log(person1); // {name: '杰哥', hobby: Array(3)};
二、浅拷贝
浅拷贝会重新在堆中新建内存,基本数据类型不会共用内存,但引用数据类型还是共用一个内存。
function shallowCopy(obj) {var target = {};for (var i in obj) {if (obj.hasOwnProperty(i)) {target[i] = obj[i];}}return target;}var person2 = shallowCopy(person);person2.name = '泽龙';person2.hobby[0] = '学习';console.log(person); // {name: '杰哥', hobby: ['学习', '学习', '造梦']};console.log(person2); // {name: '泽龙', ['学习', '学习', '造梦']};
Object.protoType.hasOwnProperty方法返回一个布尔值,判断对象是否包含特定的自身(非继承)属性。
简写写法:
Object.assign(target, ...sources);
Object.assign 方法将所有可枚举属性的值从一个或多个源对象复制到目标对象,同时返回目标对象。
其中 target 是目标对象,sources 是源对象,可以有多个,返回修改后的目标对象。
三、深拷贝
深拷贝会在堆中新建一个内存空间,两个对象互不影响(基本数据类型和引用数据类型都互不影响)。
function deepCopy(obj) {var target = obj.constructor();if (typeof obj === null) {return obj;}if (typeof obj !== 'object') {return obj;}// a instanceof b b的prototype是否在a的原型链上if (obj instanceof Date) {return new Date(obj);}if (obj instanceof RegExp) {return new RegExp(obj);}for (var i in obj) {if (obj.hasOwnProperty(i)) {target[i] = deepCopy(obj[i]);}}return target;}
constructor() 返回对象的构造器,Number.constructor() 返回 0,String.constructor() 返回 '',Array.constructor() 返回 [],Object.constructor() 返回 {},Function.constructor() 返回 ƒ anonymous() {},Bool.constructor() 返回 false。
深拷贝的简易写法:
function deepCopy(obj) {var target = obj.constructor();if (typeof obj !== 'Object') {return obj;}for (var i in obj) {if (obj.hasOwnProperty(i)) {target[i] = deepcopy(obj[i]);}}return target;}
也可以直接使用 JSON.parse(JSON.stringify()) 方法进行深拷贝:
var newObj = JSON.parse(JSON.stringify(obj));
弊端:拷贝不了函数和正则表达式。