V少JS基础班之第三弹

一、 前言

我粗略看了下函数的内容,太多与之相关的了,第二个月里函数有关的知识点太多,也不太好拆分。包括我们第一弹讲的作用域,其实也与函数有关,由于没有说到函数,所以,作用域其实也只是个入门。后面讲到函数的时候,会继续深入讲解作用域与执行上下文。按照这种情况,我需要提前进入函数的内容整理了。 那之后的JS课程我就提前预留两章出来。

之后都是每周更新一期,从JS最基础【变量与作用域】到【异步编程,密码学与混淆】。计划历时6个月左右。希望自己能坚持下来, 也希望给准备入行JS逆向的朋友一些帮助
先预告一下【V少JS基础班】的全部内容。看着很少,其实,正儿八经细分下来其实挺多的,第一个月的东西也一点不少。
第一个月【变量作用域BOMDOM 、操作符、数据类型
第二个月【函数、闭包、原型链、this】
第三个月【面向对象编程、异步编程、nodejs】
第四个月【密码学、各类加密函数】
第五个月【jsdom、vm2、express】
第六个月【基本请求库、前端知识对接】

二、本节涉及知识点

1- 数据类型
2- 操作符

三、重点内容

1- 数据类型:

很重要,认真看
JavaScript中的数据类型分两种: 一种是原始类型, 一种是引用类型。

原始类型(Primitive Types)
原始类型的值是不可变的,存储在栈内存中。它们包括:

number:数字类型,包含整数和浮点数。
string:字符串类型,一系列字符的集合。
boolean:布尔值,表示真或假。
undefined:表示未定义的值,变量声明了但未赋值时的默认值。
null:表示空或无效对象引用。
symbol:用于创建匿名唯一值的类型,常用于对象属性的标识符。

原始类型的值是不可更改的(不可变)。
变量直接存储值本身。
存储在栈内存中。
由于值本身不可改变,操作这些数据不会引发内存重分配。

引用类型(Reference Types)
引用类型包括所有复杂的数据类型,如对象、数组、函数、日期等。它们的值是对象的引用,而不是值本身。

对象(Object):一组键值对的集合,可以包含多个数据类型。
数组(Array):一种特殊类型的对象,用于存储有序的元素集合。
函数(Function):一组可以调用的代码块,用于执行某些任务。

引用类型的值是可变的,可以改变对象或数组的内容。
存储在堆内存中,但栈内存中存储的是对这些对象的引用(内存地址)。
当你将引用类型赋值给另一个变量时,你传递的是引用(内存地址),而不是值本身。

2- 栈内存&堆内存:

栈内存(Stack Memory)
栈内存用于存储原始数据类型(如数字、布尔值、字符串等)和函数调用信息。栈内存具有以下特点:
内存管理: 栈内存的分配和回收非常高效。每次函数调用时,会创建一个新的栈帧,存储局部变量,函数调用结束后,栈帧会被销毁。
存储内容: 栈内存存储的是原始类型的值以及指向堆内存中引用类型的引用(即对象、数组、函数的内存地址)。
内存生命周期: 栈内存中的数据在函数执行时分配,当函数执行完毕时,相关数据会自动销毁。
栈内存示例:

function example() {
  let num = 10; // 存储在栈内存中
  let str = 'hello'; // 存储在栈内存中
}

堆内存(Heap Memory)
堆内存用于存储引用类型的数据(如对象、数组、函数等)。堆内存的特点包括:
内存管理: 堆内存的分配和回收较为复杂,由垃圾回收机制(GC)负责。当对象不再被引用时,垃圾回收器会回收堆内存。
存储内容: 堆内存存储的是引用类型的值。栈中存储的是指向堆内存中数据的引用(即对象的内存地址)。
内存生命周期: 堆内存中的数据由垃圾回收机制管理,生命周期不固定,可能在堆内存中存在很长时间,直到没有任何引用指向它。
堆内存示例:

