ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

JS零基础第一天:环境搭建、变量函数数组循环与异步核心

JS零基础第一天:环境搭建、变量函数数组循环与异步核心 从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免费、轻量、插件生态好后期写项目也用得上。三个环境准备步骤装一个现代浏览器推荐Chrome或Edge打开后按F12会弹出开发者工具点“Console”控制台标签页。这里就是你JS的第一块试验田。在控制台里输入console.log(hello js)然后回车如果打印出hello js恭喜你你的第一个JS程序已经跑通了。装一个VS Code再装一个插件叫Live Server后面写带HTML的JS文件时会非常方便改完代码保存浏览器自动刷新不用手动切换窗口。这里有个实操心得控制台里直接敲代码适合验证小逻辑但真正写代码一定要养成“在文件里写、在浏览器里跑”的习惯。因为控制台一关就什么都没了文件里写的代码才能积累、复用、回头看。1.3 JS的三种引入方式与“网页不能访问了”这个坑把JS写进网页有几种方式新手最常见的问题是搞混了它们导致页面白屏或者脚本不生效。学第一天我建议你把三种方式都试一遍行内引入直接在HTML标签的事件属性里写JS比如button onclickalert(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其次用letvar能不用就不用。这里的逻辑很简单。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返回numbertypeof abc返回stringtypeof true返回booleantypeof 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后再includesforEach里break报错forEach不支持break改用for循环、some或every实现提前终止点击事件绑不上script标签放在head里且没加deferscript移到body末尾或加defer属性这五条经验都是我自己带新人时最常见的现场翻车场景。第一天踩坑不可怕可怕的是不知道怎么排查。学会打开控制台、读报错、定位问题这比背过一百条语法都管用。我个人在实际操作中的体会是学JS的第一天最重要的不是记语法而是建立“调试肌肉记忆”。每写一段代码就养成按F12看一眼Console的习惯每次报错先读第一行错误信息再点进对应文件定位行号。这套动作练熟了后面的学习速度会成倍加快。第一天先把环境跑起来把变量、函数、数组、循环这几个最基本的组件练手再感受一下异步的节奏后面的路就有底气了。
返回列表