js知识点汇总之js的数据类型(值和引用)

JS中的数据类型

面试题:JS 中的数据类型有哪些?基本类型和引用类型的区别是什么?

  • 简单值和复杂值
  • 两者之间本质区别
  • 两者之间行为区别

简单值和复杂值

JS 中的数据类型就分为两大类

  • 简单值(基本类型、原始类型)
  • 复杂值(引用值、引用类型)

1. 简单值

一共有 7 种

  • number:数字
  • string:字符串
  • boolean:布尔值
  • undefined:未定义
  • null:空
  • symbol:符号
  • bigint:大数
console.log(null + 1); // 1
console.log(undefined + 1); // NaN

目前来讲,关于 null 和 undefined 主要区别总结如下:

  • null:从语义上来讲就是表示对象的 “无”
    • 转为数值时会被转换为 0
    • 作为原型链的终点
  • undefined:从语义上来讲就是表示简单值的“无”
    • 转为数值为 NaN
    • 变量声明了没有赋值,那么默认值为 undefined.
    • 调用函数没有提供要求的参数,那么该参数就是 undefined
    • 函数没有返回值的时候,默认返回 undefined.

2. 复杂值

复杂值就一种:object

之所以被称之为复杂值,就是因为这种类型的值可以继续往下拆分,分为多个简单值或者复杂值

const obj = {name: "张三",age: 18,scores: {"htmlScore": 99,"cssScore": 95}
};

像数组、函数、正则这些统统都是对象类型,属于复杂值

console.log(typeof []); // object
console.log(typeof function () {}); // function
console.log(typeof /abc/); // object

函数的本质也是对象。

function func() {}
// 该函数我是可以正常添加属性和方法的
func.a = 1; // 添加了一个属性
func.test = function () {console.log("this is a test function");
}; // 添加了一个方法
console.log(func.a); // 1
func.test(); // this is a test function

在函数内部有一个特别的内部属性 [[Call]],这个是属于内部代码,开发者层面是没有办法调用的。但是有了这个属性之后,表示这个对象是可以被调用。

因为函数是可调用的对象,为了区分 普通对象函数对象,因此当我们使用 typeof 操作符检测一个函数时,它返回的是 function。

也正因为这种设计,所以 JS 中能够实现高阶函数。高阶函数的定义:

  • 接受一个或多个函数作为输入
  • 输出一个函数

因为在 JS 中,函数的本质就是对象,因此可以像其他普通对象一样,作为参数或者返回值进行传递。这也是 JS 中所说的函数是一等公民这个说法的由来。

两者之间本质区别

介绍完了简单值和复杂值之后,接下来我们从内存存储的角度,来看一下这两种本质上的区别。

我们知道,内存的存储区域可以分为 这两大块。

  • 栈内存:栈内存因为其数据大小和生命周期的可预测性而易于管理和快速访问。栈支持快速的数据分配和销毁过程,但它不适合复杂的或大规模的数据结构
  • 堆内存:堆内存更加灵活,可以动态地分配和释放空间,适合存储生命周期长或大小不确定的数据。使用堆内存可以有效地管理大量的数据,但相对于栈来说,其管理成本更高,访问速度也较慢。

对于简单值而言,它们通常存储在栈内存里面。上面说了,栈内存的特点是管理简单且访问速度快,适用于存储 大小固定、生命周期短 的数据。简单值的存储通常包括直接在栈内存中分配的数据空间,并且直接存储了数据的实际值。

image-20240430111914109

而对于复杂值而言,具体的值是存储在 堆内存 里面的。因为复杂值往往大小是不固定的,无法在栈区分配一个固定大小的内存,因此具体的数据放在堆里面。那么这就没有栈区什么事儿了么?倒也不是,栈区会存储一个内存地址,通过该内存地址可以访问到堆区里面具体的数据。

image-20240430112917412

另外讲到这里,还有一个非常重要的点要提一下,那就是 JS 中在调用函数的时候,通通都是值传递,而非引用传递

function test(obj) {obj.a = 1000;
}
const obj = {};
console.log(obj); // {}
test(obj);
console.log(obj); // { a: 1000 }

上面的代码,有一定的迷惑性。你看到上面的代码,觉得调用函数之后,obj 发生了真实的修改,所以这是一个引用传递。

但是这里仍然是一个值传递。只不过这个值的背后对应的是一个地址值,这个地址值和简单值一模一样,会被复制一份传递给函数,然后函数内部拿到的是地址值,就可以通过这个地址值找到同一份堆区数据。

