We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
本系列的主题是 JavaScript 基础,每期讲解一个技术要点。如果你还不了解各系列内容,文末点击查看全部文章,点我跳转到文末。
如果觉得本系列不错,欢迎 Star,你的支持是我创作分享的最大动力。
在ECMAScript中,变量可以存放两种类型的值,即原始值和引用值。
原始值(primitive value):
(primitive value)
原始值是固定而简单的值,是存放在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。
(stack)
最新的 ECMAScript 标准定义了7 种原始值:undefined、Boolean、Number、String、BigInt、Symbol 和 null。
undefined
Boolean
Number
String
BigInt
Symbol
null
其实在今年的早些时候,null 还不属于原始类型,这个会在下文中贴图展示。
引用值(reference value):
(reference value)
引用值则是比较大的对象,存放在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(pointer),指向存储对象的内存处。
(heap)
(pointer)
所有引用类型都集成自Object。
Object
如果一个值是引用类型的,那么它的存储空间将从堆中分配。由于引用值的大小会改变,所以不能把它放在栈中,否则会降低查询速度。相反,存放变量的栈空间中的值是该对象存储在堆中的地址。地址的大小是固定的,所以把它存放在栈中对变量性能无任何负面影响。如图:
我们看一下MDN对原始值的定义:
原始值( primitive values )
( primitive values )
除 Object 以外的所有类型都是不可变的(值本身无法被改变)。例如,与 C 语言不同,JavaScript 中字符串是不可变的(译注:如,JavaScript 中对字符串的操作一定返回了一个新字符串,原始字符串并没有被改变)。我们称这些类型的值为“原始值”。
JavaScript
“原始值”
变量存储类型分两类
基本类型:直接存储在栈中的数据。(字符串、布尔值、数字、undefined、null)
引用类型:将该对象引用地址存储在栈中,然后对象里面的数据存放在堆中。(数组、对象、Date、RegExp、函数、特殊的基本包装类型以及单体内置对象)
特殊的基本包装类型(String、Number、Boolean)以及单体内置对象(Global、Math)
假如有以下几个基本类型的变量:
var name = 'jozo'; var city = 'guangzhou'; var age = 22;
那么它的存储结构如下图:
栈区包括了 变量的标识符和变量的值。
JavaScript 和其他语言不同,其不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间,那我们操作啥呢? 实际上,是操作对象的引用,所以引用类型的值是按引用访问的。
准确地说,引用类型的存储需要内存的栈区和堆区(堆区是指内存里的堆内存)共同完成,栈区内存保存变量标识符和指向堆内存中该对象的指针,也可以说是该对象在堆内存的地址。
假如有以下几个对象:
var person1 = {name:'jozo'}; var person2 = {name:'xiaom'}; var person3 = {name:'xiaoq'};
则这三个对象的在内存中保存的情况如下图:
在从一个变量向另一个变量赋值基本类型时,会在该变量上创建一个新值,然后再把该值复制到为新变量分配的位置上:
var a = 10; var b = a; a ++ ; console.log(a); // 11 console.log(b); // 10
此时,a中保存的值为 10 ,当使用 a 来初始化 b 时,b 中保存的值也为10,但b中的10与a中的是完全独立的,该值只是a中的值的一个副本,此后,这两个变量可以参加任何操作而相互不受影响。
也就是说基本类型在赋值操作后,两个变量是相互不受影响的。
当从一个变量向另一个变量赋值引用类型的值时,同样也会将存储在变量中的对象的值复制一份放到为新变量分配的空间中。前面讲引用类型的时候提到,保存在变量中的是对象在堆内存中的地址,所以,与简单赋值不同,这个值的副本实际上是一个指针,而这个指针指向存储在堆内存的一个对象。那么赋值操作后,两个变量都保存了同一个对象地址,则这两个变量指向了同一个对象。因此,改变其中任何一个变量,都会相互影响:
var a = {}; // a保存了一个空对象的实例 var b = a; // a和b都指向了这个空对象 a.name = 'jozo'; console.log(a.name); // 'jozo' console.log(b.name); // 'jozo' b.age = 22; console.log(b.age);// 22 console.log(a.age);// 22 console.log(a == b);// true
它们的关系如下图:
因此,引用类型的赋值其实是对象保存在栈区地址指针的赋值,因此两个变量指向同一个对象,任何的操作都会相互影响。
查看全部文章
各系列文章汇总:https://github.com/yuanyuanbyte/Blog
我是圆圆,一名深耕于前端开发的攻城狮。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
本系列的主题是 JavaScript 基础,每期讲解一个技术要点。如果你还不了解各系列内容,文末点击查看全部文章,点我跳转到文末。
如果觉得本系列不错,欢迎 Star,你的支持是我创作分享的最大动力。
JS 的原始值和引用值
在ECMAScript中,变量可以存放两种类型的值,即原始值和引用值。
原始值
(primitive value)
:原始值是固定而简单的值,是存放在栈
(stack)
中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。最新的 ECMAScript 标准定义了7 种原始值:
undefined
、Boolean
、Number
、String
、BigInt
、Symbol
和null
。引用值
(reference value)
:引用值则是比较大的对象,存放在堆
(heap)
中的对象,也就是说,存储在变量处的值是一个指针(pointer)
,指向存储对象的内存处。所有引用类型都集成自
Object
。如果一个值是引用类型的,那么它的存储空间将从堆中分配。由于引用值的大小会改变,所以不能把它放在栈中,否则会降低查询速度。相反,存放变量的栈空间中的值是该对象存储在堆中的地址。地址的大小是固定的,所以把它存放在栈中对变量性能无任何负面影响。如图:
我们看一下MDN对原始值的定义:
原始值
( primitive values )
除
Object
以外的所有类型都是不可变的(值本身无法被改变)。例如,与 C 语言不同,JavaScript
中字符串是不可变的(译注:如,JavaScript
中对字符串的操作一定返回了一个新字符串,原始字符串并没有被改变)。我们称这些类型的值为“原始值”
。JS 的变量存储类型
变量存储类型分两类
基本类型:直接存储在栈中的数据。(字符串、布尔值、数字、undefined、null)
引用类型:将该对象引用地址存储在栈中,然后对象里面的数据存放在堆中。(数组、对象、Date、RegExp、函数、特殊的基本包装类型以及单体内置对象)
特殊的基本包装类型(String、Number、Boolean)以及单体内置对象(Global、Math)
1. 基本类型的变量是存放在栈区的(栈区指内存里的栈内存)
假如有以下几个基本类型的变量:
那么它的存储结构如下图:
栈区包括了 变量的标识符和变量的值。
2. 引用类型的变量将对象引用地址存储在栈中,对象里面的数据存放在堆中
JavaScript 和其他语言不同,其不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间,那我们操作啥呢? 实际上,是操作对象的引用,所以引用类型的值是按引用访问的。
准确地说,引用类型的存储需要内存的栈区和堆区(堆区是指内存里的堆内存)共同完成,栈区内存保存变量标识符和指向堆内存中该对象的指针,也可以说是该对象在堆内存的地址。
假如有以下几个对象:
则这三个对象的在内存中保存的情况如下图:
3. 简单赋值
在从一个变量向另一个变量赋值基本类型时,会在该变量上创建一个新值,然后再把该值复制到为新变量分配的位置上:
此时,a中保存的值为 10 ,当使用 a 来初始化 b 时,b 中保存的值也为10,但b中的10与a中的是完全独立的,该值只是a中的值的一个副本,此后,这两个变量可以参加任何操作而相互不受影响。
也就是说基本类型在赋值操作后,两个变量是相互不受影响的。
4. 对象引用
当从一个变量向另一个变量赋值引用类型的值时,同样也会将存储在变量中的对象的值复制一份放到为新变量分配的空间中。前面讲引用类型的时候提到,保存在变量中的是对象在堆内存中的地址,所以,与简单赋值不同,这个值的副本实际上是一个指针,而这个指针指向存储在堆内存的一个对象。那么赋值操作后,两个变量都保存了同一个对象地址,则这两个变量指向了同一个对象。因此,改变其中任何一个变量,都会相互影响:
它们的关系如下图:
因此,引用类型的赋值其实是对象保存在栈区地址指针的赋值,因此两个变量指向同一个对象,任何的操作都会相互影响。
查看全部文章
博文系列目录
交流
各系列文章汇总:https://github.com/yuanyuanbyte/Blog
我是圆圆,一名深耕于前端开发的攻城狮。
The text was updated successfully, but these errors were encountered: