JavaScript引用数据类型(对象类型)和原始(基本)数据类型特点比较

news2024/11/28 13:34:03

JavaScript引用数据类型(对象类型)和原始(基本)数据类型特点比较

为讲解JavaScript引用数据类型(对象类型)和原始(基本)数据类型特点比较,需要先回顾JavaScript数据类型有哪些?

一)原始(primitive:原始、基本)数据类型,也称为原始值(primitive value),包括:

1.布尔值(Boolean),其字面值只有两个,分别是true和false。

2.null,Null类型只有一个唯一的字面值null, null 值的特殊关键字。JavaScript 是大小写敏感的,因此 null 与 Null、NULL或变体完全不同。

3.undefined,Undefined类型只有一个唯一的字面值undefined,undefined 表示变量未赋值时的属性。而undefined是JavaScript中的一个全局变量,即挂载在window对象上的一个变量,并不是关键字。

4.数字(Number),整数或浮点数,例如: 42 或者 3.14159。

5.任意精度的整数(BigInt),可以安全地存储和操作大整数。ES10(也称为ES2019)引入了一个新的原始数据类型BigInt,用于表示任意精度的整数。在之前的版本中,JavaScript只能表示有限范围的整数,超出范围的整数会被转换为特殊的Infinity值。

6.字符串(String),字符串是一串表示文本值的字符序列,例如:"Howdy"。

7.代表(Symbol,在 ECMAScript 6 中新添加的类型)。一种实例是唯一且不可改变的数据类型。

二)对象(object)类型,是一种非原始(non-primitive)数据类型,也称为引用值(reference value),用于更复杂的数据结构。JavaScript中的对象类型包括:

1、普通对象(Plain objects):是指用户自定义的对象类型。这些对象通常是通过使用构造函数或类来定义的。在JavaScript中,有多种方式可以创建对象。在ES6及以后的版本中,JavaScript引入了类(class),这是一种创建和定义对象的新方法。

2、数组(Arrays):例如let arr = [1, 2, 3]; 数组对象有一些特殊的属性和方法,如length、push、pop等。

3、函数(Functions):函数也是对象,它们可以有属性和方法。例如:
function sayHello() {
  console.log('Hello');
}
sayHello.myProperty = 'This is a property of the function.';

4、日期(Dates):例如let date = new Date();

5、正则表达式(RegExp,Regular expressions):例如let regex = /ab+c/;

6、其他内置对象,如Math,Set,Map等。

JavaScript原始(基本)数据类型和引用数据类型(对象类型)特点差别:

☆原始(基本)数据类型只能表示一个简单的值,不能添加、修改和删除属性。引用数据类型可以包含多个键值对,形成复杂的数据结构,可以动态地添加、修改和删除属性。

 原始(基本)数据类型只能表示一个简单的值,比如字符串、数字、布尔值等。它们不能添加、修改和删除属性。

例如:

let num = 5;
num = 10; // 修改变量的值

console.log(num); // 10

let str = "Hello";
str.length = 5; // 添加属性

console.log(str.length); // undefined

在这个例子中,我们可以修改原始数据类型的变量的值,但不能添加属性。即使我们尝试添加属性,也不会对原始数据类型的值产生影响。因为原始数据类型的值是不可变的,它们没有属性可以修改或删除。

引用数据类型可以包含多个键值对,形成复杂的数据结构,比如对象和数组。你可以动态地添加、修改和删除属性或元素。

例如:

let person = {
  name: "John",
  age: 30,
  hobbies: ["reading", "coding"]
};

person.name = "Jane"; // 修改属性值
person.gender = "female"; // 添加新属性
delete person.age; // 删除属性

console.log(person); // { name: "Jane", hobbies: ["reading", "coding"], gender: "female" }

在这个例子中,我们有一个person对象,它包含了name、age和hobbies等属性。我们可以通过修改属性值、添加新属性或删除属性来动态地改变对象的结构。

☆ 原始(基本)数据类型的值是不可变的,引用数据类型的值是可变的。

原始(基本)数据类型的值是不可变的,意味着你不能直接修改它们的值。当你尝试修改原始数据类型的值时,实际上是创建了一个新的值,并将其赋给变量。

