☰
JS零基础第一天:环境搭建、变量函数数组循环与异步核心
2026/10/2 9:33:15 网站建设 项目流程

从0学JS,最难的往往不是语法本身,而是不知道“第一天到底该学什么”。网上教程一大堆,今天看变量明天看函数,后天又跳去学框架,结果学了一个月还在原地打转。这篇笔记是Day01,也就是我这个系列的第一篇,目标很明确:把JavaScript最核心的底子打牢——开发环境怎么搭、变量和数据类型怎么玩、函数怎么写、数组怎么用、异步到底是个什么鬼。学完这一天,你至少能自己写一段小逻辑,并且能看懂别人的入门代码,不会一上来就被各种术语劝退。

我自己带过不少新人,也踩过很多自己当初学JS时踩过的坑,所以这篇笔记里的顺序、重点、案例都是按“真实新手第一天的认知节奏”来排的。不是说所有教程都得这么教,但我觉得这样学,最容易建立信心。文章会覆盖JS的基础语法、字符串处理、函数作用域、数组循环、事件循环,还会把几个高频问题——比如字符串怎么包含判断、foreach怎么打断、setTimeout返回值为什么不会有0——一并说清楚。

1. 第一天,先把JS的环境跑起来

1.1 认识JS:它到底能干什么

JavaScript不是一个只能做网页弹窗的语言。它能处理数据、操作网页上的元素、跟服务器通信,甚至现在还能写后端、写桌面应用、写小程序。但不管它的边界扩展到多远,最核心的根基只有一个:它是一门运行在“宿主环境”里的编程语言。最常见的宿主环境就是浏览器,另一个常用的宿主环境是Node.js。

对零基础的你来说,第一天不需要纠结“JS和Java是不是一回事”这种问题,只需要记住一个比喻:如果把网页比作一栋毛坯房,HTML是房子的墙体结构,CSS是墙纸和地板,JavaScript就是水电线路和智能家居系统——房子能不能真正“住起来”,全靠它。没有JS的网页是静态的,有了JS,页面才会响应你的点击、验证你的输入、动态刷新数据。

Day01的目标不是让你写出多牛的项目,而是让你建立“我能控制程序”的感觉。所以后面所有的操作,我都建议你在浏览器里直接跑,因为反馈最快、最直观,出错也最容易排查。

1.2 开发环境搭建:有浏览器就够了

很多人以为学编程要先装一堆软件,其实学JS的第一天,你只需要一个浏览器(Chrome、Edge都行)和一个文本编辑器。电脑自带的记事本都能跑,但我建议你装一个VS Code,免费、轻量、插件生态好,后期写项目也用得上。

三个环境准备步骤:

  1. 装一个现代浏览器,推荐Chrome或Edge,打开后按F12,会弹出开发者工具,点“Console”(控制台)标签页。这里就是你JS的第一块试验田。
  2. 在控制台里输入console.log('hello js')然后回车,如果打印出hello js,恭喜你,你的第一个JS程序已经跑通了。
  3. 装一个VS Code,再装一个插件叫Live Server,后面写带HTML的JS文件时会非常方便,改完代码保存,浏览器自动刷新,不用手动切换窗口。

这里有个实操心得:控制台里直接敲代码适合验证小逻辑,但真正写代码一定要养成“在文件里写、在浏览器里跑”的习惯。因为控制台一关就什么都没了,文件里写的代码才能积累、复用、回头看。

1.3 JS的三种引入方式与“网页不能访问了”这个坑

把JS写进网页有几种方式,新手最常见的问题是搞混了它们,导致页面白屏或者脚本不生效。学第一天,我建议你把三种方式都试一遍:

  • 行内引入:直接在HTML标签的事件属性里写JS,比如<button onclick="alert('hi')">点我</button>。这种方式最直观,但不推荐用于正式开发,因为代码耦合在HTML里,后期维护很痛苦。
  • 内部引入:在HTML文件的<head>或<body>里用<script>标签包一段JS代码。适合单页面小演示。
  • 外部引入:新建一个.js文件,然后在HTML里用<script src="./index.js"></script>引入。这是实际项目里最常用的方式,JS和HTML分离,各自清晰。