function example() {
  let obj = { name: 'Alice' }; // 存储在堆内存中
  let arr = [1, 2, 3]; // 存储在堆内存中
}

3- 原始类型与引用类型的区别:

赋值方式: 原始类型在赋值时会复制值本身,而引用类型在赋值时会复制引用(即内存地址)。

let x = 5;
let y = x;  // y 是 x 的副本
y = 10;     // 修改 y 不会影响 x
console.log(x);  // 输出 5
console.log(y);  // 输出 10

引用类型赋值:

let obj1 = { a: 1 };
let obj2 = obj1;  // obj2 引用 obj1
obj2.a = 2;       // 修改 obj2 会影响 obj1
console.log(obj1.a);  // 输出 2
console.log(obj2.a);  // 输出 2
小结:这里的知识点就是深拷贝&浅拷贝。在其他语言里经常会有深拷贝和浅拷贝的知识点。
我们这里就知道:浅拷贝只能拷贝原始类型, 对于引用类型使用浅拷贝,原对象修改,拷贝的对象也会变动。

类型转换的内存与计算开销:
当 JavaScript 执行类型转换时,可能会导致额外的内存分配或计算开销:
原始类型转换:原始类型之间的转换(如 number 转为 string)通常会生成一个新的值。例如,当数字 1 被转换成字符串 ‘1’ 时,JavaScript 会在堆内存中为新生成的字符串分配内存。

let num = 1;
let str = num + '';  // 1 转为字符串,创建新的字符串对象

引用类型转换:引用类型的转换(如将对象转换为基本数据类型)通常会导致临时对象的创建,增加了计算和内存开销。

let result = 1 + '1';  // 隐式类型转换,数字 1 被转为字符串 '1'
console.log(result);    // 输出 "11"

总结:
栈内存:存储原始类型的数据和函数调用信息,分配和回收非常高效。
堆内存:存储引用类型的数据,分配和回收较慢,需要垃圾回收机制来管理。
原始类型:存储值本身,分配在栈内存。
引用类型:存储内存地址(引用),分配在堆内存,栈内存存储引用。
类型转换:会增加计算和内存开销,特别是当涉及到创建新的对象时。
通过合理管理数据类型和避免不必要的类型转换,你可以提高 JavaScript 程序的效率,并更好地管理内存资源。

解析: 讲了很多我不知道大家理解了多少。 上面的总结大家认真看了应该都会有所感悟。那我这里有个点再跟大家强调一下。 
就是类型装换。 我们不论原始类型,还是引用类型。 只要涉及到类型转换,大多都与堆内存有关。 或许有人会疑惑,原始类型不是应该在栈内存吗。 
这里也很好理解。 栈内存的特点是,高效,系统自动分配,自动回收。 而且内存的大小与系统直接相关。那么如果原始类型的值过大,会导致栈溢出。
所以,为了避免性能产生的问题。 在类型转换的时候,大多会在堆内存中处理。这里也间接说明了类型转换是一个消耗性能的操作。
特征栈内存堆内存
存储内容原始类型数据(number、string、boolean)、局部变量引用类型数据(对象、数组、函数等)
分配方式操作系统自动分配,遵循 LIFO(后进先出)规则由程序员手动分配或垃圾回收自动管理
内存回收自动回收,函数执行完毕后自动销毁需要垃圾回收机制来清理不再引用的对象
生命周期与函数的生命周期一致,函数执行完后自动销毁与对象的引用计数相关,引用为 0 时被回收
大小限制内存较小,由操作系统设置内存较大,受操作系统限制较小
访问速度较快,结构简单较慢,需要通过引用访问数据
分配和释放速度分配和释放都很快分配和释放较慢,受垃圾回收影响
例子let a = 10;let person = { name: ‘John’ };

4- 类型转换(显示转换):

在 JavaScript 中,显示转换(Explicit Type Conversion)是指通过明确的代码将一种数据类型转换为另一种数据类型。这种转换是由开发者主动进行的,不像隐式转换那样由 JavaScript 引擎自动完成。
常见的显示转换方式有以下几种:

