在我们开始之前,了解一下js的数据类型,js的数据类型分为2类,一种是基本数据类型(原始值)它包含String,Number,Boolean,Null,Undefined,Symbol(ES6),基本数据类型存于栈中,访问方式为值访问。而另一种引用数据类型(引用值),存于堆中,访问方式为内存地址访问。
动态属性
对于引用值而言是可以动态添加属性的
let obj = {}obj.name = 'xb'console.log(obj.name) // 'xb'
对于原始值而言是添加动态属性,会隐式的生成包装类型然后添加属性之后销毁。当调用原始值的动态类型,会出现undefined,(调用时,调用的是隐式生成的包装类型,访问包装类型的属性所以出现了undefined)
let str = 'd'str.name = 'lm'console.log(str.name) // undefined
复制
除了数据存储方式不同,变量复制方式也有所不同。
- 原始值复制是值复制。
- 引用值复制是地址复制。
原始值
let num1 = 1let num2 = num1console.log(num1, num2) // 1, 1
![VL1LS{VC{5]DS~%O%%$Q801.png](/uploads/projects/mooncakezhuking@qa0eee/9fab47a74ac3e366eeb4d13de50ed290.png)
let num1 = 1let num2 = num1console.log(num1, num2) // 1, 1num1 = 2console.log(num1, num2) // 2, 1
引用值
```javascript let obj1 = {
}name: 'xb'
let obj2 = obj1 obj2.name = ‘d’ console.log(obj1.name) // ‘d’
- 首先建立了名为obj1的对象,之后建立一个我obj2的对象同时obj2复制了obj1的地址值。- 之后在obj2修改它的 name 属性,。由于此时 obj1 和 obj2拥有相同的值,也就是说引用同一个对象,所以 obj 做的修改会被外部的 obj1感知到,它们的 name 属性都被修改为 "d"。<a name="lHxbv"></a>## 传递参数JavaScript函数传参为传值```javascriptfunction setName(obj) {obj.name = 'Nicholas'obj = new Object()obj.name = 'Greg'}let person = new Object()setName(person)console.log(Person.name) // 'Nicholas'
- 建立了一个名为person的对象,在调用函数中将person作为参数传入obj,此时obj复制了person的地址值,访问obj,name属性并将其值改为’Nicholas’。

- 随后在函数内部将obj重新引入一个新对象,其内存地址发生改变。从而断开了与person的链接

之后添加obj属性为name,值为’Greg’不会影响person
