一文彻底搞懂 JS 中的基础类型和引用类型

简介: 一文彻底搞懂 JS 中的基础类型和引用类型

在JavaScript中,可以按值和按引用传递

这两种方法的主要区别在于,在赋值原始值(primitive)时是传递值,而在赋值对象(objects)时是传递引用

让我们在这篇文章中更详细地讨论值和引用。

primitive && objects

JavaScript提供了两类数据类型: 基本类型(primitive)和引用类型(objects)。

基本类型包括数字、布尔值、字符串、符号和特殊值(null和undefined)。例如:

// Primitives
const number = 10;
const bool = false;
const str = 'Hello!';
const missingObject = null;
const nothing = undefined;

第二类是对象。特别是普通对象、数组、函数等等都是对象

// Objects
const plainObject = {
  prop: 'Value'
};
const array = [1, 5, 6];
const functionObject = (n1, n2) => {
  return n1 + n2;
};

换句话说,任何不是原始值的东西都是对象。

值传递

按值传递的简单规则是,JavaScript中的所有原始值都是按值传递的。就这么简单。

通过值传递意味着每次给变量赋值时,都会创建该值的一个副本

假设你有两个变量a和b:

let a = 1;
let b = a;
b = b + 2;
console.log(a); // 1
console.log(b); // 3

第一个语句让a = 1定义一个初始化为数字1的变量a。

第二个语句让b = a定义另一个变量b,并使用一个变量的值初始化它——这是通过value传递的。简单点说,把数字1的一个副本赋给b

之后,b = b + 2增加2,变成3。变量b发生变化,这个变化不影响变量a的值

引用传递

然而,引用传递的表现方式不同。

当创建一个对象时,你会得到一个对该对象的引用如果两个变量拥有相同的引用,那么改变对象会反映在两个变量中

让我们检查下面的代码示例:

let x = [1];
let y = x;
y.push(2);
console.log(x); // [1, 2]
console.log(y); // [1, 2]

第一个语句让x =[1]创建一个数组,定义一个变量x,并使用对创建的数组的引用初始化该变量。

然后让y = x定义一个变量y,并使用存储在x变量中的引用初始化y。这是一个引用传递。

y.push(2)通过入项2来改变数组。因为xy变量引用相同的数组,所以这一变化反映在两个变量中。

注意: 为简单起见,我说变量包含对对象的引用。但是严格地说,JavaScript中的变量保存的值是对对象的引用

使用比较运算符

在比较对象时,理解值和引用之间的差异很重要。

当使用严格比较操作符===时,如果两个变量的值相同,那么它们就是相等的。下面所有的比较都是相等的:

const one = 1;
const oneCopy = 1;
console.log(one === oneCopy); // true
console.log(one === 1);       // true
console.log(one === one);     // true

oneoneCopy的值相同。当两个操作数的长度都为1时,操作符===的计算结果为true,而不管值是从哪里取的。

但是比较操作符===比较引用时的工作方式不同只有当它们引用完全相同的对象时,两个引用才相等

例如,ar1和ar2引用不同的数组:

const ar1 = [1];
const ar2 = [1];
console.log(ar1 === ar2); // false
console.log(ar1 === [1]);  // false
const ar11 = ar1;
console.log(ar1 === ar11); // true
console.log(ar1 === ar1);  // true

ar1和ar2引用相同结构的数组,但是ar1 === ar2计算为false,因为ar1和ar2引用不同的数组对象

比较操作符仅在比较指向同一个对象的引用时返回true: ar1 === ar11ar1 === ar1

总结

在JavaScript中,基本类型是作为值传递的:这意味着每次赋值时,都会创建一个值的副本

另一方面,对象(包括普通对象、数组、函数、类实例)是引用。如果您修改了该对象,那么所有引用该对象的变量都将看到更改

比较运算符区分比较值和引用。只有引用了完全相同的对象时,两个引用的变量才相等,但如果两个变量的值是相同的,那么它们的值就是相等的,而不管值来自哪个地方。



