Logo
Section 1 / 4

值类型和引用类型

了解 JavaScript 中的值类型和引用类型。

导入

值类型和引用类型

了解 JavaScript 中的值类型和引用类型。

...
JavaScript值类型和引用类型

简介

JavaScript 并不让你完全访问内存中的数据结构。然而,引用类型仍然存在于语言中。混合使用值类型和引用类型会带来意外的副作用和错误。理解值类型与引用类型之间的区别,在编写健壮程序时至关重要。

数字、布尔值、字符串、null、bigint、symbol 和 undefined 是基本类型。所有基本类型都是按值传递的。对象、数组和函数都是按引用传递的。

字符串在 JavaScript 中有些特殊。与许多其他语言不同,字符串并不是字符数组。更进一步地说,JavaScript 中甚至没有单独的字符类型。字符串是不可变的数据类型,其接口使其看起来像一个字符数组。实际上,对字符串的任何修改都会生成一个新的、不可变的字符串值。

在介绍了值类型和引用类型之后,我们来解决一个谜题。判断以下控制台输出的结果。

1var people = [ 2 { name: 'John Hill', age: 22 }, 3 { name: 'Jack Chill', age: 27 } 4]; 5 6var getInitials = function( name ) { 7 // 一般情况下重用 name 参数并无意义。 8 // 我们在这里进行这个赋值,是为了演示值类型和引用类型之间的区别。 9 name = name.split( ' ' ).map( function( word ) { 10 return word.charAt( 0 ); 11 } ).join( '' ); 12 13 console.log( name ); 14 15 return name; 16} 17 18var increaseAge = function( person ) { 19 person.age += 1; 20} 21 22var addPerson = function( people, name, age ) { 23 people.push( { name: name, age: age } ); 24} 25 26// 第一部分:getInitials 27console.log( getInitials( people[0].name ) ); 28console.log( people[0].name ); 29 30// 第二部分:increaseAge 31increaseAge( people[1] ); 32console.log( people[1].age ); 33 34// 第三部分:addPerson 35addPerson( people, 'Jim Gordon', 32 ); 36console.log( people );

问题: 控制台输出了什么?

答案:

  • 第一部分中,getInitials 函数构造了名字的首字母缩写。传入函数的字符串值被复制了一份。函数内部操作的是这份副本,这些修改与原始值 people[0].name 无关。
  • increaseAge 函数接收一个对象。由于对象是引用类型,仅复制了传入的 person 的引用。当修改被引用对象的属性时,这些更改在函数执行后依然保留,并且可以通过任意引用访问到。
  • 数组也是引用类型。向数组添加元素是一种永久性改变。

循环

错误:将值类型当作引用类型使用