关于<script>标签放哪里,很多人第一次就被坑了。如果放在<head>里,而脚本又要操作body里的元素,运行时元素还没加载完,就会出现“找不到元素”的报错。我之前带新人时,有人因为这个问题折腾了一下午,页面就是没反应。解决办法很简单:要么把script标签放在</body>之前,要么给script标签加上defer属性。defer的意思是“等HTML解析完再执行我的JS”,加了它,脚本放哪里都行。

另外要提一个热词里反复出现的现象——“网页不能访问了”。新手改代码时经常遇到两种白屏情况:一是JS文件路径写错了,src指向了一个不存在的文件,控制台会报404;二是JS代码里有语法错误,导致整个脚本解析失败,页面里依赖这个脚本的动态内容全部不渲染。遇到白屏别慌,先按F12看控制台,绝大多数问题都会在那里给出明确提示。排查顺序永远是:先看报错信息,再定位代码位置,最后修复逻辑。

2 变量与数据类型:先学会“存东西”

2.1 声明变量的三种方式:var、let、const怎么选

在JS里声明变量有三种关键字:var、let、const。很多零基础的人一上来就被这三兄弟搞晕,其实记住两个原则就够用:优先用const,其次用let,var能不用就不用。

这里的逻辑很简单。const声明的变量不能重新赋值,适合用来存“不会变的东西”,比如配置项、DOM元素引用、常量列表。let则允许重新赋值,适合循环计数、临时状态这类会变化的场景。var是老时代的产物,它的作用域规则比较宽松,容易造成变量污染,ES6之后新项目基本不碰它。

实际操作中会有个微妙的问题:用const声明一个对象或数组,虽然不能重新给变量赋值,但可以修改对象的属性、往数组里push元素。这是新手最容易懵的地方。我打个比方:const声明的是“行李箱的编号”,这个编号不能换,但行李箱里装什么可以随意变。所以别担心用const会限制你的数据操作,它限制的只是变量本身的重定向。

2.2 数据类型与typeof:摸清JS的底细

JavaScript的数据类型分成两大类:基本类型和引用类型。基本类型包括number(数字)、string(字符串)、boolean(布尔值)、null(空)、undefined(未定义)、symbol(符号)、bigint(大整数);引用类型主要是object(对象),数组和函数也属于对象的特殊形态。

第一天不要求你把每种类型都研究透,但必须会用typeof这个操作符来判断一个变量的类型。比如typeof 123返回"number",typeof 'abc'返回"string",typeof true返回"boolean",typeof undefined返回"undefined"。这里有个著名的历史遗留坑:typeof null返回的是"object",这其实是早期JS的一个bug,但为了兼容性一直保留着。

理解基本类型和引用类型的区别,也是第一天的一个小重点。基本类型是“复制了一份值”,引用类型是“大家共用同一个对象”。我一般用便签做类比:基本类型就像你抄了一段笔记给同学,他改了不影响你的原文;引用类型就像一个共享文件夹,谁改了里面的文件,其他人打开看到的都是改过的内容。

2.3 几个容易混淆的“空”值

null、undefined、空字符串、0、NaN,这几兄弟在逻辑判断里都算“假值”(falsy),但它们的语义完全不同。undefined表示“变量声明了但还没赋值”,null表示“这里本该有值,但现在是空的”,空字符串表示“有值,但值是空文本”,0是数字零,NaN表示“这是一个非法的数字”。

实操中最重要的技巧是:判断一个变量到底有没有值,不要直接if (x)了事,因为空字符串和0也会走进else分支。正确做法是先确认业务场景里“空”到底指什么。比如判断用户有没有填名字,应该检查name.trim().length === 0,而不是只检查if (name)。

我刚学JS时就在这上面吃过亏:写一个购物车数量逻辑,数量为0时直接把商品移除了,因为我在判断里写了if (!count),0被当成“没填”处理了。后来才意识到,0在很多场景里是合法值,必须跟undefined和null区别对待。

