原始值:最简单的数据 (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类型的实例,但其行为类似原始值
let obj = new String("font")
obj.name = "objName"
console.log(obj.name) // objName
console.log(typeof obj) // object
首先比较一下复制原始值和引用值的复制
//原始值
let value1 = 5;
let value2 = value1; // 把value1的值复制给了value2
// 我们修改value1 的值 再打印value2
value1 = 8;
console.log(value2); // 还是 5
// 引用值
let obj1 = new Object();
let obj2 = obj1; //把obj1 复制给obj2
// 此时改变obj1 再打印obj2
obj1.name = "test"
console.log(obj2) // {name: 'test'}
ECMAScript中 函数的参数都是按值传递的, 也就是函数外的值会被复制到函数内部的参数中。
参数的形式有可能是原始值 也有可能是引用值。
// 原始值
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
// 引用值
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属性,函数外部对象也会反映这个变化,就感觉引用类型的参数是按引用值传递的。那我们看一下下面的例子
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'}
ECMAScript中函数的参数就是局部变量
typeof适用于原始类型,对于引用值只能判断出是object类型。但是我们通常要知道是什么样的对象。 (比如 typeof null
回返回object类型)
因此就有了 instanceof操作符
let person = [{'id':1}]
console.log(person instanceof Object) // true
console.log(person instanceof Array) // false
console.log(person instanceof RegExp) // false
用 instanceof
检查原始值则会始终返回false
📢 typeof检查函数时,也会返回function