人话 JS 之引用值

参考

《JS 高级程序设计》

原始值与引用值

  1. 所谓原始值,就是 Undefined、Null、Boolean、Number、String 和 Symbol。对于原始值的操作,也是操作的实际的值。
  2. 所谓引用值,就是保存在内存中的对象因为 JS 不能直接操作对象的内存地址,所以实际操作的是对象的引用。
  3. 引用值是具体引用类型的实例,它们有自己的属性和方法,很像类,但是不是类

区别

动态属性

  1. 引用值可以添加,修改和删除其属性和方法。但原始值不可以
// 引用值可以操作它的属性
let person = new Object(); 
person.name = "Nicholas"; 
console.log(person.name); // "Nicholas"

// 原始值不可以
let name = "Nicholas"; 
name.age = 27; 
console.log(name.age); // undefined

相同类型的原始值和引用值行为区别

let name1 = "Nicholas"; 
let name2 = new String("Nicholas"); 
name1.age = 27; 
name2.age = 27; 
console.log(name1.age); // undefined 
console.log(name2.age); // 26 
console.log(typeof name1); // string 
console.log(typeof name2); // object

复制值

  1. 原始值在复制的时候是值传递(传递的是“克隆体”,可以随意修改而不相互影响),而引用类型是引用传递(指针传递,都是指向相同的地址)
let obj1 = new Object(); 
let obj2 = obj1; 
obj1.name = "Nicholas"; 
console.log(obj2.name); // "Nicholas"
// 可以看到 obj1 和 obj2 指向的都是相同的对象,所以它们显示的内容也相同

在这里插入图片描述

函数参数为值传递

  1. 不管是原始类型还是引用类型,在作为函数参数的时候都是按值传递,在 JS 中函数参数是一个局部变量,都是 arguments 类数组对象的一个值
// 原始值按值传递,这一点是非常好理解的
// 但是引用值也按值传递是怎么回事呢
function setName(obj) {
    
     
 obj.name = "Nicholas"; 
} 
let person = new Object(); 
setName(person); 
console.log(person.name); // "Nicholas"
// 到这里,很多人会以为,这是引用传递
// 因为明明函数内的修改,作用到了全局作用域中

// 我们再看一个例子
function setName(obj) {
    
     
 obj.name = "Nicholas"; 
 obj = new Object(); 
 obj.name = "Greg"; 
} 
let person = new Object(); 
setName(person); 
console.log(person.name); // "Nicholas"
// 可以看到 obj 的引用并没有被修改,这个在函数内部被重写的对象,在函数结束时就被销毁了

确定引用值

我们知道 typeof 可以适合判断一个变量是否为原始类型,但是像 Array,Object 等都是对象(引用类型),我们需要具体知道它是什么对象的实例。

这个时候 instanceof 就是用来确定对象是什么类型的,顾名思义,a instanceof b 就是问,a 是不是 b 的实例

console.log(person instanceof Object); // 变量 person 是 Object 吗?
console.log(colors instanceof Array); // 变量 colors 是 Array 吗?
console.log(pattern instanceof RegExp); // 变量 pattern 是 RegExp 吗?

【注】在 JS 中所有的引用类型都是 Object 的实例

Guess you like

Origin blog.csdn.net/qq_34902437/article/details/118363826