3. 运算符与字符串处理:先过“逻辑关”

3.1 比较运算与“忽略大小写”问题

写JS绕不开比较运算,==和===是新手第一道坎。简单说,===会比较“类型和值是否都相等”,==则会在比较前做类型转换。举几个例子就明白了:1 == '1'返回true,因为字符串被转换成了数字;但1 === '1'返回false,因为类型不同。我在第一天给你的建议只有一条:永远用===,不要用==。它能让你的逻辑更可预期,少一堆莫名其妙的bug。

热词里那个“js忽略大小写”的问题也属于比较运算的范畴。JS默认区分大小写,所以'Hello' === 'hello'结果是false。如果你要做大小写不敏感的比较,标准做法是先把两边都转成同一种形式再比:str.toLowerCase() === target.toLowerCase()。这个技巧在用户名匹配、邮箱校验、验证码核对等场景里非常常用。

1.1 判断字符串是否包含:includes、indexOf、search

字符串包含判断是前端高频需求,热词里反复出现。JS里主要三种写法:

  • str.includes('关键字'):最直观,返回布尔值,适合日常判断。
  • str.indexOf('关键字') !== -1:传统写法,返回位置索引,找不到返回-1。
  • str.search(/正则/):支持正则,适合模糊匹配场景。

如果做忽略大小写的包含判断,组合一下就行:str.toLowerCase().includes('关键字'.toLowerCase())。很多人会问为什么需要toLowerCase而不是什么魔法参数,因为includes原生不带忽略大小写的选项,只能自己规整后再比。

indexOf和includes还有一个细节区别:indexOf接收的是字符串,不能传正则;includes也一样。要做复杂模式匹配,用search或者match更合适。第一天记住一个总结:日常八成场景用includes就够,碰到正则需求直接上search。

3.3 运算符优先级:为什么结果总跟你想的不一样

很多人写代码时会栽在运算符优先级上,比如1 + 2 * 3的结果是7,不是9,因为乘法的优先级高于加法。JS有一套完整的优先级规则,但我不建议你死记硬背,两个实用建议:

第一,使用小括号明确优先级,比如(1 + 2) * 3,代码写给别人看时,括号本身就是一种“意图注释”。

第二,注意赋值运算符和比较运算符的结合:let x = 5; x += 3这种是合法且常用的简写,但新手容易把=和===弄混,写if条件时用了单个等号导致一直返回true,然后逻辑怎么调都不对。这个坑几乎每个JS学习者都踩过,记住了就能少浪费很多时间。

除了算术优先级,还有逻辑运算的短路特性。&&和||不只是“与”和“或”,它们还会返回参与运算的值。比如0 || '默认值'返回"默认值",因为0是假值,会继续往后走;'ok' && 123返回123,因为前面是真值,结果取决于后面。第一天你不用玩太花,但至少要知道这个机制存在,之后写代码时会发现很多老手喜欢用它来写默认值。

4. 函数:把逻辑打包起来

4.1 三种函数写法:声明式、表达式、箭头函数

函数是JS最基本的“逻辑容器”,相当于工具箱里的一个个抽屉。同样一个加法功能,至少有三种写法:

// 函数声明 function add(a, b) { return a + b; } // 函数表达式 const add = function(a, b) { return a + b; }; // 箭头函数 const add = (a, b) => a + b;

这三种方式都能用,但底层细节有些差别。函数声明会被“提升”,也就是你可以在声明函数的代码之前调用它;函数表达式和箭头函数不会提升,必须先定义后使用。箭头函数还简化了写法,单行表达式会自动return结果,不需要写大括号和return。

我推荐第一天就把箭头函数作为主力,因为它更接近现代JS风格,而且写法简洁。但有一个重要区别必须知道:箭头函数没有自己的this。如果你在一个对象方法里用this访问对象属性,箭头函数会往外层作用域找this,容易出错。这个知识点第一天可以先埋个种子,等学到对象和事件绑定后再细品。