例如:

let num = 5;
num = 10;

console.log(num); // 10

在这个例子中,我们将num的值从5修改为10,但实际上是创建了一个新的值10,并将其赋给num变量。

引用数据类型的值是可变的,意味着你可以修改它们的属性或元素。这是因为引用数据类型的值实际上是存储在内存中的对象,变量只是指向这个对象的引用。当你修改引用数据类型的值时,实际上是在修改对象本身,而不是修改变量的值。

例如:

let obj = { name: "John" };
obj.name = "Jane";

console.log(obj); // { name: "Jane" }

在这个例子中,我们修改了obj对象的name属性的值,这是因为obj是一个引用数据类型,它指向的对象是可变的。

这种不可变性的特性使得原始数据类型在处理简单的数据时更加方便和可靠,而引用数据类型则更适合处理复杂的数据结构和对象。

☆ 变量赋值方面,原始(基本)数据类型的变量赋值是值的复制,而引用数据类型(对象类型)的变量赋值是引用的复制。

当执行到变量赋值语句时,JavaScript引擎会将赋值操作的右侧表达式计算出一个值,并将该值赋给变量。赋值操作可以使用赋值运算符 =,也可以使用其他赋值运算符(如 +=、-= 等)。
变量赋值是一个按值传递的过程。对于基本数据类型(如数字、字符串、布尔值等),赋操作会将值复制给变量。而对于引用数据类型(如对象、数组等),赋值操作会将引用(指向对象的内存地址)复制给变量,而不是复制对象本身。这意味着,当你修改一个引用类型的变量时,实际上是修改了引用所指向的对象。

对于原始类型,变量赋值是通过将一个值复制给另一个变量来完成的。这意味着当你将一个原始数据类型的变量赋值给另一个变量时,实际上是将原始值复制到了新的变量中。这两个变量是完全独立的,修改其中一个变量的值不会影响另一个变量。

例如:

let a = 5;
let b = a;
b = 10;

console.log(a); // 输出 5
console.log(b); // 输出 10

当一个原始变量把值赋给另一个原始变量时,只是把栈中的内容复制给另一个原始变量,此时这两个变量互不影响——其实在内存中是两个地址,是互相独立的存在,当一个变量值改变时,另一个变量不会因此而发生任何变化。图解如下:

对于引用数据类型,变量赋值是通过将引用复制给另一个变量来完成的。引用是指向存储在内存中的对象的地址。当你将一个引用数据类型的变量赋值给另一个变量时,实际上是将引用复制到了新的变量中。这两个变量指向同一个对象,修改其中一个变量的属性会影响另一个变量。

例如:

let obj1 = { name: 'Alice' };
let obj2 = obj1;
obj2.name = 'Bob';

console.log(obj1.name); // 输出 'Bob'
console.log(obj2.name); // 输出 'Bob'

需要注意的是,当你修改引用数据类型的属性时,实际上是修改了对象本身,而不是变量。因此,所有指向该对象的变量都会反映出这个修改。图解如下:

☆  参数传递方面,在 JavaScript中,参数传递方式是按值传递——传递的是副本。具体说来:1)当将一个原始(基本)数据类型(如数字、字符串、布尔值等)作为参数传递给函数时,实际上是将该值的一个副本传递给函数——将实参值复制给形参,实参和形参相互独立互不干扰。函数内部对该副本的修改不会影响到原始的值。2)当将一个引用数据类型(对象类型)(如对象、数组等)作为参数传递给函数时,传递的是该对象的引用(地址)的副本——将实参引用的地址值复制给形参,形参和实参指向同一个对象的地址,改变形参所指向的对象的属性将影响实参所指向的对象。需要注意,在引用类型的参数传递中,并不会改变形参的值(即引用的地址),而是通过形参改变它所指向的对象的属性。

当传递原始数据类型时,实际上是将原始值的副本传递给了函数或其他变量。这意味着函数或其他变量操作的是原始值的副本,而不是原始值本身。

这种传递方式使得函数内部对原始值的修改不会影响到函数外部的变量,因为函数内部操作的是原始值的副本,而不是原始值本身。

例如:

function changeValue(num) {
  num = 10;
}

