广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript中原始值和引用值深入讲解
  • 940
分享到

JavaScript中原始值和引用值深入讲解

js中的原始值原始值和引用值的区别js原始值有哪些 2022-11-13 18:11:34 940人浏览 八月长安
摘要

目录值和引用相关内容1. 简单值(原始值)2. 复杂值(引用值)3. 访问方式4. 比较方式5. 动态属性6. 变量赋值灵魂拷问总结值和引用相关内容 在 javascrip

值和引用相关内容

在 javascript 中,数据类型整体上来讲可以分为两大类:基本类型引用数据类型

基本数据类型,一共有 6 种:

string,symbol,number,boolean,undefined,null

其中 symbol 类型是在 es6 里面新添加的基本数据类型。

引用数据类型,就只有 1 种:

object

基本数据类型的值又被称之为原始值或简单值,而引用数据类型的值又被称之为复杂值或引用值。

那么两者之间具体有什么区别呢?我们一点一点来看:

1. 简单值(原始值)

简单值是表示 JavaScript 中可用的数据或信息的最底层形式或最简单形式。简单类型的值被称为简单值,是因为它们是不可细化的。

也就是说,数字是数字,字符串是字符串,布尔值是 true 或 false,null 和 undefined 就是 null 和 undefined。这些值本身很简单,不能够再进行拆分。

由于简单值的数据大小是固定的,所以简单值的数据是存储于内存中的栈区里面的。

要简单理解栈的存取方式,我们可以通过类比乒乓球盒子来分析。如下图:

下面是具体的代码示例:

var str = "Hello World";
var num = 10;
var bol = true;
var myNull = null;
var undef = undefined;
console.log(typeof str); // string
console.log(typeof num); // number
console.log(typeof bol); // boolean
console.log(typeof myNull); // object
console.log(typeof undef); // undefined

这里面 null 比较特殊,打印出来是 object,这是由于历史原因所遗留下来的问题。

是来源于 JavaScript 从第一个版本开始时的一个 bug,并且这个 bug 无法被修复。因为修复会破坏现有的代码。

具体原因是因为不同的对象在底层都表现为二进制,在 JavaScript 中二进制前三位都为 0 的话会被判断为 object 类型,null 的二进制全部为 0,自然前三位也是 0,所以执行 typeof 值会返回 object。

例外,当我们打印 null == undefined 的时候,返回的是 true,这也是面试时经常会被问到的一个问题。

这两个值都表示“无”的意思。

通常情况下, 当我们试图访问某个不存在的或者没有赋值的变量时,就会得到一个 undefined 值。Javascript 会自动将声明是没有进行初始化的变量设为 undifined。

而 null 值表示空,null 不能通过 Javascript 来自动赋值,也就是说必须要我们自己手动来给某个变量赋值为 null。

那么为什么 JavaScript 要设置两个表示"无"的值呢?

这其实也是因为历史原因。

1995 年 JavaScript 诞生时,最初像 Java 一样,只设置了 null 作为表示"无"的值。根据 C 语言的传统,null 被设计成可以自动转为 0。

但是,JavaScript 的设计者,觉得这样做还不够,主要有以下两个原因。

  • null 像在 Java 里一样,被当成一个对象。但是,JavaScript 的数据类型分成原始类型(primitive)和复合类型(complex)两大类,作者觉得表示“无”的值最好不是对象。
  • JavaScript 的最初版本没有包括错误处理机制,发生数据类型不匹配时,往往是自动转换类型或者默默地失败。作者觉得,如果 null 自动转为 0,很不容易发现错误。

因此,作者又设计了一个 undefined。这里注意:先有 null 后有 undefined 出来,undefined 是为了填补之前的坑。

JavaScript 的最初版本是这样区分的:

null 是一个表示“无”的对象(空对象指针),转为数值时为 0;

典型用法是:

  • 作为函数的参数,表示该函数的参数不是对象。
  • 作为对象原型链的终点。

