原始值与引用值
原始值:最简单的数据 (Undefined、Null、Boolean、Number、String、Symbol)。我们操作的就是存储在变量的实际值
引用值:多个值构成的对象。是保存在内存中的对象。Js不允许直接访问内存位置,不能直接操作对象所在的内存空间。实际操作的是对该对象的引用。
动态属性
原始值和引用值的定义 都是创建一个变量,然后给它赋值。
- 引用值可以随时增加、删除、修改其属性和方法。
let obj1 = new Object();
obj1.name ="Nike"
console.log(obj1.name) // Nike
这个给对象obj1新增的属性可以被访问,直到对象销毁或者属性被显式删除。
- 原始值不能有属性
let oldValue = "old"
oldValue.name = "mm"
console.log(oldValue.name) // undefined
原始值只能使用原始字面量形式,如果使用new关键字,则javaScript创建一个Object类型的实例,但其行为类似原始值
代码语言:javascript复制let obj = new String("font")
obj.name = "objName"
console.log(obj.name) // objName
console.log(typeof obj) // object
复制值
首先比较一下复制原始值和引用值的复制
代码语言:javascript复制//原始值
let value1 = 5;
let value2 = value1; // 把value1的值复制给了value2
// 我们修改value1 的值 再打印value2
value1 = 8;
console.log(value2); // 还是 5
代码语言:javascript复制// 引用值
let obj1 = new Object();
let obj2 = obj1; //把obj1 复制给obj2
// 此时改变obj1 再打印obj2
obj1.name = "test"
console.log(obj2) // {name: 'test'}
区别
- 原始值的复制是互不干扰的。
- 引用值复制的实际上是指针,都指向着同一对象。改变一个另一个也会改变
传递参数
ECMAScript中 函数的参数都是按值传递的, 也就是函数外的值会被复制到函数内部的参数中。
参数的形式有可能是原始值 也有可能是引用值。
代码语言:javascript复制 // 原始值
function Add(num){ // 相当于复制原始值 let num = count
num = 10;
return num;
}
let count = 20; // 变量count
let result = Add(count) // 执行函数 传参count
consol.log(count); // 20 没有变化
console.log(result); // 30
代码语言:javascript复制// 引用值
function Change(obj){
obj.name = "test"
return obj
}
let person = new Object() // 实例化对象
let pObj = Change(person) // 执行函数 参数为person对象
console.log(person) // {name:'test'}
console.log(pObj) // {name:'test'}
我们上面说过参数是按值传递的,但是上面这个引用值的例子,在函数内部给obj添加name属性,函数外部对象也会反映这个变化,就感觉引用类型的参数是按引用值传递的。那我们看一下下面的例子
代码语言:javascript复制function Change(obj){
obj.name = "test"
obj = new Object();
// 变化:新增两行代码
obj.name = "wgh"
return obj
}
let person = new Object() // 实例化对象
let pObj = Change(person) // 执行函数 参数为person对象
console.log(person) // {name:'test'}
console.log(pObj) // {name:'wgh'}
- 如果person是按引用值传递的,那么person应该自动将指针指向name为 wgh 的对象。但是我们再次访问的结果是test,这表明原始的引用值仍然没变。
- obj在函数内部重写事,变成了一个指向本地对象的指针。这个本地对象在函数执行结束时被销毁。
ECMAScript中函数的参数就是局部变量
确定类型
typeof适用于原始类型,对于引用值只能判断出是object类型。但是我们通常要知道是什么样的对象。 (比如 typeof null
回返回object类型)
因此就有了 instanceof操作符
代码语言:javascript复制 let person = [{'id':1}]
console.log(person instanceof Object) // true
console.log(person instanceof Array) // false
console.log(person instanceof RegExp) // false
用 instanceof
检查原始值则会始终返回false