1. 字符串转换(String Conversion)
你可以使用 String() 函数或者 .toString() 方法将其他类型转换为字符串。

let num = 42;
let str = String(num);  // 显式转换为字符串
console.log(str);        // 输出 "42"

let bool = true;
let strBool = String(bool);  // 显式转换为字符串
console.log(strBool);        // 输出 "true"
数据类型转换结果
Number数字直接转换为字符串(例如 123 → “123”)
Booleantrue → “true”, false → “false”
Object对象通常转换为 “[object Object]”,除非有自定义 toString() 方法
Array数组元素通过逗号连接成字符串(例如 [1,2,3] → “1,2,3”)
Function转换为函数的代码(例如 function() {…})
null转换为字符串 “null”
undefined转换为字符串 “undefined”
Date转换为日期的字符串表示(例如 “Mon Dec 25 2024”)
空字符串 “”不变,仍然是 “”
Symbol报错:TypeError

细节1:
Symbol不可以被String()方法强转。 但是Symbol 类型提供了一个专门的方法 toString(),它可以将 Symbol 转换为字符串,返回该 Symbol 的字符串表示(包含描述信息)。

let sym = Symbol("description");
console.log(sym.toString());  // "Symbol(description)"
sym.toString() 返回 Symbol 对象的字符串表示形式,格式为 "Symbol(description)",其中 description 是创建 Symbol 时传入的可选描述。

细节2:
Object 转换为字符串:
JavaScript 对象本身并不直接具备字符串表示形式。因此,String() 方法依赖 toString() 方法来生成字符串表示。默认情况下,Object.prototype.toString() 返回的是一个固定格式的字符串 “[object Object]”,表示该对象的类型(对象)。
但是你可以通过为对象定义 toString() 方法来定制它的字符串表示。
细节3:
这个涉及到隐式转换和显示转换的区别:
显示转换:你显式地调用 String()、Number() 等方法进行转换。在这种情况下,String() 会优先调用 toString(),然后才会回退到 valueOf()。
隐式转换:通常发生在 JavaScript 执行一些操作时(比如加法、布尔值测试等),这时 JavaScript 自动调用相关类型的转换方法(如 toString() 或 valueOf())。隐式转换的规则会首先尝试 valueOf(),如果不行,才会尝试 toString()。

2. 数字转换(Number Conversion)
你可以使用 Number() 函数将其他类型转换为数字,或者使用 parseInt() 和 parseFloat() 转换为整数或浮动数值。

let str = "42";
let num = Number(str);  // 显式转换为数字
console.log(num);        // 输出 42

let bool = true;
let numBool = Number(bool);  // 显式转换为数字 (true -> 1, false -> 0)
console.log(numBool);        // 输出 1

let invalidStr = "abc";
let numInvalid = Number(invalidStr);  // 转换无效字符串为 NaN
console.log(numInvalid);    // 输出 NaN

另外,parseInt() 和 parseFloat() 用于将字符串转换为整数或浮点数:

let strInt = "42";
let intNum = parseInt(strInt);  // 显式转换为整数
console.log(intNum);            // 输出 42

let strFloat = "3.14";
let floatNum = parseFloat(strFloat);  // 显式转换为浮动数
console.log(floatNum);              // 输出 3.14
数据类型转换结果
字符串 (String)如果是有效数字字符串,转换为该数字(例如 “123” → 123);否则返回 NaN(例如 “abc” → NaN)
布尔值 (Boolean)true → 1,false → 0
对象 (Object)一般对象转换为 NaN;Date 转换为对应的时间戳(毫秒数)
null转换为 0
undefined转换为 NaN
数组 (Array)数组先转换为字符串,再转换为数字;空数组 [] 转换为 0
Symbol报错:TypeError,无法转换为数字
函数 (Function)转换为 NaN
NaN 和 InfinityNaN → NaN,Infinity → Infinity