undefined 是一个表示"无"的原始值,转为数值时为 NaN。

典型用法是:

  • 变量被声明了,但没有赋值时,就等于 undefined。
  • 调用函数时,应该提供的参数没有提供,该参数等于 undefined。
  • 对象没有赋值的属性,该属性的值为 undefined。
  • 函数没有返回值时,默认返回 undefined。

2. 复杂值(引用值)

在 JavaScript 中,对象就是一个复杂值。因为对象可以向下拆分,拆分成多个简单值或者复杂值。

复杂值在内存中的大小是未知的,因为复杂值可以包含任何值,而不是一个特定的已知值,所以复杂值的数据都是存储于堆区里面。

如下图所示:

下面是具体的代码示例:

// 简单值
var a1 = 0;
var a2 = "this is str";
var a3 = null

// 复杂值
var c = [1, 2, 3];
var d = {m: 20};

3. 访问方式

按值访问

简单值是作为不可细化的值进行存储和使用的,引用它们会转移其值。

var str = "Hello";
var str2 = str;
str = null;
console.log(str,str2); // null "Hello"

引用访问

复杂值是通过引用进行存储和操作的,而不是实际的值。创建一个包含复杂对象的变量时,其值是内存中的一个引用地址。引用一个复杂对象时,使用它的名称(即变量或对象属性)通过内存中的引用地址获取该对象值。

var obj = {};
var obj2 = obj;
obj.name = "zhangsan";
console.log(obj.name); // zhangsan
console.log(obj2.name); // zhangsan

4. 比较方式

简单值采用值比较,而复杂值采用引用比较。复杂值只有在引用相同的对象(即有相同的地址)时才相等。即使是包含相同对象的两个变量也彼此不相等,因为它们并不指向同一个对象。

示例 1:

var a = 10;
var b = 10;
var c = new Number(10);
var d = c;
console.log(a === b); // true
console.log(a === c); // false
console.log(a === c); // false
console.log(a == c); // true
d = 10;
console.log(d == c); // true
console.log(d === c); // false

示例 2:

var obj = {name : 'zhangsan'};
var obj2 = {name : 'zhangsan'};
console.log(obj == obj2); // false
console.log(obj === obj2); // false
var obj3 = {name : 'zhangsan'};
var obj4 = obj3;
console.log(obj3 == obj4); // true
console.log(obj3 === obj4); // ture

5. 动态属性

对于复杂值,可以为其添加属性和方法,也可以改变和删除其属性和方法。但简单值不可以:

var str = 'test';
str.abc = true;
console.log(str.abc); // undefined
var obj = {};
obj.abc = true;
console.log(obj.abc); // true

复杂值支持动态对象属性,因为我们可以定义对象,然后创建引用,再更新对象,并且所有指向该对象的变量都会获得更新。

一个新变量指向现有的复杂对象,并没有复制该对象。这就是复杂值有时被称为引用值的原因。复杂值可以根据需求有任意多个引用,即使对象改变,它们也总是指向同一个对象

var obj = {name : 'zhangsan'};
var obj2 = obj;
var obj3 = obj2;
obj.name = 'abc';
console.log(obj.name, obj2.name, obj3.name);
// abc abc abc

6. 变量赋值

最后说一下关于变量的赋值,其实是可以分为直接赋值和引用赋值的。直接赋值,就是指将简单值赋值给变量,而引用赋值是指将一个复杂值的引用赋值给变量,这个引用指向堆区实际存在的数据。

直接赋值

var a = 3;
var b = a;
b = 5;
console.log(a); // 3

引用赋值

var a = {value : 1};
var b = a;
b.value = 10;
console.log(a.value); // 10

灵魂拷问

  • js 的基本数据类型有哪些?基本数据类型和引用数据类型的区别

参考答案:

在 JavaScript 中,数据类型整体上来讲可以分为两大类:基本类型引用数据类型

