JavaScript引用数据类型和构造函数的秘密

简介: JavaScript引用数据类型和构造函数的秘密

前言

今天我们就来聊聊JavaScript中的引用数据类型和构造函数,引用数据类型和原始类型有什么区别呢?构造函数创造变量时,前面为什么要加new呢?

JavaScript中的数据类型分为两大类:原始数据类型(Primitive Data Types)引用数据类型(Reference Data Types)。

  • 原始数据类型

1.字符串(String) : 用于表示文本,用单引号(')或双引号(")括起来。

let name = 'John';

2.数字(Number) : 用于表示数值,包括整数和浮点数。

let age = 25;

3.布尔值(Boolean) : 用于表示真(true)或假(false)。

let isStudent = true;

4.未定义(Undefined) : 表示一个变量已声明但未赋值。

let variable;

5.空值(null) : 表示一个变量没有值或对象为空。

let emptyValue = null;

引用数据类型

1.对象(Object) : 用于表示复杂数据结构,可以包含多个属性和方法。

const person = {
  name: 'Alice',
  age: 30,
};

2.数组(Array) : 用于存储多个值的有序列表。
const numbers = [1, 2, 3, 4, 5];

3.日期(Date) : 用于表示日期和时间。

let today = new Date();

还有函数等等引用数据类型,我们下次再介绍。

引用数据类型跟原始数据类型有什么区别呢? 这里我们拿对象来解释一下,我们先来看一道题。

let obj = {
    name: '菌菌'
}
let lw = obj
obj.name = '来颗奇趣蛋'
console.log(lw.name);

如果不太了解引用数据类型的小伙伴们,这里可能就会觉得输出菌菌了。让我们来看看输出结果:

image.png

我们可以看到,这里输出了来颗奇趣蛋。这是为什么呢,我们修改obj.name,为什么lw.name也被修改了呢?这其实就是引用数据类型和原始数据类型的区别了,我们可以用两句话来概括一下。

  • 原始类型的值是存在调用栈中的
  • 引用类型的值是存在堆当中,但是会将引用地址存在栈中

这里我们画张图来理解一下:(图画的不是很好,请见谅)

image.png

实际上,引用数据的值存放在堆区,也就是图中黄色框框所在的位置,堆区中存在着一段连续的地址,而这些地址又对应引用数据的值,如图中的1005,而栈区中变量存储的是堆区中的地址,就如图中obj = 1005,所以通过这些地址值,我们就可以访问堆区中的值,这里也可以叫指针

为什么改变obj.name会影响到lw.name呢?从图中观察到,obj和lw存储着相同的指向堆区的地址。当let obj = {...}时,obj会将变量的值的地址存储进去,这里为obj = 1005,而真正的变量值存储在堆区。当赋值语句lw = obj时,lw被赋值为obj相同的地址,lw = 1005.

而当执行到obj.name = '来颗奇趣蛋'时,先在栈区寻找变量obj,发现obj存储的是一段地址,然后会顺着obj存储的地址来到堆区,将堆区中name的值改为'来颗奇趣蛋'.所以当输出lw.name时,发现lw的值为1005,为地址,顺着地址找到了堆区中name的值,但此时name的值已经被修改为'来颗奇趣蛋',所以输出'来颗奇趣蛋',引用数据类型共享变量。

构造函数

我们想创建一个对象,有几种方法呢?

  1. 对象字面量(对象直接量)
var obj = {} //对象字面量||对象直接量
  1. 构造函数
let obj = new Object()  //构造函数
  1. 自定义构造函数

我们来写一个构造车对象的构造函数

function Car(name,color,size) {
    this.name = name
    this.color = color
    this.size = size
}
let car1 = new Car('BMW','red','long')   // 实例对象
let car2 = new Car('奔驰','green','short')

自定义构造函数跟构造函数方法差不多,只是自定义构造函数是我们人为的写出一个方法,而构造函数可以直接使用。我们将用构造函数声明出的对象,叫做实例对象。我们输出一下用自定义构造函数声明出的两个对象:

image.png

构造函数就像工厂,可以批量化生成对象

在上面的例子中,我们可以发现,使用构造函数创建对象时,必须要在前面加上一个new,那new的作用是什么呢?

构造函数中new的作用

我们首先可以试试,当使用构造函数时,不加new会怎么样:

function Car(name,color,size) {
    this.name = name
    this.color = color
    this.size = size
}
let car = Car('BMW','red','short')

输出一下 image.png

我们可以发现,当我们输出car时,它的值为undefined,这里我们可以想一下,因为这个构造函数里面并没有返回值,那我们输出创建的对象时,应该是找不到这个值的。那为什么在构造函数创建对象时,在前面加一个new时,就可以创建一个有值的对象呢?

其实,当我们加入new关键字时,它会在构造函数内创建一个this对象,然后将属性传入this对象里面,最后return this对象,所以就有值了

function Car(name,color,size) {
    this.name = name
    this.color = color
    this.size = size
    // let this = {
    //     name: name,
    //     color: color
    //     size: size
    // }
    // return this
}
let car =  new Car('BMW', 'red', 'short')
console.log(car);

而这里的this对象其实就是由构造函数创造的实例对象,关于this小伙伴们可以先这样理解,后面的文章我们会仔细分析。所以,当我们在构造函数前加入new关键字时,在函数内部就会有一个返回值,所以我们创造出的实例对象是有值的。

总结

  • 原始类型的值是存在调用栈中的
  • 引用类型的值是存在堆当中,但是会将引用地址存在栈中
  • new会在函数内部生成一个this对象,最后返回this对象

今天的内容就到这啦,如果你觉得小编写的还不错的话,或者对你有所启发,请给小编一个辛苦的赞吧


相关文章
|
2月前
|
存储 JavaScript 对象存储
js检测数据类型有那些方法
js检测数据类型有那些方法
140 59
|
3月前
|
JavaScript
js基础数据类型
js基础数据类型
30 1
|
29天前
|
存储 JavaScript 前端开发
JavaScript 数据类型详解:基本类型与引用类型的区别及其检测方法
JavaScript 数据类型分为基本数据类型和引用数据类型。基本数据类型(如 string、number 等)具有不可变性,按值访问,存储在栈内存中。引用数据类型(如 Object、Array 等)存储在堆内存中,按引用访问,值是可变的。本文深入探讨了这两种数据类型的特性、存储方式、以及检测数据类型的两种常用方法——typeof 和 instanceof,帮助开发者更好地理解 JavaScript 内存模型和类型检测机制。
68 0
JavaScript 数据类型详解:基本类型与引用类型的区别及其检测方法
|
1月前
|
JavaScript 前端开发 开发者
【干货拿走】JavaScript中最全的数据类型判断方法!!!!
【干货拿走】JavaScript中最全的数据类型判断方法!!!!
22 1
|
30天前
|
存储 JavaScript 前端开发
JavaScript数据类型全解:编写通用函数,精准判断各种数据类型
JavaScript数据类型全解:编写通用函数,精准判断各种数据类型
18 0
|
2月前
|
存储 前端开发 JavaScript
前端基础(三)_JavaScript数据类型(基本数据类型、复杂数据类型)
本文详细介绍了JavaScript中的数据类型,包括基本数据类型(Number、String、Boolean、Undefined、Null)和复杂数据类型(Object),并解释了如何使用`typeof`操作符来识别变量的数据类型。同时,还讨论了对象、函数和数组等复杂数据类型的使用方式。
44 2
|
2月前
|
JavaScript 前端开发
JavaScript基础知识-构造函数(也称为"类")定义
本文介绍了JavaScript中构造函数(也称为“类”)的定义和使用方法。
34 1
JavaScript基础知识-构造函数(也称为"类")定义
|
2月前
|
JavaScript 前端开发
JavaScript基础知识-基本数据类型和引用数据类型
关于JavaScript基础知识的文章,主要介绍了基本数据类型和引用数据类型。
41 2
JavaScript基础知识-基本数据类型和引用数据类型
|
3月前
|
JavaScript 前端开发
JavaScript基础&实战(1)js的基本语法、标识符、数据类型
这篇文章是JavaScript基础与实战教程的第一部分,涵盖了JavaScript的基本语法、标识符、数据类型以及如何进行强制类型转换,通过代码示例介绍了JS的输出语句、编写位置和数据类型转换方法。
JavaScript基础&实战(1)js的基本语法、标识符、数据类型
|
3月前
|
开发者 图形学 开发工具
Unity编辑器神级扩展攻略:从批量操作到定制Inspector界面,手把手教你编写高效开发工具,解锁编辑器隐藏潜能
【8月更文挑战第31天】Unity是一款强大的游戏开发引擎,支持多平台发布与高度可定制的编辑器环境。通过自定义编辑器工具,开发者能显著提升工作效率。本文介绍如何使用C#脚本扩展Unity编辑器功能,包括批量调整游戏对象位置、创建自定义Inspector界面及项目统计窗口等实用工具,并提供具体示例代码。理解并应用这些技巧,可大幅优化开发流程,提高生产力。
351 1