ARTICLE DETAIL

资讯详情

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

JavaScript入门核心知识点梳理:从变量到调试再到框架

JavaScript入门核心知识点梳理:从变量到调试再到框架 JavaScript入门最难的其实不是语法而是搞不清自己到底卡在哪一步。我带过不少转行做前端的同事见过太多人一上来就追着框架跑React、Vue学了一大堆结果让他写一个变量交换、循环遍历数组还要想半天。也有朋友把文档翻了好几遍看到函数和对象直接懵掉。做了这么多年前端我自己的体会是入门阶段最重要的不是学多少新东西而是把语言的核心机制弄明白知道一段代码为什么这样写、报错在说什么。这篇文章我就按平时带新人的思路把JavaScript入门必须过一遍的知识点串起来从变量、数据类型到函数、循环、事件处理再到调试和框架认知全部用实际例子讲清楚适合零基础或者学了一阵还觉得不够系统的同学。1. 先搞清楚JavaScript到底是个什么角色1.1 它和HTML、CSS的分工很多新手第一句话就是“我到底先学HTML还是先学JavaScript”我的回答是不是先后关系是分工关系。你可以把网页想象成一栋毛坯房HTML是房子的梁柱和墙体负责结构CSS是墙壁刷漆、地板瓷砖、家具摆放负责外观JavaScript则是水电管线、电梯、开关面板负责让房子“活起来”——按钮能点、表单能提交、数据能刷新、动画能动。没有JavaScript的网页也不是不能用但它只能看不能玩。你点击一个按钮没反应输入内容不能即时校验下拉菜单不展开轮播图不滚动这些“交互”全是JavaScript在背后干活。所以入门JavaScript本质上就是学会控制浏览器里的页面元素并且处理用户的操作。1.2 JavaScript运行在哪里浏览器和Node.jsJavaScript最初就是给浏览器用的每个现代浏览器都内置了JavaScript引擎。你在浏览器里写的脚本可以直接操作页面上的HTML标签和CSS样式也可以通过fetch去请求后台数据。这是前端的基础。后来出现了Node.js它把JavaScript引擎单独抽出来跑在服务器上于是JavaScript也能写后端了。但对入门者来说先认准一个环境就好浏览器。你不需要装任何额外软件记事本加浏览器就能跑JavaScript。最直接的试验方式新建一个文本文件把后缀改成.html用浏览器打开再在里面写点内容!DOCTYPE html html headtitleJS测试/title/head body h1 idtitle你好/h1 script document.getElementById(title).textContent Hello, JavaScript; /script /body /html保存后用浏览器打开你会看到标题变成了“Hello, JavaScript”。这就是JavaScript在起作用。1.3 浏览器里的JavaScript三大能力入门阶段你只需要记三个方向操作页面DOM操作、监听用户行为事件处理、收发数据Ajax/Fetch。后面的所有知识点基本都是围这三个方向服务的。比如变量是拿来存数据的函数是拿来封装操作逻辑的事件是拿来响应用户点击或输入的字符串和数组是拿来处理数据的。所以学JavaScript不要孤立地背语法每学一个东西都要问自己它跟“操作页面”“响应用户”“处理数据”有什么关系带着这个意识学效率会高很多。2. 变量与数据类型先把东西存起来2.1 声明变量var、let、const怎么选变量就是给数据起个名字。过去JavaScript只有var后来ES6增加了let和const现在新手直接统一用let和const就好了。var的坑在变量提升和作用域太野容易出一些“说不清为什么”的问题。关键字作用域是否可重新赋值是否能重复声明是否存在变量提升var函数作用域可以可以有且初始化值为undefinedlet块级作用域可以不可以有但存在暂时性死区const块级作用域不可以不可以有但存在暂时性死区我一般建议优先用const除非你确定这个值要变才用let。这样能避免很多“不小心改错变量”的问题。比如const userName 张三; let count 0; count count 1; // 可以 userName 李四; // 报错Assignment to constant variable这里的报错不是坏事它是在提醒你这个变量不打算改变你却试图改它说明代码逻辑有问题。2.2 基础数据类型和typeofJavaScript的数据类型在入门阶段你至少得认得这些number数字、string字符串、boolean布尔值、undefined未定义、null空值、object对象、symbol和bigint后面遇到了再说。数组和函数其实是object的一种特殊形式但先不用太纠结。下面是一段很常见的判断类型代码console.log(typeof hello); // string console.log(typeof 123); // number console.log(typeof true); // boolean console.log(typeof undefined); // undefined console.log(typeof null); // object -- 这个很坑 console.log(typeof [1, 2, 3]); // object console.log(typeof function(){}); // function新手最容易记错的是typeof null返回的是object这是JavaScript从诞生就带的老bug官方也没法改怕改坏历史代码。你只要记住判断空值不能只靠typeof就够了。还有一个经典坑0.1 0.2不等于0.3。因为计算机内部用二进制存小数很多十进制小数没法精确表示这是浮点数的通病不是JavaScript独有的。处理金额或需要精确计算时可以避免直接做浮点运算或者用整数的最小单位来算。2.3 命名规范和赋值细节变量命名推荐小驼峰userName、shoppingCart、isLoaded。常量全大写加下划线MAX_COUNT。变量名要能“自解释”不要用a、b、c这种过两周你自己都看不懂。还要注意声明变量但不赋值初始值就是undefined。很多报错“Cannot read property of undefined”根源就是你拿一个未初始化的变量去读内容了。let someVariable; console.log(someVariable); // undefined console.log(someVariable.name); // 报错Cannot read properties of undefined建议在声明时就给一个明确的初始值空字符串、0、空数组都行别留undefined在代码里流通。3. 运算符与类型转换坑都集中在这一块3.1 算术运算符的隐式转换风险JavaScript是弱类型语言但它不是没有类型而是会在运算时悄悄做类型转换。最容易出问题的就是加号。console.log(1 2); // 3 console.log(1 2); // 12 字符串连接 console.log(1 2); // 12 console.log(1 2 3); // 123 从左到右先出字符串就全变字符串 console.log(1 2 3); // 33 先算123再变成33加号只要一边是字符串结果就成了字符串拼接。想确保数字相加可以用Number()、parseInt()或parseFloat()先转成数字或者用一元加号console.log(123); // 123 console.log(Number(123.45)); // 123.45 console.log(parseInt(123abc)); // 123注意它解析到非法字符就停 console.log(parseFloat(3.14hello)); // 3.14新手经常把用户输入当成数字来算像表单里拿到的值都是字符串。比如用户输入年龄比较年龄大小的时候如果你直接比字符串会出现“9大于10”的诡异结果。所以要养成习惯从页面拿到的数据类型先确认一下再决定要不要转类型。3.2 比较运算符永远用而不是和最大的区别是会先做类型转换再比较要求类型和值都相等。新手阶段最好强制自己只用能避开许多莫名其妙的坑。console.log(0 false); // true console.log(0 false); // false console.log( 0); // true console.log( 0); // false console.log(null undefined); // true console.log(null undefined); // false这些的结果靠硬记很容易忘直接用就不用管了。比较数字和字符串时也一样比如const userAge 18; console.log(userAge 18); // false一个字符串一个数字 console.log(Number(userAge) 18); // true拿用户输入做判断时这一步尤其重要。3.3 逻辑运算符的短路逻辑、||、!不只是运算符它们还经常被用来写简短的判断。const isLogin true; const name isLogin 欢迎回来; console.log(name); // 欢迎回来遇到前面的值为假就停下来返回前面的值否则返回后面的值||遇到前面的值为真就停下来返回前面的值否则返回后面的值。很多老代码会用||给参数设置默认值function greet(name) { name name || 陌生人; console.log(你好 name); } greet(李雷); // 你好李雷 greet(); // 你好陌生人现在更推荐用默认参数来写函数章节会讲但理解和逻辑运算符的短路对阅读老代码还是有用的。!则用来取反。连续两个!!可以快速把任意值转成布尔值console.log(!!hello); // true console.log(!!0); // false console.log(!!undefined); // false4. 条件语句与循环让代码有路径4.1 if-else的逻辑顺序程序执行过程里经常要“岔路”if-else就是路标。写的时候最需要注意的是条件的先后顺序。const score 75; if (score 90) { console.log(优秀); } else if (score 60) { console.log(及格); } else { console.log(不及格); }如果先写了score 60再写score 90那90分也会先走score 60的分支。所以优先级高的条件要放在前面。新手常犯的错误就是把分支条件搞反或者每个if都不带else导致默认情况没处理。switch适用于“一个变量精确等于多个值”的场景但比if-else更易读const day 3; switch (day) { case 1: console.log(星期一); break; case 2: console.log(星期二); break; case 3: console.log(星期三); break; default: console.log(未知); }初学者最容易忘写break一旦不写就会继续往下执行其他分支这叫“穿透”。除非你故意想用穿透合并多个case否则每个分支都要加上break。4.2 for循环与数组遍历循环用来处理重复动作。for循环的写法是初始化、条件、更新三步。const fruits [苹果, 橘子, 香蕉]; for (let i 0; i fruits.length; i) { console.log(fruits[i]); }这就是遍历数组的经典写法。i从0开始到小于数组长度结束正好覆盖所有下标。三个位置的分号不能省少一个就语法错误。除了for还有while和do-whilelet count 3; while (count 0) { console.log(count); count--; } let num 5; do { console.log(至少执行一次 num); num--; } while (num 0);do-while在条件为假时也会先执行一次循环体这点和while不同。使用场景不多但面试偶尔会问。4.3 break和continue的妙用break是跳出整个循环continue是跳过当前这一次。比如打印1到5但要跳过3for (let i 1; i 5; i) { if (i 3) { continue; // 跳过本次不打印3 } console.log(i); // 1 2 4 5 }如果要在数组里找第一个满足条件的人找到后就没有必要继续循环了这时用breakconst users [ { name: 张三, age: 20 }, { name: 李四, age: 17 }, { name: 王五, age: 30 } ]; for (let i 0; i users.length; i) { if (users[i].age 18) { console.log(第一个成年人 users[i].name); break; } }循环里嵌套循环会放大执行次数新手经常掉到无限循环里。写while时尤其要注意条件最终要有变化否则浏览器直接卡死甚至要关进程。5. 函数组织代码的最小单位5.1 三种函数写法函数用来把一段逻辑包起来给它起个名字方便重复调用。JavaScript里函数有三种常见写法。// 函数声明 function add(a, b) { return a b; } // 函数表达式 const add2 function(a, b) { return a b; }; // 箭头函数 const add3 (a, b) a b;函数声明会“提升”意思是你可以先调用再声明但函数表达式不行因为const/let声明的变量在赋值之前是undefined。箭头函数是ES6之后的写法它和普通函数最大的区别是this指向不同入门阶段可以先把它当成一种更简短的写法。注意return。函数里如果只有一句return后面的代码不会执行。没有写return则函数返回undefined。5.2 参数默认值和剩余参数调用函数可以传参数。参数过多容易出错可以设置默认值function greeting(name 朋友) { console.log(你好 name); } greeting(); // 你好朋友 greeting(小明); // 你好小明注意默认值只有在参数为undefined时才生效。如果你想传一个空值进去清空某个数据还得另外处理。剩余参数用...把多个参数收进数组function sum(...numbers) { let total 0; for (let num of numbers) { total num; } return total; } console.log(sum(1, 2, 3, 4)); // 105.3 回调函数异步逻辑的地基了解函数紧接着就要了解回调。JavaScript里函数可以作为参数传给另一个函数这就是回调函数。最简单的例子function afterCall(callback) { console.log(开始); callback(); console.log(结束); } function sayHi() { console.log(我说你好); } afterCall(sayHi);输出顺序是“开始 - 我说你好 - 结束”。数组的forEach也是回调的典型使用const list [1, 2, 3]; list.forEach(function(item) { console.log(item * 2); });setTimeout也接受回调setTimeout(function() { console.log(两秒后执行); }, 2000);运行顺序是先往下执行其他代码等2秒后再执行回调函数。这跟“读完代码就从下往上跑”的直觉完全不一样所以理解回调对后面的异步编程很重要。6. 字符串与数组最常处理的两类数据6.1 字符串常用方法几乎所有交互都离不开字符串。入门必须掌握的方法不算多length、indexOf、includes、toUpperCase、toLowerCase、slice、split、replace、trim还有模板字符串。const sentence Hello, JavaScript! ; console.log(sentence.length); // 字符串长度 console.log(sentence.includes(Java)); // true console.log(sentence.trim()); // 去掉两端空格 console.log(sentence.toLowerCase()); // 全小写 console.log(sentence.slice(0, 5)); // 截取前5个字符下标0到4 console.log(sentence.split(,)); // 按逗号拆成数组 console.log(sentence.replace(Hello, Hi)); // 替换第一处匹配模板字符串用反引号可以方便地嵌入变量const name 小红; const message 你好${name}欢迎回来; console.log(message);字符串是不可变的所有返回新字符串的方法都不会改原字符串。如果你想修改必须用变量把他接住。6.2 数组的增删查改数组是JavaScript里最常用的数据容器。先记住这些const arr [1, 2, 3]; arr.push(4); // 尾部添加返回新长度 arr.pop(); // 删除尾部 arr.unshift(0); // 头部添加 arr.shift(); // 删除头部 arr.indexOf(2); // 查找下标 arr.includes(3); // 是否包含 arr.slice(1, 3); // 截取不修改原数组 arr.splice(1, 2); // 从下标1开始删除2个元素会修改原数组高阶方法则更有威力const nums [1, 2, 3, 4, 5]; const doubled nums.map(n n * 2); // [2, 4, 6, 8, 10] const even nums.filter(n n % 2 0); // [2, 4] const found nums.find(n n 3); // 4 const hasBig nums.some(n n 10); // false nums.forEach(n console.log(n));map和filter不会改原数组而是返回一个新数组forEach只遍历不返回。新手经常混淆map和forEach想生成新结果用map只想执行副作用比如打印用forEach。7. 事件处理与DOM入门让页面动起来7.1 事件是什么网页上的点击、输入、滚动、键盘按键都是事件。JavaScript通过监听事件来执行对应逻辑。最常用的写法是addEventListenerconst btn document.querySelector(#btn); btn.addEventListener(click, function() { alert(按钮被点了); });事件监听的好处是允许多个监听器而且可以动态移除。另一种写法是在HTML标签里写οnclickxxx()但项目里一般不建议因为会把行为和结构混在一起。7.2 获取元素和修改样式操作页面的入口是document。document.querySelector可以按CSS选择器获取元素。const title document.querySelector(.title); title.textContent 修改后的标题; title.style.color red; title.style.fontSize 24px;热搜里有个示例是旋转视频元素v document.querySelector(video); v.style.rotate -90deg;。这就是利用style对象给元素设置CSS属性属于入门很常见的操作。注意这里用querySelector、用style.rotate都是标准做法。style属性里设置的是内联样式优先级比较高。除了textContent还有innerHTML。两者区别是textContent只显示纯文本innerHTML会把字符串当成HTML解析。如果内容是用户输入的用innerHTML容易造成XSS跨站脚本攻击。入门阶段可以记住更新文本优先用textContent。7.3 事件冒泡与事件委托当你点击一个元素事件会从最里层向外层传播这叫事件冒泡。利用这个机制可以在父元素上统一监听子元素的事件。const list document.querySelector(#list); list.addEventListener(click, function(e) { const target e.target; if (target.tagName LI) { console.log(你点了 target.textContent); } });这样即使后面动态添加新的li也不用一个个去绑定事件这就是事件委托。新手阶段可以不用太深究但写出这样的代码会显得专业不少。8. 运行时报错与调试先学会读错误信息8.1 区分语法错误和运行时报错JavaScript报错大体分两类。语法错误SyntaxError是代码写错了比如少括号、少分号浏览器直接不执行运行时报错是代码语法没问题但执行过程出现意外比如调用了一个不存在的方法、读取了undefined的属性。常见运行时报错类型错误类型含义示例ReferenceError引用不存在的变量console.log(x) 但x未定义TypeError对不支持的类型做操作对一个undefined调用方法RangeError数值超出有效范围调用栈溢出、数组长度非法SyntaxError语法错误括号不匹配、字符串引号未闭合遇到报错第一反应不是慌而是看浏览器控制台最前面的红色信息。错误信息会告诉你出错在哪个文件第几行点开直接定位代码。8.2 用console和debugger排查问题console.log是最常用的调试方式。你可以打印变量也可以打印多个值const a 1; const b 2; console.log({ a, b }); console.table([{ name: 张三, age: 20 }, { name: 李四, age: 21 }]);打印对象时建议用console.log({ a, b })这样能直接看到变量名和值不然输出一堆数字还得猜是谁。数组用console.table看起来更清晰。如果断点比较复杂直接写debugger语句function calculate(x) { const y x * 2; debugger; // 程序跑到这里会暂停 return y 1; }浏览器开发者工具的Sources面板配合debugger可以逐行看代码执行这是排查复杂逻辑的利器。8.3 入门高频报错的背后逻辑“Cannot read properties of undefined”是新手遇到最多的错误。这个报错的意思是你想读某个对象的属性但这个对象本身是undefined。比如const user { name: 张三 }; console.log(user.address.city); // Uncaught TypeError: Cannot read properties of undefined因为user.address是undefined再读city就不行。解决方案是提前确保每一层都存在或者用可选链console.log(user?.address?.city); // undefined不报错可选链是ES2020新增的遇到null或undefined会直接返回undefined不再继续往下读。另一个常见报错是“xxx is not a function”。一般是你把一个非函数的值当成函数来调用。比如const name 张三; name(); // TypeError: name is not a function排查时看报错前有没有函数名再看这个函数是不是没定义、被赋值成了普通变量或者调用位置搞错了。9. 框架和库是怎么回事9.1 库和框架的区别热搜里有一句“JavaScript框架或库是一组能轻松生成跨浏览器兼容的JavaScript代码的工具和函数”。这句话说得比较绕我翻译一下库就是一组现成函数你调用它们解决特定问题框架则是更大的结构你把自己写的代码放进它规定的框架里让框架帮你在合适的时机调用。举个例子jQuery是库它封装了很多操作DOM和处理事件的函数解决早期浏览器兼容问题。React、Vue是框架它们让你用组件的方式组织界面还要管理数据状态变化。它们都大大提高了开发效率但底层依然是JavaScript本身。9.2 入门阶段要不要学框架我见过太多“零基础直接上Vue”的朋友结果组件传值、响应式数据学了一堆遇到问题还是不会调试因为不知道框架底层到底干了什么。我的建议是至少先花时间把原生JavaScript的基本语法、数组操作、对象、函数、事件这五样练熟再碰框架。怎么检验自己基础够不够试着用原声写一个待办列表能增加、删除、标记完成数据用数组存。如果这个过程中你不查资料能写出来那你就具备了学框架的前提。否则先把基础补一补。框架不是万能的。很多基础的DOM操作、数据校验、通用工具函数框架反而没有原生方便。原生JavaScript是根框架是树枝根不牢的树长不高这是我在实际项目里最深的体会。9.3 给新手的学习顺序建议如果按我平时带人的顺序可以这样走变量和类型 - 运算符 - 条件判断 - 循环 - 函数 - 数组和字符串 - 对象 - DOM操作与事件 - 调试技巧。把这些过一遍之后再去看一个简单框架的入门教程会顺畅很多。学习过程中要多写小例子不要只看不练。每一块语法都可以用一个30行以内的小页面去验证比如写一个按钮点击计数、一个实时显示输入字符长度的小工具。这些都比抄一堆大项目代码有效得多。另外写代码时手机随时打开浏览器控制台多看报错、多改代码。JavaScript入门最大的阻碍不是难度而是“以为自己会了”。只有反复在浏览器里调试才能把知识点变成手感。10. 一些入门阶段的避坑清单最后分享几个我踩过、也看过别人反复踩的坑。第一个坑分号到底加不加。JavaScript的分号是可选不用分号也能跑但某些场景下换行会导致自动分号插入出意外。我自己的习惯是“加上分号”。这样代码更明确也少被工具链问题折腾。第二个坑变量提升让你看不懂老代码。看到var声明的变量在声明之前就拿来用不要觉得奇怪这是提升机制。但现在写新代码用let和const就能避免。第三个坑数组里的空位和稀疏数组。比如const arr [1, , 3]; console.log(arr.length); // 3 arr.forEach(item console.log(item)); // 只会输出1和3空位直接跳过所以遍历数组前最好确认数组元素是否存在别依赖forEach帮你处理空位。第四个坑回调里的this。普通函数里的this指向调用它的对象但回调里this可能变了。箭头函数没有自己的this会保留定义时的this。这也是为什么箭头函数在回调中特别常用。新手如果看到this莫名变成undefined优先考虑是不是函数定义方式的问题。第五个坑死循环导致浏览器卡死。如果看到页面无响应先把循环检查一遍特别是while循环里有没有更新计数器有没有可能在条件上永远满足。调试这些东西时我常用一个“小步走”方法把一段大逻辑拆成几段每段都打印中间结果确认每一步都对了再拼接起来。这样定位问题比对着整段代码猜要快得多。JavaScript入门说难不难说简单也不简单关键在于持续动手。把本文提到的每个知识点在浏览器控制台敲一遍相信你很快就能建立起底层直觉。等你把基础打牢再去看框架源码、学习工程化工具会发现很多原来“看不懂的点”其实都是基础语法的组合。这条路没有捷径但按我说的顺序走至少不会走偏。
返回列表