基本数据类型,一共有 6 种:

string,symbol,number,boolean,undefined,null

其中 symbol 类型是在 ES6 里面新添加的基本数据类型。

引用数据类型,就只有 1 种:

object

基本数据类型的值又被称之为原始值或简单值,而引用数据类型的值又被称之为复杂值或引用值。

两者的区别在于:

原始值是表示 JavaScript 中可用的数据或信息的最底层形式或最简单形式。简单类型的值被称为原始值,是因为它们是不可细化的。

也就是说,数字是数字,字符是字符,布尔值是 true 或 false,null 和 undefined 就是 null 和 undefined。这些值本身很简单,不能够再进行拆分。由于原始值的数据大小是固定的,所以原始值的数据是存储于内存中的栈区里面的。

在 JavaScript 中,对象就是一个引用值。因为对象可以向下拆分,拆分成多个简单值或者复杂值。引用值在内存中的大小是未知的,因为引用值可以包含任何值,而不是一个特定的已知值,所以引用值的数据都是存储于堆区里面。

最后总结一下两者的区别:

访问方式

  • 原始值:访问到的是值
  • 引用值:访问到的是引用地址

比较方式

  • 原始值:比较的是值
  • 引用值:比较的是地址

动态属性

  • 原始值:无法添加动态属性
  • 引用值:可以添加动态属性

变量赋值

  • 原始值:赋值的是值
  • 引用值:赋值的是地址

总结

到此这篇关于JavaScript中原始值和引用值的文章就介绍到这了,更多相关js原始值和引用值内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: JavaScript中原始值和引用值深入讲解

