JavaScript中除了简单数据类型(包括数字、字符串、布尔值、null值和undefined值)外的其他所有值都是对象。
JavaScript中的对象是无类型的(class-free),也就是对新的属性名和属性值没有限制。
对象通过引用来传递,永远不会被复制。
比如:
//example 1
let originArray = new Array(0, 1, 2);
let newArray = originArray; //对象引用
originArray[0] = 9;
console.log('originArray', originArray);
console.log('newArray', newArray);
打印的结果是
//example 2
let a = {}, b = {}, c = {};
a、b、c每个的引用都是一个不同的空对象。
//example 3
let a = b = c = {};
a、b、c都引用的是同一对象。
对于非对象的数据是可以复制的,不存在引用。
//example 4
let originString = 'abc';
let newString = originString;
originString = 'def';
console.log('originString', originString);
console.log('newString', newString);
打印结果是
下面再来看一个列子:
//example 5-1
let data = {a: 1, b: [0, 1, 2]};
let dataOne = data;
function change(dataTwo) {
dataTwo['c'] = 5;
console.log('dataTwo', JSON.stringify(dataTwo));
}
change(dataOne);
console.log('dataOne', JSON.stringify(data));
console.log('data', JSON.stringify(data));
这样的情况下,打印的结果是
但是对象引用赋值后,如果将对象置空,相互不受影响。
//example 5-2
let data = {a: 1, b: [0, 1, 2]};
let dataOne = data;
function change(dataTwo) {
dataTwo['r'] = 5;
dataTwo = null;
console.log('dataTwo', JSON.stringify(dataTwo));
}
change(dataOne);
console.log('dataOne', JSON.stringify(data));
console.log('data', JSON.stringify(data));
最近在项目中遇到一个这样的问题,所以才引起了我对Refrence的反思。
const defaultPromo= {
code: '',
isValid: null
};
const defaultDiscounts = {
discount1: defaultPromo,
discount2: defaultPromo
};
const promoCodes = {
discount1: {
code: "inValid",
isValid: false
},
discount2: {
code: "79315",
isValid: true
}
};
const result = _.merge(defaultDiscounts, promoCodes);
result 会是什么呢?是这样吗?
{
discount1: {
code: "inValid",
isValid: false
},
discount2: {
code: "79315",
isValid: true
}
}
☝🏻☝🏻☝🏻其实是这样的:
{
discount1: {
code: "79315",
isValid: true
},
discount2: {
code: "79315",
isValid: true
}
}
在这种情况下,就需要使用clone或者使用...
const defaultPromo= {
code: '',
isValid: null
};
const defaultDiscounts = {
discount1: {... defaultPromo},
discount2: {...defaultPromo}
};
const promoCodes = {
discount1: {
code: "inValid",
isValid: false
},
discount2: {
code: "79315",
isValid: true
}
};
const result = _.merge(defaultDiscounts, promoCodes);