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

这篇具有很好参考价值的文章主要介绍了JavaScript引用数据类型(对象类型)和原始(基本)数据类型特点比较。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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),可以安全地存储和操作大整数。 ECMAScript 2020 引入了一个新的原始数据类型BigInt,用于表示任意精度的整数。在之前的版本中,JavaScript只能表示有限范围的整数,超出范围的整数会被转换为特殊的Infinity值。

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

7.符号(Symbol,在 ECMAScript 2015 / ES6 中新添加的类型)。一种实例是唯一且不可改变的数据类型。

二)对象(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.1;
let b = a;
b = 10.2;

console.log(a); // 输出 5.1
console.log(b); // 输出 10.2

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

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

【图中的红色❌,表示5.1这个值不再被变量a引用,若一个值不再被任何变量引用,可以被垃圾回收器标记为可回收的,具体的垃圾回收时间是由JavaScript引擎决定的。】

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

例如:

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

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

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

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

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

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

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

例如:

function addTen(num) { // num 是一个局部变量
    num += 10;
    return num;
}

let count = 20;
let result = addTen(count);
console.log(count);   // 20,没有变化
console.log(result);   // 30

解析如下:

此例展示了在 JavaScript 中传递变量的值的方式。

例中定义了一个函数 addTen,它接受一个参数 num。

在此主要关注变量情况:

首先,定义了一个变量 count,并赋值为 20。

接下来,调用 addTen 函数,并将 count 作为参数传递进去。这里需要注意的是,虽然 count 的值是 20,但是在函数中传递的是 count 的值的副本,而不是 count 本身。

在函数内部,num 的值被增加了 10,变成了 30。然后,函数返回了这个新的值,并将其赋给了变量 result。

最后,通过 console.log 打印了 count 和 result 的值。由于在函数中传递的是 count 的值的副本,所以 count 的值没有发生变化,仍然是 20。而 result 的值是函数返回的新值,即 30。图解如下:

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

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

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

例如:

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

let person = { name: 'Alice' };
console.log(person.name); // 输出 'Alice'

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

解析如下:

此例展示了在 JavaScript 中传递对象的引用的方式。

例中定义了一个函数 changeName,它接受一个参数 obj。

在此主要关注变量情况:

首先,定义了一个对象 person,并赋值为 { name: 'Alice' }。这个对象有一个 name 属性,其初始值为 ‘Alice’。

接下来,通过 console.log 打印了 person.name 的值,即 ‘Alice’。

然后,调用 changeName 函数,并将 person 对象作为参数传递进去。这里需要注意的是,虽然 person 是一个对象,但是在函数中传递的是 person 对象的引用,而不是对象本身的副本。

在函数内部,通过修改 obj 的 name 属性,将其值改为 ‘Bob’。由于 obj 是 person 对象的引用,所以这个修改也会影响到 person 对象本身。

最后,通过 console.log 打印了 person.name 的值,即 ‘Bob’。由于在函数中修改了 person 对象的 name 属性,所以 person.name 的值变成了 ‘Bob’。图解如下:

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

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

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

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

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。

补充、关于“JavaScript(JS)参数传递按值传递” MDN Web Docs说法

Arguments are always passed by value and never passed by reference. This means that if a function reassigns a parameter, the value won't change outside the function. More precisely, object arguments are passed by sharing, which means if the object's properties are mutated, the change will impact the outside of the function.
【选自https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions 】
译文:实参总是按值传递,而不是按引用传递。这意味着,如果函数重新赋值一个参数,该值在函数外部不会改变。更准确地说,对象参数是通过共享传递的,这意味着如果对象的属性发生了变化,那么这种变化将影响函数的外部。
解析一下:
JS调用函数时,参数本质上是按值传递给函数的。传递给函数的值被称为函数的实参(值传递),对应位置的函数参数名叫作形参。如果实参是一个包含原始值 (数字,字符串,布尔值) 的变量,则就算函数在内部改变了对应形参的值,返回后,该实参变量的值也不会改变。如果实参是一个对象引用,则对应形参会和该实参指向同一个对象。假如函数在内部改变了对应形参的值,返回后,实参指向的对象的值也会改变。

附录
JavaScript中的可变(Mutable)、不可变(Immutable)和变量的赋值介绍 https://blog.csdn.net/cnds123/article/details/134036700

多种(C++、Java、JavaScript、Python)编程语言参数传递方式介绍 https://blog.csdn.net/cnds123/article/details/132981086

ECMAScript 中变量的复制,以及函数的参数传递
https://juejin.cn/post/6953878356836384805文章来源地址https://www.toymoban.com/news/detail-743099.html

到了这里,关于JavaScript引用数据类型(对象类型)和原始(基本)数据类型特点比较的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [Java]关于基本数据类型与引用类型赋值时的底层分析的小结(简述)

    【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://www.cnblogs.com/cnb-yuchen/p/17969159 出自【进步*于辰的博客】 目录 1、关于赋值 1.1 基本数据类型赋值 1.2 String类型赋值 2、关于String赋值 2.1 情形一 2.2 情形二 3、关于String与char[]的比较 4、不同类型引

    2024年01月17日
    浏览(28)
  • JavaScript—数据类型、对象与构造方法

    JavaScript(简称“JS”) 是一种具有函数优先的轻量级,解释型或即时编译型的编程语言。JavaScript 基于原型编程、多范式的动态脚本语言,并且支持面向对象、命令式、声明式、函数式编程范式。 (1)脚本语言。js不编译,直接解释执行 (2)基于对象。JavaScript是一种基于对象的

    2024年02月10日
    浏览(25)
  • 懒得改变原始对象?JavaScript代理模式教你怎样一步步偷懒!

    系列首发gong zhong hao[『非同质前端札记』] ,若不想错过更多精彩内容,请“星标”一下,敬请关注gong zhong hao最新消息。 何为代理模式 例如,你想预约一家公司的董事长会面,按照正常流程,你只能通过先联系他的秘书,然后跟他的秘书预约时间,约好时间后你们两个才能

    2024年02月15日
    浏览(24)
  • JavaScript变量与基本数据类型

    目录 一、声明变量 (1)let (2)const (3)var 二、基本类型 (1)undefined和null (2)string (3)number和bigin (4)boolean (5)symbol         JavaScript(JS)是一种具有 函数优先 特性的轻量级、解释型或者说 即时编译型 的编程语言。虽然作为 Web 页面中的脚本语言被人所熟知

    2023年04月15日
    浏览(33)
  • JVM零基础到高级实战之对象存活算法引用计数法存在的特点分析

    JVM零基础到高级实战之对象存活算法引用计数法存在的特点分析 JVM零基础到高级实战之对象存活算法引用计数法存在的特点分析 优点 引用计数收集器可以很快的执行,交织在程序运行中。对程序需要不被长时间打断的实时环境比较有利。 缺点 无法检测出循环引用。如父对

    2024年02月15日
    浏览(79)
  • JVM 对象引用类型

    对象引用类型分为强引用、软引用、弱引用和虚引用。 强引用         声明对象时虚拟机生成的引用,是指在程序代码之中普遍存在的引用赋值。强引用环境下,垃圾回收时需要严格判断当前对象是否被强引用,如果被强引用,则不会被垃圾回收,当内存空间不足的时候

    2024年02月09日
    浏览(29)
  • JavaScript中对象的定义、引用和复制

    JavaScript是一种广泛使用的脚本语言,其设计理念是面向对象的范式。在JavaScript中,对象就是一系列属性的集合,每个属性包含一个名称和一个值。属性的值可以是基本数据类型、对象类型或函数类型,这些类型的值相互之间有着不同的特点。本文将探讨JavaScript中对象的定义

    2024年02月02日
    浏览(23)
  • kotlin学习(一)基本概念、数据对象类型、控制流程、空值检验、类与接口

    kotlin与java语言一样,编译成字节码后,在JVM虚拟机中运行。kotlin语言的特性依赖于kotlin的语法编译器。与kotlin类似的语言还有: Scala:大数据领域开发语言 Groovy:基于 JVM 平台的动态脚本语言, 在安卓开发中用来编写依赖关系、插件等 2019年谷歌宣布Kotlin成为安卓第一开发语

    2024年02月09日
    浏览(29)
  • 1.原始数据的对象包装器 - JS

    已知,JS 中数据类型分为两种: 原始数据类型:数、字符串、布尔值、大数、Symbol、null、undefined(7个); 引用数据类型:对象(自定义对象、内置对象 Array/Map/Set/Date/Error/Promise……)。 对于原始数据和部分对象,允许通过字面量进行赋值操作。但是不影响两种数据的存储

    2024年02月19日
    浏览(25)
  • 第五章 基本引用类型(上)——Date、RegExp

            引用值(或者对象)是某个特定引用类型的实例。在ECMAScript中,引用类型是把数据和功能组织到一起的结构,经常被人错误地称作“类”。虽然从技术上讲JavaScript是一门面向对象语言,但ECMAScript缺少传统的面向对象编程语言所具备的某些基本结构,包括类和接口

    2024年01月17日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包