前端百题斩【003-004】——从基本类型、引用类型到包装对象

简介: 前端百题斩【003-004】——从基本类型、引用类型到包装对象

1. 基本类型和引用类型


1.1 基本类型


js中基本数据类型包含:Number(数值)、String(字符串)、Boolean(布尔值)、Null、Undefined、Symbol(ES6引入的,表示独一无二的),其有以下特点:

  1. 基本类型的访问是按值访问的;
  2. 不能添加属性和方法;
  3. 基本类型的变量时存在放栈区的,包括变量标识符和变量的值。(栈区不会设置太大,主要用来存在基本类型);
  4. 基本类型的复制就是在栈内存中开辟一个新的存储区域来存储新的变量;
  5. 基本类型的比较是值比较的。

640.png


1.2 引用类型


js中引用类型包含三类:

  1. 基本引用类型:Object(对象)、Array、RegExp、Date、Function;
  2. 基本包装类型:String、Number、Boolean;
  3. 单体内置对象:Global、Math。

其具有以下特点:


  1. 引用类型的值是按引用访问的;
  2. 引用类型可以拥有属性和方法,且可动态改变;
  3. 存储需要内存的栈区和堆区,其中栈区保存变量标识符和指向内存中该对象的指针;
  4. 引用类型的比较是引用的比较;
  5. 引用类型的复制将复制引用地址。


640.png


1.3 扩展——为什么需要“栈”和“堆”两个存储空间


因为JavaScript引擎需要用栈来维护程序执行期间上下文的状态(调用栈),如果栈空间太大的话(即所有数据都存储在栈空间中),会影响上下文的切换效率,进而影响整个程序的执行效率,所以通常情况下栈空间不会设置太大,用于存储基本类型这样的小数据,而引用类型将存储到堆中。

2.包装对象



2.1 背景


有一个奇怪的现象不知道大家注意过没有,字符串、数字、布尔值都能够调用属性和方法,例如:

const str = '123';
console.log(typeof(str)); // string
console.log(str.toString()); // 123
const num = 123; 
console.log(typeof(num)); // number
console.log(num.toString()); // 123
const bool = true;
console.log(typeof(bool)); // boolean
console.log(bool.toString()); // true

看到这个现象,大家是不是感觉很奇怪,这与我们平时的想法是相悖的,毕竟我们认为基本类型上面是不存在属性和方法的,这个时候主角包装对象就出现了。

2.2 包装对象


JS 的数值,布尔,字符串类型的变量,在一定条件下,也可以自动变成对象,这就是原始类型的包装对象。包装对象其实是一种特殊的引用类型,其与引用类型的主要区别在于生命周期。

  1. 一般的引用类型在使用new创建其实例时,在执行流离开当前作用域之前一直都保存在内存中;
  2. 包装类型的对象只存在该行代码的执行瞬间,然后会立即被销毁。(也意味着在运行时不能为基本类型添加属性和方法)


2.3 包装对象后台执行流程


基本类型中的String、Number、Boolean在调用属性和方法的时候,后台是怎样执行的呢?其实整个过程可以简化为三步:

  1. 创建一个对象类型的实例,例如字符串则创建一个String类型的实例;
  2. 调用该实例对象上的特定方法;
  3. 销毁该实例。

以字符串为例,来演示该流程:

const str = 'abc';
const strNew = str.substring(0, 2);

在运行到str.substring(0, 2)的时候其实偷偷执行了以下三步:

let strObj = new String(str);
const strNew = strObj.substring(0, 2);
strObj = null;

2.4 扩展


  1. 包装对象和同样的原始类型的值相等吗?

不相等。因为包装对象是引用类型,原始类型是基本类型;包装对象的最大目的,首先是使得 JavaScript 的对象涵盖所有的值,其次使得原始类型的值可以方便地调用某些方法。

  1. 如何给基本类型添加属性和方法?

在基本包装对象的原型下面添加,每个对象都有原型。

  1. 同一个字符串调用两次相同的方法其包装对象相等吗?

不相等。调用结束后,包装对象实例会自动销毁。这意味着,下一次调用字符串的属性时,实际是调用一个新生成的对象,而不是上一次调用时生成的那个对象,这也说明了为什么不能直接给字符串、数字、布尔值添加属性和方法。