4.2 参数传递与默认值

函数在调用时可以传入参数,但如果没有传,参数默认是undefined。很多场景下我们想要一个默认值,以前需要手动判断:name = name || '匿名用户'。ES6之后直接写在参数里就行:

function greet(name = '匿名用户') { console.log('你好,' + name); } greet(); // 你好,匿名用户 greet('张三'); // 你好,张三

参数默认值不只是简单的尖括号语法,它还有几个细节:默认值可以写表达式,比如function sum(a, b = a * 2) {};默认值只在参数为undefined时生效,传null不会触发默认值。这个特性在封装组件、处理配置项时特别有用,可以减少很多“边界判断”的脏代码。

4.3 作用域与变量提升:闭包的地基

作用域是什么?简单说就是变量能访问的范围。JS有两种主要作用域:全局作用域和函数作用域。函数内部可以访问全局变量,但函数外面访问不了函数内部的变量。ES6加入的let和const还带来了块级作用域,就是用{}包裹的范围,比如if和for的代码块。

作用域链的概念也很重要:当函数里访问一个变量时,JS会先在当前作用域找,找不到就往外层找,直到全局作用域,再找不到就报错。这个“往外层找”的链式关系就是作用域链。底层逻辑类似小时候在家翻零食:先找自己房间,没有再去客厅,再没有去储藏间,整个过程是逐层向外扩展的。

变量提升则是一个容易混淆的概念。用var声明的变量会被提升到作用域顶部,但赋值不会被提升,所以会出现“变量已经存在,但值是undefined”的现象。let和const虽然也会被提升,但会进入一个“暂时性死区”,在声明之前访问会直接报错。第一天不要求你把提升机制研究透,只要记住一个准则:变量先声明,再使用,永远不要在声明前依赖它的值。

5. 数组、循环与控制流:真正开始“编程”

5.1 数组与forEach中断问题:这个坑必须说

数组是JS里最常用的数据结构,第一天至少要学会:定义数组、访问元素、遍历数组、增删元素。遍历数组最常用的方法包括for循环、forEach、map、filter等等。但有一个高频问题频繁出现在各种热词里——js foreach 打断。

forEach本身不支持break或continue。很多人试图在forEach里写break,结果直接报SyntaxError;写return,结果只是跳出当前这次回调,并不会终止整个循环。这是因为forEach的回调是每个元素独立调用的,return只能结束这一次调用。

如果确定要提前终止遍历,有几个替代方案:

  • 普通for循环或for...of循环,用break终止。
  • 用some()方法,回调返回true时终止循环。
  • 用every()方法,回调返回false时终止循环。

这里顺便说一句,some和every虽然设计初衷是“判断是否符合条件”,但完全可以借它们的终止机制来做带条件的遍历,代码还更简洁。

5.2 break、continue、return三兄弟到底咋用

新手最容易把break、continue、return混为一谈,我用一个“排队打饭”的比喻来说清楚:

  • break:你饿了,不想排队了,直接走人,整个循环结束。
  • continue:排到你发现这个菜你不吃,跳到下一个人,循环继续,但跳过当前这一次。
  • return:你不仅不排队了,还直接离开了整栋食堂大楼——因为它会跳出整个函数。

实操中的经验是:在for循环里想提前结束就break;想跳过某些值就continue;在函数里想直接返回结果给调用者就return。三者不能互相替代,用错了要么死循环要么逻辑错乱。

5.3 小实战:三级联动背后的思路雏形

热词里有一个“js三级联动”,这在表单场景里非常常见,比如选择省、市、区。三级联动的本质,其实就是一个“数据驱动视图”的思路:

  • 数据先按照层级关系组织好,比如一个省份对象里包含城市数组,城市对象里包含区县数组。
  • 当第一级下拉框变化时,拿到选中的省,取出对应城市数组,重新渲染第二级下拉框。
  • 第二级变化时,再取对应区县数组,重新渲染第三级。

