
链式学习JavaScript| 前端开发学习 |对于有c语言基础的人来说较好的学习方式(第一章:变量与作用域)
专为熟悉C/C++的开发者设计,本JavaScript系列教程旨在通过“链式学习”法,助您快速掌握前端核心,避免语言混淆。本文是系列第一章,聚焦于JavaScript与C/C++差异巨大的“变量与作用域”,这是理解JS底层逻辑的关键。 对于精通C/C++的程序员来说,学习JavaScript时最大的障碍并非语法本身,而是核心概念的转变。传统的int、char类型声明在JS中被let、const和var取代,静态类型系统也变成了动态类型。这种转变要求我们从关注“类型与内存”的底层控制,转向理解“作用域与引用”的动态行为。 本章将引导您深入探讨以下核心差异: 变量声明的演进:详细对比var、let与const在作用域、变量提升及重复声明上的不同,理解为何let和const是现代JS开发的首选。 动态与静态类型:通过实例解析JS动态类型与C++静态类型的根本区别,探讨其在开发效率和代码健壮性上的权衡。 值类型与引用类型:类比C语言的int和int*,阐明JS中原始类型与对象的赋值、比较及函数传参的内在机制。 作用域链与闭包:解释JS如何通过作用域链实现变量查找,并深入剖析其强大特性“闭包”的原理、应用场景及常见陷阱。 变量提升与暂时性死区(TDZ):揭示var的“隐式提升”与let/const的“暂时性死区”行为差异,强调规范编码的重要性。 全局对象与模块化:探讨var对浏览器全局对象window的“污染”问题,并介绍如何通过现代ES模块化方案实现作用域隔离,编写更健壮的代码。 通过本章的学习,您将为后续的JavaScript学习打下坚实的基础,真正理解其灵活背后的严谨规则,从而更高效地 transitioning 您的编程思维至前端开发领域。
链式学习JavaScript| 前端开发学习 |对于有c语言基础的人来说较好的学习方式(第一章:变量与作用域)
如果还没有配置环境建议阅读:VS-JS篇
本文的写作是建立在以下前提下的,如果希望通过阅读本无来同步javascript的朋友可以先思考以下自己是否是这个系列文章的适合人士。
前言
这个系列是对于学习过c++、c语言的人专门设计的学习教程,目的是最大程度的减少时间消耗,同时避免快速学习多门语言导致的语法混淆,这本来是博主自己的需求,但是全网没有满足这个需求比较好的文章,即使有也缺乏系列化搜索,这个系列最大的意义是它但是在AI时代,我会按照“启发式学习”的方式,将最少的文字添加在其中。
适合人群(满足其中三条以上就算适合)
- 学习过OI
- 对c的语法非常熟悉
- 喜欢阅读文档解决问题
- 有趁手的AI模型以及科学上网
- 学习计算机以自学为主
如果确定了自己适合这个教程,就可以开始阅读接下来的文章了。
阅读效率提升
- 本文按照章节-序号-单元模式,实际上序号和章节是为了版式添加的,除了标记为重要的单元内容,其他都可以跳读。
- 本文将采取词典的写作模式,即不仅为了初次阅读,更是为了后续查找,即使一开始没有学习明白,也可以在后续补充思考。
- 本文的单元鼓励采取启发式学习,会为coder提供预先准备的提示词,凭借当前的AI技术,可以通过AI来补充学习,启发式学习,而不是对着文章的文字望文生义。
- 本网站会尽力保持长期运行,但是如果词典化的需求让你担心网站的访问,我们鼓励到自己的私人知识库下载,比如语雀。
- 本文鼓励复制和转载,如果在私人途径使用,只需要找到网站的对应MD文件下载即可,如果在公网转载,只要注明出处就可以。
展示单元
章节一:变量与作用域
(章节介绍)
1.变量定义
@ 1.1.Main
(此处是标记的重要知识,全部在小结的开头,建议通过这里的一些语句思考是否已经掌握)
@ (H) 1.1.var 表示优先阅读
@ 1.1.var 表示可以补读
然后就是单元,这是最小单位。
@ 1.1.AI
(此处是学习的提示词,对于一个编号单元群,只有一组提示词,如果要单元的提示词,建议自行询问)
章节一:变量与作用域
本章将会从变量开始讲解JS语言,内容简单,建议阅读,与c、c++区别很大。 这甚至是这篇文章对于高手唯一需要阅读的地方,因为这关系语言的逻辑。
一句话说:JS没有刻意在代码上分别变量类型,不同于c++,所以基本上看不到`int,long
`这样的东西。
1.变量声明
@ 1.1.Main
@ 1.2.var
var是非常特殊的声明方法,因为var声明的变量有以下特点:
- 函数作用域 (Function Scope): var 声明的变量作用域是整个函数,或者如果在函数外声明,则是全局作用域。它没有块级作用域(即 {} 内部)。
- 变量提升 (Hoisting): 使用 var 声明的变量会被“提升”到其作用域的顶部。这意味着你可以在声明之前访问变量,但其值为 undefined。
- 可重复声明: 在同一个作用域内,可以使用 var 多次声明同一个变量名。
所以看的出来,这是一个导致bug的“粗心”变量,实际上已经没有几个人使用了,c没有这种。
@ (N)1.3.let
let基本上算得上最常用的声明方式,这可以代表声明变量,对应c++的所有常见可变变量的声明,就是c++11后的`auto,但是他们性质还是不同,auto是自动匹配,而let
`是本质上的不区分。
@ 1.4.const
const这里不做展示,可以将其理解为const let(不存在)的简写,如果let代表(int,double,long),const 代表就是 (const int,const double,const long
`)。
@ 1.5.AI
提示词1.
提示词2.
提示词3.
2.动态类型 vs 静态类型
以下是关于 动态类型(Dynamic Typing)与静态类型(Static Typing) 的详细对比与解释,结合 JavaScript(动态类型语言)和 C++(静态类型语言)作为典型代表,帮助你深入理解这两种类型系统的核心差异、优缺点及实际影响。
@ 2.1.main
动态类型让你写得快,静态类型让你改得稳。
类型系统 定义 典型语言 动态类型
(Dynamic Typing) 变量的类型在运行时根据其值动态确定。同一个变量可在不同时刻持有不同类型的数据。 JavaScript, Python, Ruby, PHP 静态类型
(Static Typing) 变量的类型在编译时必须明确声明,通常不可更改。类型错误可在编译阶段被检测出来。 C++, Java, C#, Go, Rust, TypeScript
这一节没有其他必读单元。
@ 2.2.对比
特性 动态类型(如 JavaScript) 静态类型(如 C++) 类型检查时机 运行时(Runtime) 编译时(Compile Time) 变量类型绑定 绑定到值上 绑定到变量上 类型声明 通常不需要显式声明类型 必须或推荐显式声明类型 灵活性 高:变量可随时改变类型 低:类型一旦确定,不可随意更改 错误发现时机 运行时才发现类型错误 编译时即可发现类型错误 性能 相对较低(运行时需类型判断) 相对较高(编译器可优化) 代码简洁性 简洁,写法灵活 可能更 verbose(冗长),但更明确 工具支持 IDE 智能提示较弱(除非用 TypeScript) 强大的 IDE 支持(自动补全、重构、跳转)
@ 2.3.JavaScript(动态类型)
@ 2.4. C++(静态类型)
@ 2.5.关键概念解析
@ 2.5.1. 类型安全(Type Safety)
- 静态类型语言通常具有更强的类型安全,编译器能防止很多低级错误(如调用不存在的方法)。
- 动态类型语言依赖运行时检查,容易出现
undefined is not a function
等错误。
@ 2.5.2. 鸭子类型(Duck Typing)
- 动态语言常用概念:“如果它走起来像鸭子,叫起来像鸭子,那它就是鸭子。”
- 只关心对象是否有某个方法或属性,而不关心它的具体类型。
- 示例(JS):
@ 2.6. 类型推导(Type Inference)
- 即使是静态语言,也可以“看起来像动态”:
cpp auto x = 42; // C++ 自动推导 x 为 int ts let name = "Bob"; // TypeScript 推导 name 为 string
- 但这仍然是静态类型,因为类型在编译时已确定。
@ 2.7.AI
3. 值类型 vs 引用类型
在 JavaScript 和大多数编程语言中,值类型(Value Types) 和 引用类型(Reference Types) 是理解数据存储、赋值、比较和函数传参行为的核心概念。下面我们将以 JavaScript 为主,并结合 C++ 等语言进行对比,深入解析这两者的区别。
@ 3.1.Main
值类型存“值”,引用类型存“地址”——就像 C 里的 int
和 int*
。
在内存模型上:
- 值类型:变量直接保存数据(栈上)
- 引用类型:变量保存指针(JS 中叫“引用”),指向堆上的对象
JS“指针”的写法与c中的结构体参数易混淆,实际上就是“引用类型”。
@ (H) 3.2.值类型(Primitive Types)
JavaScript 的值类型(共 7 种): 这些类型赋值时是拷贝值:
@ (H) 3.3.引用类型(Reference Types)
包括:object
, array
, function
等。
类比c++:
@ 3.4.比较行为差异
@ 3.5.函数传参的本质
注意:JS 所有参数传递都是按值传递,但引用类型的“值”是地址。
所以叫“按共享传递(call-by-sharing)”更准确。
@ 3.6.AI
4.作用域链与闭包
@ 4.1.Main
作用域链 = 变量查找路径;闭包 = 函数“记住”它的出生环境。
@ (H) 4.2.作用域链(Scope Chain)
JS 中,每个函数都有一个“作用域链”,用于查找变量。 查找规则:从内到外,逐层向上。
如果对函数不了解,可以跳读或阅读对应章节再返回,不建议强制读。
类比 C 嵌套作用域:
@ (H) 4.3.闭包(Closure)
当一个函数返回另一个函数时,内部函数仍能访问外部函数的变量——这就是闭包。
本质:闭包让函数可以“携带”其词法环境。
@ 4.4.闭包的典型用途
- 模拟私有变量
- 回调函数中保持状态
- 柯里化函数
@ 4.5.常见陷阱
@ 4.6.AI
5. 变量提升(Hoisting)与暂时性死区
@ 5.1.Main
var
会被提升到作用域顶部(值为 undefined
);let/const
也有提升,但进入“暂时性死区”。
@ (H) 5.2.var 的提升
函数声明也会提升:
```java
foo(); // 可以调用
function foo() { console.log("hoisted"); }
`
@ (H) 5.3.let/const 与暂时性死区(TDZ)
解释:
let/const
也被“提升”,但在声明前的区域称为暂时性死区(Temporal Dead Zone),访问会抛错。
@ 5.4.TDZ 的意义
- 避免
var
那种“先用后声明”的混乱 - 强制开发者按顺序书写代码
- 提高代码可读性和可维护性
@ 5.5.AI
6. 全局对象与模块作用域
@ 6.1.Main
浏览器中全局对象是 window
;现代 JS 推荐使用模块作用域避免污染全局。
@ (N) 6.2.全局对象(Global Object)
在浏览器中:
⚠️var
声明的全局变量会成为window
的属性,容易造成命名冲突。
@ (N) 6.3.模块作用域(Module Scope)
ES6 模块默认处于“严格模式”,且顶级 var/let/const
不属于全局对象。
@ 6.4.避免全局污染
- 使用
let/const
替代var
- 使用 IIFE(立即调用函数表达式)隔离作用域(旧方式)
- 使用 ES Module(现代标准)
@ 6.5.AI
第一章小结:
- 用
let
和const
替代var
(除非维护老代码) - 理解值类型 vs 引用类型的赋值与比较差异
- 闭包 = 函数 + 词法环境,是 JS 最强大的特性之一
- 变量提升对
var
是“默默 undefined”,对let/const
是“显式报错”(TDZ) - 优先使用模块化避免全局污染
💡 一句话总结本章:
JS 的变量系统看似随意,实则有一套严谨的规则。
从 C/C++ 过来,要放下“类型+内存”的控制感,转而理解“作用域+引用”的动态性。