3. 布尔值转换(Boolean Conversion)
Boolean() 函数可以将其他类型转换为布尔值。JavaScript 中有一些"假值"(falsy values),例如 0、“”、null、undefined、NaN 等,它们会被转换为 false,其余的值都转换为 true。

let str = "hello";
let boolStr = Boolean(str);  // 显式转换为布尔值
console.log(boolStr);         // 输出 true

let num = 0;
let boolNum = Boolean(num);  // 显式转换为布尔值
console.log(boolNum);         // 输出 false

let obj = {};
let boolObj = Boolean(obj);  // 非空对象转为 true
console.log(boolObj);         // 输出 true
数据类型true 转换的结果false 转换的结果
数字 (Number)10
字符串 (String)“true”“false”
对象 (Object)Boolean {true}Boolean {false}
数组 (Array)Boolean {true}Boolean {false}
nullfalsefalse
undefinedfalsefalse
NaNfalsefalse
空字符串 (“”)falsefalse
数字 0falsefalse
其他数据类型(如对象、非空字符串、非零数字等)truefalse

4. 转换为其他类型(其他方法)
有时你可能需要将一个对象转换为特定的类型,例如将对象转换为字符串。这可以通过 .toString() 方法完成。

let obj = { name: "Alice", age: 25 };
let objStr = obj.toString();  // 转换为字符串
console.log(objStr);          // 输出 "[object Object]"

你还可以通过 JSON.stringify() 方法将对象转换为 JSON 字符串:

let obj = { name: "Alice", age: 25 };
let objJson = JSON.stringify(obj);  // 转换为 JSON 字符串
console.log(objJson);               // 输出 '{"name":"Alice","age":25}'

5- NaN,null和undefined区别:

null、undefined 和 NaN 都在 JavaScript 中代表“无效”或“未定义”的值,但它们有不同的含义和用途。这里是它们的区别:

1. null
	含义:null 表示“空”或“无”。它通常用于指示一个有意为空的值。
	用途:可以在代码中明确地将一个变量设置为 null,表示这个变量目前没有有效值,但预期会有值。
	类型:null 是一个特殊的对象类型,但 typeof null 返回 'object',这是 JavaScript 的一个历史遗留问题。
	示例:
	javascript
	复制代码
	let obj = null; // 明确表示 obj 目前为空
	
2. undefined
	含义:undefined 表示“未定义”。通常,当变量声明了但没有赋值时,默认值就是 undefined。
	用途:表示一个变量或属性尚未被初始化。如果尝试访问不存在的对象属性,也会得到 undefined。
	类型:undefined 是它自己的类型。typeof undefined 返回 'undefined'。
	示例:
	javascript
	复制代码
	let value;
	console.log(value); // undefined,因为 value 没有赋值

	let obj = {};
	console.log(obj.property); // undefined,因为 property 属性不存在
3. NaN
	含义:NaN 表示“不是一个数字”(Not a Number)。通常出现在数值运算出错的情况下,例如试图将无法解析为数值的内容转换为数字。
	用途:用于表示无效的数值计算结果。例如,0 / 0、parseInt('abc') 等会返回 NaN。
	类型:NaN 是 number 类型的一部分。typeof NaN 返回 'number'。
	示例:
	javascript
	复制代码
	console.log(0 / 0);         // NaN
	console.log(Number('abc')); // NaN
	主要区别总结
	特性	null	undefined	NaN
	含义	明确为空	未定义	非数值
	产生原因	有意地表示“没有值”	未赋值或属性不存在	数值运算错误
	类型	object	undefined	number
	典型场景	空对象、空值	未初始化变量、缺失属性	无效数学计算
	特殊性比较
	null == undefined 返回 true,因为它们都表示“没有值”。
	null === undefined 返回 false,因为它们的类型不同。

	自我总结:
		nan: 是number类型,表示为非数字, 一般只有在数值运算出错的情况下出现。
		undefined: 本质是一个对象, 他就是undefined类型。 但是, 这个对象是没有被定义的。 所以为undefined
		null: 他本质是这个值为空, 但是后续可能会赋值, 只是目前为空。 但是type null 结果为对象, 这个其实是js的底层错误,是历史遗留问题