相关文章
|
5月前
|
前端开发 开发者
new操作符背后的秘密:揭开Web前端对象创建的神秘面纱!
【8月更文挑战第23天】在Web前端开发中,`new`操作符是创建对象实例的核心。本文以`Person`构造函数为例,通过四个步骤解析`new`操作符的工作原理:创建空对象、设置新对象原型、执行构造函数并调整`this`指向、判断并返回最终对象。了解这些有助于开发者更好地理解对象实例化过程,从而编写出更规范、易维护的代码。
46 0
|
2月前
|
存储 前端开发 JavaScript
前端中对象的深度应用与最佳实践
前端对象应用涉及在网页开发中使用JavaScript等技术创建和操作对象,以实现动态交互效果。通过定义属性和方法,对象可以封装数据和功能,提升代码的组织性和复用性,是现代Web开发的核心技术之一。
|
3月前
|
JSON 前端开发 数据格式
前端的全栈之路Meteor篇(五):自定义对象序列化的EJSON介绍 - 跨设备的对象传输
EJSON是Meteor框架中扩展了标准JSON的库,支持更多数据类型如`Date`、`Binary`等。它提供了序列化和反序列化功能,使客户端和服务器之间的复杂数据传输更加便捷高效。EJSON还支持自定义对象的定义和传输,通过`EJSON.addType`注册自定义类型,确保数据在两端无缝传递。
|
4月前
|
前端开发 JavaScript
前端基础(十四)_Math对象
本文介绍了JavaScript中`Math`对象的常用方法,包括: 1. `Math.floor()`:向下取整,去掉小数部分。 2. `Math.ceil()`:向上取整,向上进一。 3. `Math.round()`:四舍五入,针对小数点后面第一位数字。 4. `Math.max()`:获取数字序列中的最大值。 5. `Math.min()`:获取数字序列中的最小值。 6. `Math.pow()`:计算某个数字的次方数。 7. `Math.sqrt()`:开根号。 8. `Math.random()`:生成一个0到1之间的随机数。
28 1
前端基础(十四)_Math对象
|
3月前
|
JSON 前端开发 数据格式
@RequestMapping运用举例(有源码) 前后端如何传递参数?后端如何接收前端传过来的参数,传递单个参数,多个参数,对象,数组/集合(有源码)
文章详细讲解了在SpringMVC中如何使用`@RequestMapping`进行路由映射,并介绍了前后端参数传递的多种方式,包括传递单个参数、多个参数、对象、数组、集合以及JSON数据,并且涵盖了参数重命名和从URL中获取参数的方法。
272 0
@RequestMapping运用举例(有源码) 前后端如何传递参数?后端如何接收前端传过来的参数,传递单个参数,多个参数,对象,数组/集合(有源码)
|
4月前
|
前端开发 JavaScript
前端基础(十五)_时间对象、字符串对象
本文介绍了JavaScript中时间对象的操作方法,包括获取和设置年、月、日、小时、分钟、秒等,以及如何格式化时间显示,同时提及了字符串对象的常用方法。
36 0
前端基础(十五)_时间对象、字符串对象
|
5月前
|
缓存 前端开发 Java
【前端学java】复习巩固-Java中的对象比较(15)
【8月更文挑战第11天】Java中的对象比较
37 1
|
4月前
|
前端开发 JavaScript
前端基础(十六)_数组对象
本文详细介绍了JavaScript中数组对象的创建和操作方法,包括数组的增删改查、排序、去重、迭代等常用操作。
22 0
|
5月前
|
JavaScript 前端开发 API
前端开发者的救赎:揭秘JQ对象与DOM元素的神秘转换术
【8月更文挑战第23天】在Web前端开发领域,jQuery(简称JQ)作为一款流行的JavaScript库,极大简化了HTML文档遍历、事件处理、动画及Ajax交互等操作。理解和掌握jQuery对象与DOM元素间的转换至关重要。
50 0
|
5月前
|
存储 运维 前端开发
中后台前端开发问题之定义编排对象如何解决
中后台前端开发问题之定义编排对象如何解决
31 0