function test(obj) {obj = {b:1}; // 这里就赋值了一个新对象,不再使用原来的对象obj.a = 1000;
}
const obj = {};
console.log(obj); // {}
test(obj);
console.log(obj); // {}

如果是真正的引用传递,那么函数内部的 obj 和外部的 obj 是绑在一起的,函数内部对 obj 做任何修改,都会影响外部。但是上面的代码中,很明显在函数内部对 obj 重新赋值后,断开了内外的联系,因此在 JS 中只有值传递

两者之间行为区别

聊完了本质区别后,接下来我们再来聊一下两者之间行为的区别,主要就下面这么几个点:

  1. 访问方式
  2. 比较方式
  3. 动态属性
  4. 变量赋值

1. 访问方式

简单值是 按值访问,也就是说,一个变量如果存储的是一个简单值,当访问这个变量的时候,得到就是对应的值。

const str = "Hello";
console.log(str);

复杂值是虽然也是 按值访问 ,但是由于值对应的是一个 内存地址值,一般不能够直接使用,还需要进一步获取地址值背后对应的值。

const obj = {name: "张三"};
console.log(obj.name);

2. 比较方式

这个比较重要,无论是简单值也好,复杂值也好,都是进行的值比较。不过由于复杂值对应的值是一个 内存地址值,因此只有在这个内存地址值相同时,才会被认为是相等。

const a = {}; // 内存地址不一样,假设 0x0012ff7c
const b = {}; // 内存地址不一样,假设 0x0012ff7d
console.log(a === b); // false

3. 动态属性

对于复杂值来讲,可以动态的为其添加属性和方法,这一点简单值是做不到的

如果为简单值动态添加属性,不会报错,会静默失败,访问时返回的值为 undefined

但如果为简单值动态添加方法,则会报错 xxx is not a function.

const a = 1;
a.b = 2;
console.log(a.b); // undefined
a.c = function(){}
a.c(); // error

4. 变量赋值

最后说一下关于赋值,记住,它们都是 将值复制一份 然后赋值给另外一个变量。

不过由于复杂值复制的是 内存地址,因此修改新的变量会对旧的变量有影响。

let a = 5;
let b = a;
b = 10; // 不影响 a
console.log(a);
console.log(b);
let obj = {};
let obj2 = obj;
obj2.name = "张三"; // 会影响 obj
console.log(obj); // { name: '张三' }
console.log(obj2); // { name: '张三' }
obj2 =  { name: '张三' };
obj2.age = 18; // 不会影响 obj
console.log(obj)
console.log(obj2)

-EOF-

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/18102.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

洁净环境测试标准、监测计划要点及风险评估注意事项

洁净区日常环境监测 洁净区环境监测作为污染控制策略(CCS)的重要组成部分,用于监测旨在将粒子和微生物污染风险降至最低的控制措施。下面内容,中邦兴业小编将与大家做个详细的分享。 环境监测计划 评估和定义粒子、微生物监测所…

2024吉林省电赛(达盛杯)

1. 电赛F4系统板3D图 提起自制STM32F407VET6系统板 2. 电赛原理图 3. 电赛PCB图 4. 智能车实物图 下图是电赛的实物图,结构采用3D打印 5. 软件设计 下图是程序设计图 6. 仿真视频 (1) 变化高度 2024吉林省电赛仿真1 (2) 变化轮距 2024电赛仿真2 7. APP控制小车 …

Py列表(list)

目录 正向索引: 反向索引: 嵌套列表: 修改列表中的值 列表常用的方法 实例 练习: 正向索引: 从0开始,依次递增。第一个元素的索引为0,第二个元素的索引为1,依此类推。 列表的下标…

视频太大怎么压缩变小 视频太大了怎么压缩

视频作为一种多媒体形式,在当今社会的重要性日益凸显,其应用范围广泛,影响力深远。 但是视频文件的大小也在不断增加,这给存储和传输带来了很大的困扰。那么,当视频文件过大时,我们该如何将其压缩变小呢&am…

左偏树,可合并堆