我口语化解释一下:
nan :他是个number类型。 一般都在数学计算中,才会出现nan。
undefined : 变量声明了,但是没有初始化,这时候变量就是undefined。 举例: var a;
此时a就是被声明了,但是a没有被初始化。此时的值就是undefined
null :占位空值。 记住一点,null只能是显示赋值。 意思就是null必须得是人为定义。 举例:
var a = null;我们人为的给了他一个空值。用于占位。

6- 总结:

以上是数据类型部分的知识。其中隐式转换并没有说的很细。 因为隐式转换多半涉及到操作符。 我们看完操作符,再回过头来看这个隐式转换

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

视频汇聚融合云平台Liveweb一站式解决视频资源管理痛点

随着5G技术的广泛应用,各领域都在通信技术加持下通过海量终端设备收集了大量视频、图像等物联网数据,并通过人工智能、大数据、视频监控等技术方式来让我们的世界更安全、更高效。然而,随着数字化建设和生产经营管理活动的长期开展&#xff0…

RabbitMQ工作模式(详解 工作模式:简单队列、工作队列、公平分发以及消息应答和消息持久化)

文章目录 十.RabbitMQ10.1 简单队列实现10.2 Work 模式(工作队列)10.3 公平分发10.4 RabbitMQ 消息应答与消息持久化消息应答概念配置 消息持久化概念配置 十.RabbitMQ 10.1 简单队列实现 简单队列通常指的是一个基本的消息队列,它可以用于…

No Python at ‘C:\Users\MI\AppData\Local\Programs\Python\Python39\python.exe‘

目录 一、检查环境配置 1.1 安装键盘“winR”键并输入cmd 1.2 输入“python” 二、解决问题 2.1 检查本地的python配置路径 2.2 打开PyCharm的Settings 2.3 找到Python Interpreter 2.4 删除当前python版本 2.5 新添版本 PyCharm运行时出现的错误: No Py…

EMQX5.X版本性能配置调优参数

EMQX 主配置文件为 emqx.conf,根据安装方式其所在位置有所不同: 安装方式配置文件所在位置DEB 或 RPM 包安装/etc/emqx/emqx.confDocker 容器/opt/emqx/etc/emqx.conf解压缩包安装./etc/emqx.conf EMQ X 消息服务器默认占用的 TCP 端口包括: 端口 说明…

项目报 OutOfMemoryError 、GC overhead limit exceeded 问题排查以及解决思路实战

项目报 OutOfMemoryError、GC overhead limit exceeded 问题排查以及解决思路实战 前言: 问题现象描述: 1,生产环境有个定时任务,没有初始化告警数据【告警数据量为1000多个】 2,其他定时任务执行正常 3,查…

xinput1_3.dll放在哪里?当xinput1_3.dll丢失时的应对策略:详细解决方法汇总

在计算机系统的运行过程中,我们偶尔会遇到一些令人困扰的问题,其中xinput1_3.dll文件丢失就是较为常见的一种情况。这个看似不起眼的动态链接库文件,实则在许多软件和游戏的正常运行中发挥着至关重要的作用。一旦它丢失,可能会导致…

【Compose multiplatform教程12】【组件】Box组件

查看全部组件文章浏览阅读493次,点赞17次,收藏11次。alignment。https://blog.csdn.net/b275518834/article/details/144751353 Box 功能说明:简单的布局组件,可容纳其他组件,并依据alignment属性精确指定内部组件的对…

MySql:复合查询

✨✨作者主页:嶔某✨✨ ✨✨所属专栏:MySql✨ 准备工作,创建一个雇员信息表(来自oracle 9i的经典测试表) EMP员工表DEPT部门表SALGRADE工资等级表 多表查询 显示雇员名,雇员工资以及所在部门的名字 因为…

从零创建一个 Django 项目

