原始值和引用值
在 ECMAScript 中,变量可以存在两种类型的值,即原始值和引用值。
原始值
存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。
引用值
存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存处。
原始值 ------不会互相影响
var a = 3;
var b = a;
b = 5;
console.log(a); // 3
console.log(b); // 5
引用值 -----会互相影响
var obj1 = {
a: 1,
b: 2,
c: 3
}
var obj2 = { ...obj1 };
obj2.a = 5;
console.log(obj1.a); // 5
console.log(obj2.a); // 5
var arr1 = [1, 2, 3]
var arr2 = [...arr1];
arr2[0] = 3;
console.log(arr1[0]) //3
console.log(arr2[0]) //3
下面看一下如何深拷贝一个对象,即拷贝一个对象更改对象的值又不会互相影响
第一种 Object.assign()
该方法只能拷贝一层的对象
例子
var obj1 = {
a: 1,
b: 2,
c: 3
}
var obj2 = Object.assign({}, obj1);
obj2.a = 5;
console.log(obj1.a); // 1
console.log(obj2.a); // 5
var arr1 = [1, 2, 3]
var arr2 = Object.assign([], arr1);
arr2[0] = 3;
console.log(arr1[0]) //1
console.log(arr2[0]) //3
//以下的值不能个更改了----------------------------------
var obj3 = {
a: {
a: 111
},
}
var obj4 = Object.assign({}, obj3);;
obj4.a.a = 'aaaaa';
console.log(obj3.a.a); // aaaaa
console.log(obj4.a.a); // aaaaa
var arr3 = [{ a: 1, b: 2 }]
var arr4 = Object.assign([], arr3);
arr4[0].a = 'aaa';
console.log(arr3[0].a) //aaa
console.log(arr4[0].a) //aaa
第二种扩展符
该方法同第一种只能复制简单的一层的数据类型
例子
var obj1 = {
a: 1,
b: 2,
c: 3
}
var obj2 = Object.assign({}, obj1);
obj2.a = 5;
console.log(obj1.a); // 1
console.log(obj2.a); // 5
var arr1 = [1, 2, 3]
var arr2 = Object.assign([], arr1);
arr2[0] = 3;
console.log(arr1[0]) //1
console.log(arr2[0]) //3
//以下的值不能个更改了----------------------------------
var obj3 = {
a: {
a: 111
},
}
var obj4 = { ...obj3 };
obj4.a.a = 'aaaaa';
console.log(obj3.a.a); // aaaaa
console.log(obj4.a.a); // aaaaa
var arr3 = [{ a: 1, b: 2 }]
var arr4 = [...arr3];
arr4[0].a = 'aaa';
console.log(arr3[0].a) //aaa
console.log(arr4[0].a) //aaa
第三种JSON转化
该方法不能更改值为undefined,fun(),正则等等值得对象
例子
{
let obj1 = {
a: 1,
b: 2,
c: 3
}
let objString = JSON.stringify(obj1);
let obj2 = JSON.parse(objString);
obj2.a = 5;
console.log(obj1.a); // 1
console.log(obj2.a); // 5
}
{
let arr1 = [1, 2, 3]
let objString = JSON.stringify(arr1);
let arr2 = JSON.parse(objString);
arr2[0] = 3;
console.log(arr1[0]) //1
console.log(arr2[0]) //3
}
{
let obj3 = {
a: {
a: 111
},
}
let objString = JSON.stringify(obj3);
let obj4 = JSON.parse(objString);
obj4.a.a = 'aaaaa';
console.log(obj3.a.a); // 111
console.log(obj4.a.a); // aaaaa
}
{
let arr3 = [{ a: 1, b: 2 }]
let objString = JSON.stringify(arr3);
let arr4 = JSON.parse(objString);
arr4[0].a = 'aaa';
console.log(arr3[0].a) //1
console.log(arr4[0].a) //aaa
}
//以下的不能更改-------------------------------------------
{
let obj1 = {
a: '这样子的改不了哦',
b: undefined,
c: function () { },
d: null,
e: /a/
}
let objString = JSON.stringify(obj1);
let obj2 = JSON.parse(objString);
obj2.a = 5;
console.log(obj1);
/*
a: "这样子的改不了哦"
b: undefined
c: ƒ ()
d: null
e: /a/
*/
console.log(obj2);
/*
a: 5
d: null
e: {}
*/
}
{
let arr1 = ['这样子的改不了哦', undefined, function () { }, null, /a/]
let objString = JSON.stringify(arr1);
let arr2 = JSON.parse(objString);
arr2[0] = 3;
console.log(arr1)
/*
0: "这样子的改不了哦"
1: undefined
2: ƒ ()
3: null
4: /a/
*/
console.log(arr2)
/*
0: 3
1: null
2: null
3: null
4: {}*/
}
封装方法
例子
封装的方法
// 定义一个深拷贝函数 接收目标target参数
function deepClone(target) {
// 定义一个变量
let result;
// 如果当前需要深拷贝的是一个对象的话
if (typeof target === 'object') {
// 如果是一个数组的话
if (Array.isArray(target)) {
result = []; // 将result赋值为一个数组,并且执行遍历
for (let i in target) {
// 递归克隆数组中的每一项
result.push(deepClone(target[i]))
}
// 判断如果当前的值是null的话;直接赋值为null
} else if (target === null) {
result = null;
// 判断如果当前的值是一个RegExp对象的话,直接赋值
} else if (target.constructor === RegExp) {
result = target;
} else {
// 否则是普通对象,直接for in循环,递归赋值对象的所有值
result = {};
for (let i in target) {
result[i] = deepClone(target[i]);
}
}
// 如果不是对象的话,就是基本数据类型,那么直接赋值
} else {
result = target;
}
// 返回最终结果
return result;
}
使用
//拷贝一个对象
let obj1 = {
a: {
c: /a/,
d: undefined,
b: null
},
b: function () {
console.log(this.a)
},
c: [
{
a: 'c',
b: /b/,
c: undefined
},
'a',
3
]
}
let obj2 = deepClone(obj1);
obj2.a = {
c: 2,
}
obj2.b = function () {
console.log('你是不是傻啊')
}
console.log(obj1);
console.log(obj2);
//拷贝一个数组
var arr1 = [{
a: [1, 2, 3],
b: function () { },
c: undefined,
}, {
a: [1, 2, 3],
b: function () { },
c: undefined,
}]
let arr2 = deepClone(arr1);
arr2[0].a = [1]
arr2[0].b = {a:1}
arr2[0].c = function(){}
console.log(arr1);
console.log(arr2);