本文链接: https://www.lsjlt.com/news/169457.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JavaScript中原始值和引用值深入讲解
    目录值和引用相关内容1. 简单值(原始值)2. 复杂值(引用值)3. 访问方式4. 比较方式5. 动态属性6. 变量赋值灵魂拷问总结值和引用相关内容 在 JavaScrip...
    99+
    2022-11-13
    js中的原始值 原始值和引用值的区别 js原始值有哪些
  • JS原始值和引用值怎么理解
    这篇文章主要介绍“JS原始值和引用值怎么理解”,在日常操作中,相信很多人在JS原始值和引用值怎么理解问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JS原始值和引用值怎么理解”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-22
  • 关于ECMAScript中的原始值和引用值详解
    目录前言什么是动态属性 值的复制 判断值类型 总结前言 这应该是很基础的 JavaScript 的知识点,但估计很多小伙伴都只是简单带过,到面试时一问三不知。这里结合我之前的笔记,再...
    99+
    2022-11-12
  • 浅析JS原始值和引用值问题
    原始值->基本类型 Number String Boolean undefined null 存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置 ...
    99+
    2022-11-12
  • MySQL中int最大值深入讲解
    导语 前两天看到的问题,展开写一下。 字节 我们都知道计算机是以二进制为基础。存储的基本单位是 Bit,也称为比特、二进制位。1bit 可以表示 0 或者 1 两个数字,是可能存在的最小的信息量,任何小...
    99+
    2022-10-18
  • JavaScript 引用类型之原始值包装类型String
    目录String 原始值包装类型String 原始值包装类型 操作方法1.字符串编码常规化函数 normalize()方法2.字符串拼接函数concat()3.字符串提取子...
    99+
    2022-11-13
  • JavaScript对象内置对象,值类型和引用类型讲解
    目录对象对象的定义遍历对象的成员JS内置对象Math对象Date对象数组对象String对象值类型和引用类型对象 JS中的对象是属性和行为的结合体,其中属性是对象的静态特征,行为又称...
    99+
    2022-11-12
  • python基础(5):深入理解 python 中的赋值、引用、拷贝、作用域
    python基础(5):深入理解 python 中的赋值、引用、拷贝、作用域 目录 python基础(5):深入理解 python 中的赋值、引用、拷贝、作用域 1、先来看个问题吧: 2、引用 VS 拷贝: 3、增强赋值以及共享引用: 来源...
    99+
    2023-10-18
    python 网络 开发语言
  • JavaScript中怎么实现值引用和地址引用
    这篇文章将为大家详细讲解有关JavaScript中怎么实现值引用和地址引用,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。js中任何事务都是对象。包括基本数据...
    99+
    2022-10-19
  • 深入解析Python中的变量和赋值运算符
    Python 变量类型 变量存储在内存中的值。这就意味着在创建变量时会在内存中开辟一个空间。 基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中。 因此,变量可以指定不同的数据类型,...
    99+
    2022-06-04
    赋值 变量 运算符
  • Python直接赋值与浅拷贝和深拷贝实例讲解使用
    目录1.字典浅拷贝实例2.更多实例直接赋值:其实就是对象的引用(别名)。 浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。 深拷贝(deepcopy): copy 模块的...
    99+
    2022-11-13
    Python直接赋值 Python浅拷贝 Python深拷贝
  • 深入理解python中函数传递参数是值传递还是引用传递
    目前网络上大部分博客的结论都是这样的: Python不允许程序员选择采用传值还是传 引用。Python参数传递采用的肯定是“传对象引用”的方式。实际上,这种方式相当于传值和传引用的一种综合。如果函数收到的是...
    99+
    2022-06-04
    函数 参数 python
  • go语言中值类型和指针类型的深入理解
    golang这个语言用起来和java、 c#之类语言差不多,和c/c++差别比较大,有自动管理内存机制,省心省力。 然而,如果写golang真的按写java的习惯去写,也容易出问题,...
    99+
    2022-11-13
  • javascript深拷贝、浅拷贝和循环引用的详细讲解
    本篇内容主要讲解“javascript深拷贝、浅拷贝和循环引用的详细讲解”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“javascript深拷贝、浅拷贝和循环引...
    99+
    2022-10-19
  • Java中值类型和引用类型详解
    我们都知道java是一种面向对象的编程语言,但是在实际意义上java并不是纯面向对象,因为面向对象的意义就是万物皆对象,那么如果说int类型的变量也是一个对象的话,那么我们应该能用&...
    99+
    2022-11-12
  • JavaScript中值传递和引用传递有什么区别
    JavaScript中值传递和引用传递有什么区别?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。JavaScript是什么JavaScript是一种直译式的脚本语言,其解释器被称...
    99+
    2023-06-14
  • javascript中原始类型和引用类型有什么区别
    小编给大家分享一下javascript中原始类型和引用类型有什么区别,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1、区别(1)原始类型存储的是值,引用类型存储的...
    99+
    2023-06-15
  • 深入解析Golang中锁的原理和应用
    Golang中锁的原理及应用解析引言在并发编程中,常常会遇到多个 goroutine 同时访问共享资源的情况,一旦多个 goroutine 同时对共享资源进行读写操作,可能导致数据不一致性或者产生竞态条件。为了解决这个问题,Golang 提...
    99+
    2023-12-28
    Golang中锁的原理:锁机制 Golang中锁的应用:并发编程 Golang中锁的解析:互斥锁
  • 全面理解Java中的引用传递和值传递
    目录1.基本类型和引用类型在内存中的保存2.变量的基本类型和引用类型的区别3.引用传递和值传递4.结论关于Java传参时是引用传递还是值传递,是一个讨论比较多的话题, 有说Java中...
    99+
    2022-11-12
  • 学习CSS中的overflow属性:深入了解绝对定位的常用值
    探索绝对定位的常用属性值:掌握CSS中的overflow属性,需要具体代码示例在网页设计和开发过程中,绝对定位是一项非常重要的技能。通过对元素进行绝对定位,我们可以将其精确地放置在页面的任何位置,实现更灵活和精细的布局效果。然而,在进行绝对...
    99+
    2023-12-28
    属性值 Overflow 绝对定位
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作