第一天你不用急着实现它,但可以在脑子里建立这个“数据驱动”的模型。等后面学了DOM操作、事件监听、数组方法,你自然就能把这个思路落到代码里。很多看起来复杂的功能,拆开之后无非是数据、渲染、事件这三个环节的循环配合。

6. 异步初体验:setTimeout与事件循环

6.1 setTimeout返回值为什么不会是0

很多人第一次接触异步是从setTimeout开始的。写setTimeout(() => {}, 1000)会得到一个定时器ID,这个ID的作用是用来取消定时器,比如clearTimeout(timer)。但有一个很有意思的问题:这个ID的值范围是什么?会不会是0?

在浏览器环境中,定时器ID是一个正整数,从1开始递增,所以它不可能是0,也不会是负数。这个ID是浏览器内部用来标识定时器的句柄,每次创建定时器都会分配一个新的ID。当定时器被清除后,它的ID理论上不会马上被复用,避免混淆。在Node.js环境中,setTimeout返回的则是一个对象,不过大多数场景我们只用它来传参给clearTimeout,不用纠结具体形态。

我之所以把这个冷知识放进Day01,是因为它代表了一个重要的学习思路:不要只满足于“能用”,要习惯性地追问“为什么”。很多JS的细节,都是在这种追问中逐渐积累起来的。

6.2 单线程与事件循环:JS的底层运行模型

JavaScript是单线程语言,也就是说同一时间它只能做一件事。但你又看到它能同时处理网络请求、定时器、用户点击,这怎么做到?答案就是事件循环。

我常用一个“食堂打饭”的比喻:主线程是打饭阿姨,事件循环是排队队伍,事件队列是装菜品的保温台。一个客人想点A菜,但A菜还没做好,阿姨不会停下来盯着锅,而是先把这事记下来,继续给下一位客人打饭。等A菜好了,阿姨再回头处理那位客人的单子。所有同步任务就是已经做好的菜,随到随取;异步任务就是需要等待的菜,先在保温台排着,等条件满足后再回到主线程处理。

第一天你不需要把宏任务和微任务的细节背下来,但至少要建立起“JS代码不是从上到下一行行走完的,中间会穿插异步回调”这个认知。这是接下来理解Promise、async/await、事件监听、接口请求的基础。

实际开发中,很多页面假死、白屏、数据加载不出来的问题,根源都是事件循环被同步任务阻塞了。比如一个大for循环里跑了大量复杂计算,用户点击按钮就没反应,因为主线程被占用了。理解了事件循环,你就知道那些“卡住”的现象不是玄学,而是主线程被占满,事件队列里的任务处理不了。

6.3 初学者第一天上手容易踩的5个坑

最后把Day01最常碰到的问题整理成一个速查表,方便你随时对照排查:

现象原因解决思路
页面白屏,没有任何内容JS文件路径错误或语法错误F12打开控制台看报错,先解决脚本加载和解析问题
打印出来是undefined变量声明了但没赋值,或者函数没有return检查赋值语句是否执行,确认返回值
比较结果老是不对用了==,或者类型没统一统一用===,必要时先转换类型
字符串“包含”判断失败大小写不一致toLowerCase后再includes
forEach里break报错forEach不支持break改用for循环、some或every实现提前终止
点击事件绑不上script标签放在head里且没加deferscript移到body末尾,或加defer属性

这五条经验都是我自己带新人时最常见的现场翻车场景。第一天踩坑不可怕,可怕的是不知道怎么排查。学会打开控制台、读报错、定位问题,这比背过一百条语法都管用。

我个人在实际操作中的体会是:学JS的第一天,最重要的不是记语法,而是建立“调试肌肉记忆”。每写一段代码,就养成按F12看一眼Console的习惯;每次报错,先读第一行错误信息,再点进对应文件定位行号。这套动作练熟了,后面的学习速度会成倍加快。第一天先把环境跑起来,把变量、函数、数组、循环这几个最基本的组件练手,再感受一下异步的节奏,后面的路就有底气了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询