很多人一听到JavaScript APIs就觉得是另一门语言或者是什么高不可攀的东西尤其看到APIs 第一天这种标题第一反应通常是完了又要背一长串函数名了。其实完全不是这么回事。API全称是Application Programming Interface翻译过来就是应用程序编程接口说人话就是——别人已经把一些功能做好封装成函数或者对象方法你只需要按照约定调用就能拿到你想要的结果。这篇文章就是我给自己也是给刚入门的朋友准备的第一天学习笔记先搞清楚API是什么然后亲手用document、字符串方法、事件处理这几个最常见的API写出能跑的东西最后再聊聊第一天最容易踩的坑。适合刚学完JavaScript变量、函数、循环还没开始碰浏览器API的人。1. 为什么第一天要把API从神坛上拉下来我见过太多人卡在API这个词上。他们学完了var、function、if else觉得自己懂了JavaScript结果一打开教程看到DOM APIFetch APIStorage API就开始犯怵以为API是某种藏在深处的神秘机制。我第一天想做的事情很简单把API这个词拆开揉碎让你发现你其实天天都在用它。1.1 点一份外卖的时间你就懂了API你手机里点外卖的App本质上就是充当一个API客户端。你不需要知道餐厅后厨怎么洗菜、怎么颠勺、用什么火候你只需要在App上按下下单按钮然后平台就把你的订单信息传给餐厅餐厅做好再通过平台把饭菜送到你手上。下单这个按钮就是餐厅对外开放的API你传过去的菜品地址口味偏好就是参数最后送到你手上的饭菜就是返回值。JavaScript里的API也是一模一样的逻辑。以字符串操作来说hello.toUpperCase()就是调用了一个API方法名是toUpperCase你不需要关心它内部是怎么遍历字符、怎么转换大小写的你只要知道它没有参数、返回一个大写字符串就行了。再比如Math.random()这是Math这个平台对外开放的API你调用它它给你返回一个0到1之间的随机数。书写方式虽然跟在手机App上点按钮不一样但本质完全一致调用、传参、拿结果。这里有一个很重要的认知API不是你写出来的哪一行特殊代码它就是一堆现成的函数和方法。你之所以觉得它难是因为你不知道有哪些API以及每个API能干什么。这就像你第一次进一个大型超市货架上几千种商品你不可能全认识但你只要学会看包装说明MDN文档再挑你当前急需的买查API日子就能过下去。1.2 内置API和Web API第一天只要分清这两类打开任何一本JavaScript教材你都会发现API这个词出现在两个完全不同的地方新手很容易混淆。我自己第一天也晕过后来才理清楚类型存在环境典型代表举例内置APIJavaScript语言本身自带String、Array、Math、Date、JSONabc.length、Math.floor(3.6)Web API浏览器额外提供document、element、event、fetch、localStoragedocument.querySelector(#app)、button.addEventListener内置API就像你随身带的工具箱不管在浏览器里还是Node.js里只要JavaScript能跑这些工具就在手边。Web API则是你当前所在场所浏览器给的特殊设施Node.js环境里就没有document因为那儿没有页面给你操作。第一天你不需要把这两类分开背诵只需要在潜意识里埋下一句话如果调用一个方法时报了undefined is not a function先想想这个API到底属于JavaScript自己还是属于浏览器。举个例子alert和prompt属于Web API你在纯Node环境里跑会直接报错而parseInt和isNaN属于内置API在任何JavaScript环境都能用。分清这一点后你再看教程里那些报错信息会少很多莫名其妙的恐慌。2. 从热搜里那条旋转视频代码开始碰document前阵子有个挺有意思的热搜词原句大概是这样javascript:v document.queryselector(video);v.style.rotate -90deg;v.s。这其实是一段写得乱七八糟但意图非常明确的代码选中页面里的视频元素然后把它顺时针旋转90度。虽然里面有个大小写错误但它意外地成了最好的教学素材因为它把DOM API的核心动作演示了一遍。2.1 那段热搜代码完整读一遍并把大小写踩得清清楚楚先别急着复制我们把这段代码拆开看。第一句v document.queryselector(video)这里有两个问题queryselector里的s是小写但真实API叫querySelector字母Q和S必须大写。JavaScript是严格区分大小写的你写queryselector浏览器只会告诉你document.queryselector is not a function。第二句v.style.rotate -90deg这是在修改元素的CSS样式算是一个比较新的属性老浏览器不一定认更通用的写法是v.style.transform rotate(-90deg)。第三句v.s明显是没写完估计想写v.style.xxx或者v.play()。把正确版本补全一下应该是这样const video document.querySelector(video); if (video) { video.style.transform rotate(-90deg); }这段代码的意思是先从当前HTML页面上找到第一个video标签把它存到变量video里然后通过style对象把CSS的transform设置为旋转-90度。如果页面上没有video元素document.querySelector会返回null这时候给video.style赋值就会报错所以要用if (video)做一层保护。这个判断习惯第一天就养成后面能省不少事。2.2 选中、改样式、看效果DOM API的基本三步DOMDocument Object Model是浏览器把HTML结构变成一棵对象树的结果。每个标签都变成一个对象JavaScript通过操作这些对象来改变页面。DOM相关的API第一天只要抓住三条主线怎么选元素、怎么改属性/内容/样式、怎么看效果。选元素最推荐的是document.querySelector(CSS选择器)。它返回第一个匹配的元素。如果想要所有匹配项用document.querySelectorAll(CSS选择器)返回的是一个类数组的NodeList可以配合forEach遍历。刚开始你可能会记不住各种API不用慌你只需要记住一个万能句式document.querySelector(选择器).style.xxx 值; document.querySelector(选择器).textContent 文字; document.querySelector(选择器).setAttribute(属性名, 属性值);举个例子我想让页面上第一个.box背景变红就这样写document.querySelector(.box).style.backgroundColor red;改成页面标题document.querySelector(h1).textContent 第一天学API。如果要给图片换一张可以写document.querySelector(img).src new.png。你会发现这些操作背后都是同一个套路选中对象、调用方法或修改属性、刷新浏览器看结果。2.3 第一天就用querySelector别急着追求性能极限我知道很多老手会推荐getElementById说它性能比querySelector好。这话没错但对第一天的人来说我的建议是放心大胆用querySelector。原因有两个第一它接受CSS选择器你只要会写CSS就会用它不需要额外记忆一套id/class/tag的方法第二现代浏览器对querySelector的优化已经非常好了一个页面选几个元素性能差异根本感知不到。等你以后真的开发大型应用再按需优化也不迟。这里补充一个我第一天就踩过的细节querySelectorAll返回的NodeList虽然是类数组但它不是真正的数组。很多新手直接对它调用push或者map结果报错。第一天你可以先用Array.from把它转成真正的数组或者直接使用forEach遍历。等以后熟练掌握再考虑用展开运算符[...document.querySelectorAll(...)]这种更简洁的写法。3. 把控制台当游乐园字符串和数组API随便试在第一天的学习中我最推荐的学习场所不是什么编程环境而是浏览器自带的控制台。你按下F12Mac上是CmdOptionI切到Console面板就可以开始把JavaScript当玩具玩。控制台的妙处在于你输入一行代码按下回车它立刻返回结果。这种即输即得的反馈比任何教程都来得痛快。3.1 控制台是回报最快的API练习场试一下在控制台里输入 hello world 回车你会看到一个字符串。再输入 HELLO .toLowerCase()你立刻得到小写版本的字符串。这就是API调用最直观的样子数据.方法名(参数)。控制台会自动把返回值打印出来所以你不需要自己写console.log去调试直接就看到了。我第一天就是靠着这种玩法记住了很多API输入[apple, banana].join( and )发现数组能拼成字符串输入Math.random()*10发现能生成随机数输入Number(3.14)发现字符串可以转数字。每试一个你对调用API这件事的肌肉记忆就加深一层。别怕报错在控制台里报错是非常正常的事情它只是告诉你这个API不能这样用换一种写法就好。3.2 字符串API先记住这几个高频动作字符串操作在前端开发里太常见了第一天不需要背所有方法但下面这几个高频动作可以优先掌握// 去空格 hello .trim(); // hello // 判断是否包含某段文字 hello world.includes(world); // true // 替换注意只替换第一个匹配 2024-01-01.replace(-, /); // 2024/01-01 // 按指定字符拆成数组 a-b-c.split(-); // [a, b, c] // 截取片段第二个参数是结束位置但不包含 abcdef.slice(1, 4); // bcd这些方法都是内置API它们的特点是不修改原字符串而是返回一个新字符串。JavaScript里的字符串是原始值不可变所以你要用变量接收返回值赋值之后原来的变量也不会变。第一天理解到这个程度就够了。另一个在实际开发里经常用到的组合是trim split replace。比如用户输入手机号时可能带着空格你先trim()把空格清掉再判断长度或者正则校验。我在第一天就意识到API不像单词不需要背而是需要混个脸熟——当你遇到一个场景脑子自然浮现好像有个方法能处理然后去查MDN几个来回之后你就永远记住了。3.3 数组API第一天认准push、map、filter就够了数组的API比字符串更多新手最容易眼花缭乱。如果你只能先记住三样我建议是push、map、filter因为这三样几乎覆盖了开发中最常见的三种需求往集合里加东西、批量转换、按条件筛选。const numbers [1, 2, 3]; // 尾部追加一个元素返回新数组长度不纯函数会改原数组 numbers.push(4); // 4 // 把每个元素乘以2生成新数组原数组不变 const double numbers.map(n n * 2); // [2, 4, 6, 8] // 只保留大于2的元素生成新数组 const big numbers.filter(n n 2); // [3, 4]注意map和filter都接收一个回调函数作为参数这是很多新手犯晕的地方。所谓回调函数就是你传给API一个小工具API会在内部自动帮你处理每个元素。你可以写成箭头函数n n * 2也可以写普通函数function(n) { return n * 2; }。第一天不需要理解闭包、this这些深水区只要先接受函数也是值可以作为参数传进去这个事实即可。我在实际操作中发现刚接触map的人最喜欢用for循环。不是说for不对而是map和filter写出来更加声明式——你告诉代码你想要的结果而不是一步步教它怎么遍历。第一天可以两种都写一遍体会一下差别后面慢慢就会自然偏好map/filter。4. 事件API让页面从自说自话到听你指令前三节的代码都是页面加载后立刻执行像是一段自顾自念的台词。但真实页面需要和人互动点击按钮、按下键盘、滚动屏幕。这些交互背后就是事件API在起作用。第一天的目标不是把所有事件类型都记住而是把一个入口摸熟addEventListener。4.1 从onclick到addEventListener选择正确的入口很多老教程会教你写button.onclick function() { ... }。这在简单场景下没问题但它有一个明显缺陷同一个元素的同一个事件只能绑定一个处理函数后面的赋值会覆盖前面的。而addEventListener可以叠加多个监听器还支持可选参数控制捕获阶段。所以第一天上手我更建议直接学习addEventListener。用法非常简单const btn document.querySelector(.btn); btn.addEventListener(click, function () { console.log(按钮被点了); });这句话的意思是找到.btn这个按钮然后跟浏览器说当click事件发生时请调用我给的函数。第一个参数是事件类型字符串第二个参数是处理函数。以后你想取消监听就调用removeEventListener但要注意必须先把你命名的函数存下来因为取消时要传同一个函数引用。我在第一天练习的时候特意试过一个按钮绑定两个监听器发现两个函数都会执行。这个特性在真实项目里很有用比如一个组件里一个监听器负责埋点统计另一个负责页面交互两者互不干扰。而如果全用onclick就只能二选一。4.2 事件对象比你想象的更话多事件处理函数可以接收一个参数这个参数是浏览器自动传入的事件对象约定俗成命名为e或event。刚开始很多人不知道怎么用它其实它包含了很多信息。举几个最常见的document.querySelector(.box).addEventListener(click, function (e) { console.log(e.target); // 实际点击的元素 console.log(e.currentTarget); // 绑定监听器的元素 console.log(e.clientX, e.clientY); // 鼠标在视口里的横纵坐标 });这里有些新手会困惑target和currentTarget的区别。我用一个简单比喻currentTarget是你贴在门上那张便利贴监听器所在的元素target是真正按响门铃的那根手指触发事件的元素。如果你在ul上绑定点击事件然后点击里面的某个li此时target是那个licurrentTarget是ul。第一天你能分清这两个后面的什么事件委托、动态列表操作都会轻松很多。事件对象还支持阻止默认行为e.preventDefault()。比如你给表单的提交按钮绑定了点击事件又不想它真的刷新页面就可以调用这个方法。这是我第一天觉得最实用的一个技能因为很多初学Demo里按钮一刷新页面你console打印的调试信息就全没了非常影响心情。4.3 事件冒泡第一天只需要知道一句话事件冒泡是学习事件API时绕不开的概念。简单来说当你点击页面里的一个元素点击事件不仅仅会触发这个元素上的监听器还会一层一层向上触发它的祖先元素上的监听器就像水里冒泡一样。这个特性听起来有点反直觉但它是真实存在的。以这段HTML为例div idouter button idinner点我/button /div你给div#outer和button#inner都绑定click监听器点击按钮时两个监听器都会执行先执行button的再执行div的。第一天你只要知道有这个现象、别到时候一脸懵就好。通常不需要去阻止它但如果确实只想让内层执行可以在内层回调里调用e.stopPropagation()。注意这句话是截断传播事件不会再到祖先元素。我在第一天的练习中遇到一个很有趣的需求点击一个卡片区域希望记录点击的位置但又不想误触发卡片上某个按钮的点击。如果直接绑定在卡片上点击按钮也会冒泡到卡片。那时我第一反应是stopPropagation后来发现更好的办法是判断e.target.tagName ! BUTTON只处理非按钮的点击。这个思路比切断冒泡更可控推荐你也试试。5. 第一天撞上的三个经典报错背后都是同一个习惯学API必然伴随着报错。第一天能遇到三四个典型的报错一点都不奇怪。我自己当年几乎全踩过现在把它们整理出来不是让你背错误信息而是让你记住一个排查习惯先看调用链上每一步是否真的得到了你想要的值。5.1 Cannot read property of null先查选择器有没有选中报错信息大概是这样的Uncaught TypeError: Cannot read properties of null (reading style)。新手看到TypeError就慌其实翻译过来就是你试图访问null的style属性而null表示没找到这个元素。原因通常是document.querySelector的CSS选择器写错了比如拼写错了class名、页面上根本没有这个元素、或者脚本在DOM结构还没渲染完时就执行了。排查方法很简单先把选择器复制到控制台输入document.querySelector(你的选择器)回车看看是不是返回null。如果确实是null检查HTML里有没有对应的class/id/tag。如果HTML有但依然为null检查脚本位置。如果脚本写在head里而元素在body里脚本执行时元素还不存在。最简单的处理是把script标签放在/body之前或者用DOMContentLoaded事件。养成一个习惯在操作元素之前先写一个判断const element document.querySelector(.target); if (element) { element.style.color red; }一旦你习惯这种防御性写法至少能规避一半的空指针报错。5.2 is not a function拼写和大小写是第一杀手另一个高频报错是document.queryselector is not a function或者numbers.pushs is not a function。这种错误十有八九是拼写多一个字母、少一个字母或者大小写不对。JavaScript是严格区分大小写的querySelector和queryselector是两个完全不同的名字。排查不应只盯着报错那一行你要沿着变量名 - 方法名一条链查。比如const v document.querySelector(video); v.style.rotate -90deg;如果报错说v is not a function那很可能是querySelector返回的不是元素而是一个NodeList——哦你可能用了querySelectorAll但忘了加下标。这种错误往往不是方法本身不存在而是你拿到的对象类型和你想象的不一样。控制台里输入变量名回车查看它的实际值是最直接的诊断手段。还有一个容易忽略的地方有些API是存在但非函数。比如你写document.style它不是函数你调用document.style()就会报is not a function。当你看到一个名字看起来像API但调用失败的时候先查它到底是属性还是方法。属性和方法的区别其实就体现在括号上有括号是调用方法没括号是读取属性。5.3 语法错误最扎心括号、引号、分号轮流检查语法错误SyntaxError是所有报错里最不讲情面的。第一天最常见的情况是自己手写代码时括号不配对、字符串引号用错、或者中英文字符混入。比如document.querySelector(.box) // 少了一个括号 document.querySelector(.box).style.color red // 没有分号也能跑但粘贴多行代码时容易出问题这里有个非常实用的技巧把出错的代码从编辑器复制到浏览器控制台运行后再用上箭头调出历史记录逐行检查。另一个技巧是使用带括号高亮的编辑器括号不匹配的时候它通常会变颜色。第一天不要嫌麻烦每次报语法错误多花30秒检查括号引号很快你就会形成条件反射。有个我亲测有效的小习惯给每一条语句结尾都加上分号。虽然现代JavaScript很多情况下可以不加分号但在第一天加大分号能让你在阅读上下多行代码时更容易分辨每条语句的边界。等你以后真正理解了ASI自动分号插入机制再选择要不要省略也不迟。6. 第一天的收尾任务把今天用过的API串联成一个小页面光看不练API永远是别人的。第一天的最后我建议你用今天碰过的API亲手做一个极简交互页面。不用框架、不用构建工具就一个HTML文件打开浏览器就能跑。6.1 做一张点击按钮就变色的卡片需求很简单页面上有一张卡片一开始是浅灰色点击按钮后卡片随机切换背景颜色卡片上方显示当前颜色的值。这里会用到document.querySelector、addEventListener、Math.random、字符串拼接、数组/对象以及style操作。!DOCTYPE html html langzh-CN head meta charsetUTF-8 title第一天API练习/title style .card { width: 260px; height: 140px; border-radius: 12px; background: #eee; display: flex; align-items: center; justify-content: center; font-family: sans-serif; margin: 40px auto; transition: background 0.3s; } /style /head body div classcard idcard点下面按钮换色/div div styletext-align:center button idbtn换一种颜色/button /div script const card document.querySelector(#card); const btn document.querySelector(#btn); function getRandomColor() { const letters 0123456789ABCDEF; let color #; for (let i 0; i 6; i) { color letters[Math.floor(Math.random() * 16)]; } return color; } btn.addEventListener(click, function () { const newColor getRandomColor(); card.style.backgroundColor newColor; card.textContent newColor; }); /script /body /html这段代码里getRandomColor是我们自己定义的函数它不依赖任何库却具备非常明确的输入输出完全可以看成是你的第一个私人API。里面用到的Math.random和Math.floor就是内置APIletters[Math.floor(...)]则是字符串和数组的下标访问——下标访问本身不是方法但它和API配合得非常紧密。保存成HTML文件用浏览器打开点击几次按钮看到卡片变色、文字更新你第一天的目标就达成了。整个过程你已经在不知不觉中用到了querySelector、addEventListener、style、textContent、Math.random、Math.floor而且都是真真正正跑在页面上的效果比单纯的看文档背方法有效十倍。6.2 把重复动作抽成函数你就拥有了第一个私人API上面的代码里我们写了一个getRandomColor函数。这个函数看似简单但它具备了API该有的几个特征有名字、有输入虽然没有参数但可以用参数扩展、有输出返回一个颜色字符串、可以被重复调用。只要你愿意你完全可以给它加一个参数变成getRandomColor(type)传light返回浅色传dark返回深色这个函数就越来越接近一个真正可复用的小工具。我第一天学API时最大的一个顿悟是所谓API不一定是别人提供的你自己也可以写出来。你定义一个函数放到某个作用域里以后别的地方需要用调用它就行。这个自己定义、自己命名、别人未来的你调用的过程让你对接口的理解一下子就从背函数名变成了设计函数名。这种视角转变非常珍贵它让你从API的消费者慢慢变成API的生产者。6.3 明天可以往哪个方向走给出三条路线第一天的任务做完你已经具备了一个最基础的认知框架通过document选中元素通过style和textContent修改页面通过事件让页面响应交互。接下来可以往三个方向继续深入看你自己的兴趣如果对操作页面更有兴趣下一站可以学fetch网络请求用API去请求远程数据然后把数据渲染到页面上。这个方向能让你感受到前后端数据流动最真实的样子。如果对数据组织更有兴趣可以深入学习数组的高阶方法reduce、some、every、find等和对象解构你会发现很多API都是围绕数据结构展开的。如果对交互体验更有兴趣可以研究事件对象更细的用法比如键盘事件、鼠标拖拽、焦点事件以及stopPropagation和preventDefault的边界场景。我到现在都记得第一天做完那个换色按钮时的兴奋感原来我写的代码真的能控制屏幕上的东西。这份成就感比背诵任何文档都更能推着你往下走。最后再分享一个第一天的实用小技巧你不需要记忆所有API的名字但你可以经常在控制台里输入document.注意有个点这时候浏览器会把所有以document开头的方法和属性列出来同理输入hello.、[].、Math.你就能看到不同对象各自能调用的API。用这种自动补全列表当字典比硬背列表高效得多。API是试出来的、看出来的不是背出来的。第一天的目标不是变成API百科全书而是建立遇到问题能用API解决的信心。有了这份信心后面再深入什么概念都不怕。