相关文章
|
16天前
|
JavaScript 前端开发 开发者
如何在 JavaScript 中处理不同类型的错误?
【10月更文挑战第29天】通过对不同类型错误的准确识别和恰当处理,可以提高JavaScript程序的可靠性和稳定性,减少错误对程序运行的影响。
|
1月前
|
JavaScript 前端开发 安全
深入理解TypeScript:增强JavaScript的类型安全性
【10月更文挑战第8天】深入理解TypeScript:增强JavaScript的类型安全性
47 0
|
15天前
|
JavaScript 前端开发 Java
除了 JavaScript,还有哪些编程语言支持 Set 类型
【10月更文挑战第30天】这些编程语言中的 `Set` 类型虽然在语法和具体实现细节上有所不同,但都提供了类似的集合操作功能,方便开发者在不同的编程场景中处理集合相关的数据和逻辑。
|
16天前
|
存储 JavaScript 前端开发
js的基础类型和引用类型
【10月更文挑战第29天】理解 JavaScript 中的基础类型和引用类型的区别对于正确地编写代码和理解程序的行为非常重要。在实际开发中,需要根据具体的需求合理地选择和使用不同的数据类型,以避免出现一些意想不到的错误和问题。同时,在处理引用类型数据时,要特别注意对象的引用关系,避免因共享引用而导致的数据不一致等问题。
|
1月前
|
存储 JavaScript 前端开发
JavaScript 数据类型详解:基本类型与引用类型的区别及其检测方法
JavaScript 数据类型分为基本数据类型和引用数据类型。基本数据类型(如 string、number 等)具有不可变性,按值访问,存储在栈内存中。引用数据类型(如 Object、Array 等)存储在堆内存中,按引用访问,值是可变的。本文深入探讨了这两种数据类型的特性、存储方式、以及检测数据类型的两种常用方法——typeof 和 instanceof,帮助开发者更好地理解 JavaScript 内存模型和类型检测机制。
71 0
JavaScript 数据类型详解:基本类型与引用类型的区别及其检测方法
|
1月前
|
JavaScript 前端开发
JavaScript返回判断类型有哪些?
JavaScript返回判断类型有哪些?
31 0
|
3月前
|
缓存 JavaScript 前端开发
|
3月前
|
JavaScript 前端开发 UED
探秘 JavaScript 错误背后的真相——揭开异常类型的神秘面纱,让你的代码从此无懈可击!
【8月更文挑战第23天】本文深入探讨了JavaScript中常见的异常类型,包括`ReferenceError`(未定义的引用)、`TypeError`(类型错误)、`SyntaxError`(语法错误)、`RangeError`(范围错误)、`EvalError`(评估错误)以及`URIError`(URI错误),并通过示例展示了如何有效地诊断与处理这些异常。此外,还介绍了如何自定义错误类以适应特定场景的需求。掌握这些异常处理技巧对于构建稳定可靠的Web应用程序至关重要。
39 0
|
3月前
|
JavaScript 前端开发 安全
TypeScript:解锁JavaScript的超级英雄模式!类型系统如何化身守护神,拯救你的代码免于崩溃与混乱,戏剧性变革开发体验!
【8月更文挑战第22天】TypeScript作为JavaScript的超集,引入了强大的类型系统,提升了编程的安全性和效率。本文通过案例展示TypeScript如何增强JavaScript:1) 显式类型声明确保函数参数与返回值的准确性;2) 接口和类加强类型检查,保证对象结构符合预期;3) 泛型编程提高代码复用性和灵活性。这些特性共同推动了前端开发的标准化和规模化。
59 0
|
3月前
|
JavaScript 前端开发
javascript 异常问题之JavaScript中的异常有哪些类型,可以举例说明吗
javascript 异常问题之JavaScript中的异常有哪些类型,可以举例说明吗
下一篇
无影云桌面