1. 准备环境 在开始之前,确保你的开发环境满足以下要求: 安装了 Python (推荐 3.8 或更高版本)。安装 pip 包管理工具。如果要使用 MySQL 或 PostgreSQL,确保对应的数据库已安装。 创建虚拟环境 在项目目录中创建并激活虚拟环境&#xff…

基于PREEvision的UML设计

众所周知,PREEvision是一款强大的电子电气架构协同开发及管理软件,可以很好地帮助架构工程师完成架构开发工作,其功能包括需求管理、定义功能逻辑、系统软件开发、网络设计、线束设计及整体工程的产品线管理和变形管理等。随着工程师们越来越…

Azure Function 解决跨域问题

这边前端call本地部署的azure function出现了跨域问题,搜索一下解决方案 直接修改local.setting.json,在其中添加CORS配置为通配符”*”,就行了 local.settings.json {"IsEncrypted": false,"Values": {"PYTHON_E…

Ubuntu离线安装Docker容器

前言 使用安装的工具snap安装在沙箱中,并且该沙箱之外的权限有限。docker无法从其隔离的沙箱环境访问外部文件系统。 目录 前言准备环境卸载已安装的Docker环境快照安装的Dockerapt删除Docker 安装docker-compose下载执行文件将文件移到 /usr/local/bin赋予执行权限…

CMake 构建项目并整理头文件和库文件

本文将介绍如何使用 CMake 构建项目、编译生成库文件,并将头文件和库文件整理到统一的目录中以便在其他项目中使用。 1. 项目结构 假设我们正在构建一个名为 rttr 的开源库,初始的项目结构如下: D:\WorkCode\Demo\rttr-master\|- src\ …

JAVA HTTP压缩数据

/*** 压缩数据包** param code* param data* param resp* throws IOException*/protected void writeZipResult(int code, Object data, HttpServletResponse resp) throws IOException {resp.setHeader("Content-Encoding", "gzip");// write到客户端resp…

公路边坡安全监测中智能化+定制化+全面守护的应用方案

面对公路边坡的安全挑战,我们如何精准施策,有效应对风险?特别是在强降雨等极端天气下,如何防范滑坡、崩塌、路面塌陷等灾害,确保行车安全?国信华源公路边坡安全监测解决方案,以智能化、定制化为…

uniapp 微信小程序 数据空白展示组件

效果图 html <template><view class"nodata"><view class""><image class"nodataimg":src"$publicfun.locaAndHttp()?localUrl:$publicfun.httpUrlImg(httUrl)"mode"aspectFit"></image>&l…

41.欠采样技术下变频不能用与跨两个nyquist的情况下

当接收到的信号位于同一nyquist区间时&#xff0c;信号被成功的折叠到了第一Nyquist区间中。 当接收信号位于两个或多个采样区间时&#xff0c;最后多个区间的信号都会被折叠到第一Nyquist区间中造成信号的重叠。

AI新书推荐:深度学习和大模型原理与实践(清华社)

本书简介 在这个信息爆炸、技术革新日新月异的时代&#xff0c;深度学习作为人工智能领域的重要分支&#xff0c;正引领着新一轮的技术革命。《深度学习和大模型原理与实践》一书&#xff0c;旨在为读者提供深度学习及其大模型技术的全面知识和实践应用的指南。 本书特色在于…

Vue项目中env文件的作用和配置

在实际项目的开发中&#xff0c;我们一般会经历项目的开发阶段、测试阶段和最终上线阶段&#xff0c;每一个阶段对于项目代码的要求可能都不尽相同&#xff0c;那么我们如何能够游刃有余的在不同阶段下使我们的项目呈现不同的效果&#xff0c;使用不同的功能呢&#xff1f;这里…

Ubuntu 22.04.5 修改IP

Ubuntu22.04.5使用的是netplan管理网络&#xff0c;因此需要在文件夹/etc/netplan下的01-network-manager-all.yaml中修改&#xff0c;需要权限&#xff0c;使用sudo vim或者其他编辑器&#xff0c;修改后的内容如下&#xff1a; # Let NetworkManager manage all devices on …