let x = 5;
changeValue(x);

console.log(x); // 输出 5

当传递引用数据类型时,实际上是将引用的地址传递给了函数。这意味着函数可以通过引用来访问和修改原始对象。引用是指向存储在内存中的对象的地址,所以传递引用时,传递的是指向对象的指针,而不是对象本身的实际值。

这种传递方式使得我们可以在函数内部修改原始对象,并且这些修改会在函数外部可见。因为函数和外部变量都指向同一个对象,所以对对象的修改会影响到所有引用该对象的变量。

例如:

function changeName(obj) {
  obj.name = 'Bob';
}

let person = { name: 'Alice' };
changeName(person);

console.log(person.name); // 输出 'Bob'

总结之,传递引用时,传递的是引用的地址,而不是实际的值。传递原始数据类型时,传递的是实际的值的副本。这种差异导致了在函数内部对引用数据类型的修改会影响到函数外部的变量,而对原始数据类型的修改不会影响到函数外部的变量。

☆ 数据比较方面,原始(基本)数据类型的比较是对值的比较,引用数据类型的比较是对内存地址的比较。

对于原始(基本)数据类型的比较,是对值的比较。例如:

let num1 = 5;
let num2 = 5;

console.log(num1 === num2); // true

因为num1和num2的值相同,所以比较结果为true。

引用数据类型的比较是对内存地址的比较,而不是对值的比较。这意味着当你比较两个引用数据类型的变量时,实际上是在比较它们是否指向同一个内存地址。例如:

let obj1 = { name: "John" };
let obj2 = { name: "John" };

console.log(obj1 === obj2); // false

尽管obj1和obj2的属性值相同,但它们指向的是不同的内存地址,所以比较结果为false。

OK!

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

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

相关文章

UE5——源码阅读——3——引擎退出

这边主要是做了个标记,为了UE的性能分析 把全局运行设置为0,把日志也设置为空 判断预加载屏幕 关闭visual logger 关闭资源编译的管理器 引擎预退出 预退出的核心代理 关闭网络追踪 关闭所有电影场景的捕捉接口 关闭UE中用于MID的缓存 关闭引擎…

哆啦百宝箱APP

专门为年轻人设计的APP,主打的免费、无恶心广告、不获取任何个人信息。 哆啦百宝箱 ● 永久免费 ● 无恶心广告 ● 种类巨多 ● 全民参与 ● 爆款功能 ● 用心创造 哆啦百宝箱 提供了从日常、图片、查询、设备、趣味、娱乐等多方面的功能, 操作简单&a…

postMessage