合并两个堆并维护最小或最大性质解决树上节点问题,从叶节点往根维护,每个节点看作一个堆表示到最近的叶节点的距离,所以每次对合并(树高矮)表示堆的顶点对应下标关键代码 static void dfs(int x){for(int ihead[x];i&g…

全域运营是本地生活服务的新模式吗?

最近,本地生活赛道又出现了一个新的说法,即全域运营是本地生活的下半场。事实上,这一论断并非空穴来风,而是有真凭实据。 作为多家互联网大厂重点布局的业务板块,本地生活的火爆程度早已有目共睹。根据多家互联网大厂…

互联网的利

在互联网没发明之前,人类说话要近距离的说,玩游戏要近距离的玩,十分麻烦。于是,互联网解决了这个问题。聊天可以在电脑上聊,玩游戏可以用游戏软件查找玩家来玩,实现了时时可聊,时时可玩的生活。…

nginx编译安装手把手教学

编译安装nginx的第一步需要从nginx的官网找到nginx最新的稳定版本 下面这是官方网站的资源下载地址 https://nginx.org/en/download.html选中稳定版本点击右键——选择复制链接 在终端内使用wget指令官网下载地址,将nginx下载 使用wget指令下载 wget https://ng…

代码模板,Cookie和Session

目录 代码模板 Cookie的基本使用 概念 Cookie的API public Cookie(String name, String value) 发送Cookie对象到客户端:使用response对象 创建Cookie对象并响应给浏览器 在服务器后端获取Cookie对象 Cookie[]cookiesrequset.getCookies(); Cookie的使用细…

【InternLM实战营第二期笔记】03:“茴香豆“,搭建你的 RAG 智能助理(未完成)

文章目录 笔记-RAG课程结构为什么要用 RAG?定义工作原理向量数据库RAG 工作流程发展历程常见优化RAG vs 微调LLM 优化方法比较RAG的评价总结 笔记-茴香豆什么是茴香豆茴香豆实战 笔记-RAG 课程结构 为什么要用 RAG? 新增知识,尤其是高频变动…

基于51单片机简易温度计

一.硬件方案 本系统利用51单片机控制温度传感器DS18B20进行温度的实时检测并显示,能够实现快速测量环境温度。硬件以微控制器为核心,外接时钟电路、复位电路、温度测量电路、LED显示电路组成。 二.设计功能 (1)采用DS18B20温度…

Node.js和npm常用命令

一、Node.js简介 Node.js是一个免费、开源、跨平台的JavaScript运行时环境,允许开发人员创建服务器、web应用程序、命令行工具和脚本。 点击查看node.js中文官网 点击查看node.js英文官网 二、npm简介 npm(Node Package Manager)是Node.js的软件包管理器&#xff0…

ssm150旅游网站的设计与实现+jsp

旅游网站设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本旅游网站就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞…

工作纪实50-Idea下载项目乱码

下载了公司的一份项目代码,发现是gbk格式的,但是我的日常习惯又是utf-8,下载项目以后全是乱码,一脸懵 借用网友的一张图,如果是一个一个文件这么搞,真的是费劲,好几百个文件! 步骤…

NSS‘题目练习3

[SWPUCTF 2021 新生赛]easyupload3.0 打开题目发现要求上传.jpg文件 先上传抓包,尝试更改后缀 换一种形式 文件头绕过 都试过之后尝试上传.htaccess文件,发现上传成功 会将之后上传的文件后缀自动更名为.php 再上传.jpg文件 蚁剑连接找到flag [SWPUCTF …

保障餐饮场所安全:可燃气体报警器专业检测的必要性

在餐饮行业,火灾隐患一直是备受关注的问题。为了有效预防和及时发现可燃气体泄漏,可燃气体报警器的专业检测周期显得尤为重要。 今天,佰德和大家一起来深入了解一下可燃气体报警器的专业检测周期,若您对此有不同的观点或其他的问…

K8S集群监控方案之Prometheus+kube-state-metrics+Grafana

序言 | Prometheus 中文文档 方案简单架构图 一、部署kube-state-metrics 1、部署文件下载 地址 kube-state-metrics/examples/standard at main kubernetes/kube-state-metrics GitHub 2、修改下载的文件 2.1、修改镜像 原镜像可能下载不了,这里修改deploy…

苹果与OpenAI合作在即:iOS 18中的ChatGPT引发期待与担忧

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

互联网应用主流框架整合之数据库事务管理

在互联网系统中同时运行着成千上百个线程是十分常见的事情,尤其当一个热门出现时,用户几乎同时打开手机、电脑、平板灯设备进行访问,这样就会导致数据库处在一个多事务访问的环境中,从而引发数据丢失或者数据不一致的现象&#xf…

计算机考研|408开始的晚,如何规划复习?

408开始的比较晚不用怕 只需要6个月的复习时间,按照我的复习计划,你至少可以考100这个分数 我的计划是对于基础差的考生的,大佬们就可以绕道了,对于基础差的考生来说,408复习的难点其实在于学好数据结构和计算机组成…