A:端口3000 import React, { useEffect } from react;function App() {useEffect(() > {const childWindow document.getElementById(child).contentWindow;const sendMessageToChild () > {childWindow.postMessage("主页面消息", "http://localhost:…

Java 数据结构篇-实现单链表核心API

🔥博客主页: 小扳_-CSDN博客 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 单链表的说明 2.0 单链表的创建 2.1 单链表 - 头插节点 2.2 单链表 - 遍历 2.2.1 使用简单的 for/while 循环 2.2.2 实现 forEach 方法 2.2.3 实现迭代器的方法 2.…

使用腾讯云服务器建站流程(新手站长指南)

使用腾讯云服务器搭建网站全流程,包括轻量应用服务器和云服务器CVM建站教程,轻量可以使用应用镜像一键建站,云服务器CVM可以通过安装宝塔面板的方式来搭建网站,腾讯云服务器网txyfwq.com分享使用腾讯云服务器建站教程,…

【网络协议】聊聊CND如何进行提升系统读性能

我们知道对于京东这种仓储来说,其实并不是在北京有一个仓储中心,而是针对全国主要的地方,北京、上海、广州、杭州,郑州等地方都有自己的仓储中心,当用户下单后,就会根据最近的仓储进行发货,不仅…

第二章:input partitioning

文章目录 Input partitioninginput partitioning 的目的computational / domain faults等价类(equivalence classes)input conditions & valid / invalid inputspartitioning and equivalence classes等价类划分的原则 白盒 - Domain testing复合谓词…

curl(七)上传和下载

一 上传 ① -T | --upload 上传 ​1、向ftp服务器 传一个文件:curl -T localfile -u name:passwd ftp://upload_site:port/path/2、向http服务器上传文件curl -T localfile http://www.wzj.com/wzj.html注意: 这时候使用的协议是HTTP的PUT…

全球首款双模型AI手机METAVERTU2,为用户开发“第二大脑”

在2023年11月1日,英国奢侈手机品牌VERTU在香港举办了一场新品发布会,它推出了一款全新的AI手机称为METAVERTU2,这是全球首款双模型AI手机。此款手机将Web3技术与人工智能相结合,通过AI模型标记数据和AI Agent的方式,将…

在线安装Arthas以及常用命令介绍

Arthas介绍:arthas(阿尔萨斯)是阿里巴巴开源的一款 Java 诊断工具,它可以对运行中的 Java 程序进行实时监控和故障排查。Arthas 提供了丰富的功能,如线程分析、内存分析、类加载分析等,帮助开发者快速定位问题并提高开发效率。 主…

自动控制原理答案

题目 现有一个单位反馈系统的开环传递函数为 试对该系统进行以下分析。 1.基础分析 计算该系统的闭环传递函数。 2.稳定性分析 2.1 使用劳斯判据分析该系统的稳定性 2.2 使用MATLAB编程,计算该系统有关于稳定性分析的零、极点,分析其稳定性。 3.暂态性…

性能测试知多少---吞吐量

我们每天的生活中都在用水用电,我只会关心自己的水管是否有水,水压是否稳定,如果我们把水龙头拧到最大,还是一滴一滴的流水。那我们就要愤怒了,直接找房东问明情况。我们从来没想过去找自来水公司。我们每天都会上网&a…

【原创】java+swing+mysql宠物领养管理系统设计与实现

摘要: 生活中,有很多被人遗弃的宠物,这些宠物的处理成为了一个新的难题。生活中也有许多人喜欢养宠物,为了方便大家进行宠物领养,提高宠物领养管理的效率和便利性。本文针对这一问题,提出设计和实现一个基…

Matlab上机三(Apriori算法)

1、题目要求 (1) 读取给定的交易数据库test3.txt,将整个交易数据库表示为一个矩阵,每个元组表示成一个行向量,向量长度为4。其中,一个项目出现在这个元组中,则相应位置设为1,否则为…

比亚迪被曝 24 小时收到 12 万份简历?

众所周知,今年找工作的难度都相当大,不论是应届毕业生还是经验丰富的职场人士,都面临相同的困境。然而,没想到情况居然如此糟糕,着实让人震惊。 最近,比亚迪公司被曝收到了12万份简历,简历投递…

深度学习框架TensorFlow.NET环境搭建1(C#)

测试环境 visual studio 2017 window10 64位 测试步骤如下: 1 新建.net framework控制台项目,工程名称为TensorFlowNetDemo,.net framework的版本选4.7.2,如下图: 2 分别安装TensorFlow.NET包(先装)和SciSharp.…

分治法——找众数

分治法——找众数 要求: 寻找整数数组的众数,如果存在多个众数,则返回权值最小的那个 第一步: 要利用分治法找众数,首先就先要使数组有序。这里,我们用C语言库中的qsort进行快排: qsort(nums…

Verilog HDL语言基础知识

目录 Verilog HDL语言基础知识 6.1.2 Verilog HDL模块的结构 6.1.3 逻辑功能定义 6.2.1 常量 6.3 运算符及表达式 6.4.2 条件语句 Verilog HDL语言基础知识 先来看两个Verilog HDL程序。 例6.1 一个8位全加器的 Verilog HDL源代码 module adder8(cout,sum,ina,…

如何用 GPT-4 全模式(All Tools)帮你高效学习和工作?

「十项全能」的 ChatGPT ,用起来感受如何? 之前,作为 ChatGPT Plus 用户,如果你集齐下面这五个模式,就会成为别人羡慕的对象。 但现在,人们更加期盼的,是下面这个提示的出现: 这个提…

Python---字符串中的count()方法

count()方法 主要功能:求子串在字符串中出现的次数 count 英 /kaʊnt/ v. (按顺序)数数;计数,点数目;把……算入,包括;重要;被允许,被接受;…