外观
计算机基础、选择题与趣味题
1. 对以下代码说法正确的是?
js
let arr = [1,2,3,4,5];
let arr2 = [1, , 3];A. 执行 arr.length = 3,此时数组为 [1,2,3] B. 执行 arr[10] = 11,此时 arr.length 为 6 C. 执行 delete arr[2],此时 arr.length 为 4,数组为 [1,2,4,5] D. arr2.length 的长度为 2
答案:
正确答案:A. 执行 arr.length = 3,此时数组为 [1,2,3]。
length 缩短会删除索引大于等于新长度的元素。给 arr[10] 赋值会把长度扩展为 11;delete arr[2] 只留下空位,长度仍为 5;[1, , 3] 有一个稀疏空位,长度是 3。
2. 下列哪些不可以实现浏览器存储数据?
A. cookie B. localStorage C. session D. sessionStorage
答案:
正确答案:C. session。
Cookie、localStorage 与 sessionStorage 都是浏览器提供的持久化或会话级存储机制。session 只是服务端会话这一概念,通常需借助 Cookie 中的 session id 关联服务端数据,本身不是浏览器的存储 API。
3. 下面不可以继承的属性有哪些?
A. font-size B. background C. color D. cursor
答案:
正确答案:B. background。
font-size、color、cursor 默认可由父元素继承;background 默认不继承,子元素背景初始为透明。可用 inherit 强制继承,但那是显式指定后的行为,不改变该属性的默认继承性。
4. 进程、线程、协程分别是什么概念?
答案:
进程是操作系统进行资源分配和隔离的基本单位,拥有独立虚拟地址空间、文件描述符等资源。线程是进程内的执行单元,线程间共享进程资源而各自保留栈和寄存器上下文。协程是用户态协作式调度的轻量执行单元,切换通常无需内核介入;它不能替代多核并行,阻塞调用仍可能阻塞所在线程。
5. 解释性语言和编译型语言有什么区别?
答案:
编译型语言通常先把源代码整体编译为目标码或机器码,再运行,便于做全局优化,部署时需匹配目标平台。解释型语言由解释器在运行时执行源码或字节码,修改和跨平台更灵活。二者并非绝对:JavaScript 的 V8 会 JIT 编译热点代码,Java 也先编译为字节码再由 JVM 执行与优化。
6. V8 里面的 JIT 是什么?
答案:
JIT(Just-In-Time Compilation,即时编译)指 V8 在程序运行中,将频繁执行的 JavaScript 字节码编译为机器码并优化。它依据实际运行时的类型、对象形状等反馈生成快速路径;当假设失效时会去优化并回退到较通用代码。因而 V8 兼具解释启动快与热点代码运行快的特点,但预热和去优化会影响短任务性能。
7. 说说你对计算机网络模型的理解
答案:
网络分层用清晰接口把通信职责拆开。学习中常用五层:应用层定义 HTTP、DNS 等业务协议;传输层以 TCP/UDP 提供进程到进程通信;网络层用 IP 和路由跨网络转发;链路层在相邻节点间传帧、使用 MAC;物理层传送比特信号。实际互联网以 TCP/IP 协议族为主,分层是模型,不是每个实现都严格逐层对应。
8. 说说DOS及DDOS的原理及防御方式
答案:
DoS 是单一或少量来源耗尽目标带宽、连接、CPU 等资源造成拒绝服务;DDoS 由大量受控主机分布式发起,更难按源地址封禁。防御应分层进行:CDN/清洗中心吸收流量,边界限速和 WAF 过滤异常请求,负载均衡与缓存扩容,并做好监控、自动牵引和应急预案。认证不能抵御带宽耗尽,限带宽也可能误伤正常用户。
9. 过桥问题
在一个夜晚,同时有4人需要过一桥,一次最多只能通过两个人,且只有一只手电筒,而且每人的速度不同。A,B,C,D需要时间分别为:1,2,5,10分钟。问:在17分钟内这四个人怎么过桥?
答案:
安排为:A、B 过桥,用 2 分钟;A 返回,用 1 分钟;C、D 过桥,用 10 分钟;B 返回,用 2 分钟;A、B 再过桥,用 2 分钟。总时间为 2+1+10+2+2=17 分钟。关键是让最快两人负责送手电,而让 5 分钟和 10 分钟的人同过,避免最慢者分别过桥。
10. 圆环转圈问题
两个圆环,半径分别是1和2,小圆在大圆内部绕大圆圆周一周,问小圆自身转了几周?如果在大圆的外部,小圆自身转几周呢?
答案:
小圆半径为 1、大圆半径为 2。无滑动滚动时,外侧绕行的自转圈数为 (R+r)/r=(2+1)/1=3 圈;内侧绕行的自转圈数为 (R-r)/r=(2-1)/1=1 圈。多出的或减少的一圈来自小圆圆心绕大圆心转动时,接触法线方向本身发生的旋转;不能只拿大圆周长除小圆周长。
11. 推理问题(二)
赵女士买了一些水果和小食品准备去看望一个朋友,谁知,这些水果和小食品被他的儿子们偷吃了,但她不知道是哪个儿子。为此,赵女士非常生气,就盘问4个儿子谁偷吃了水果和小食品。老大说道:“是老二吃的。”老二说道:“是老四偷吃的。”老三说道:“反正我没有偷吃。”老四说道:“老二在说谎。”这4个儿子中只有一个人说了实话,其他的3个都在撒谎。那么,到底是谁偷吃了这些水果和小食品?
答案:
偷吃的是老三。若老三偷吃,则老大“老二吃的”为假,老二“老四偷吃的”为假,老三“我没有偷吃”为假,老四“老二在说谎”为真,恰好只有一句真话。逐一假设老大、老二或老四偷吃,都会出现真话数量不是一条的矛盾。
12. 最后剩下谁?
1~50 号运动员按顺序排成一排。教练下令:“单数运动员出列!”剩下的运动员重新排队编号。教练又下令:“单数运动员出列!”如此下去,最后只剩下一个人,他是几号运动员?如果教练下的令是“双数运动员出列!”最后剩下的又是谁?
答案:
每轮让当前队列中奇数位置者出列,保留下来的原编号依次是 2、4、6……,所以每轮都把幸存者原编号乘 2。50 人经过 5 轮后只剩 32 号。若每轮让偶数位置者出列,则第一位始终保留,重编号后仍是第一位,因此最后是 1 号。这里的“单数、双数”指每次重新编号后的队列位置。
13. 推理问题(一)
甲、乙、丙三个人在一起做作业,有一道数学题比较难,当他们三个人都把自己的解法说出来以后:
- 甲说:“我做错了。”
- 乙说:“甲做对了。”
- 丙说:“我做错了。”
在一旁的丁看到他们的答案并听了她们的意见后说:“你们三个人中有一个人做对了,有一个人说对了。”
请问,他们三人中到底谁做对了?
答案:
丙做对了。题设要求三人中恰有一人做对、恰有一句话为真。若丙做对,则甲、乙做错:甲“我做错了”为真,乙“甲做对了”和丙“我做错了”均为假,完全符合。其他任一人做对时,三句话的真假数量都无法同时满足题设。
14. 问路问题
- [ ] 有甲、乙两人,其中,甲只说假话,而不说真话;乙则是只说真话,不说假话。
但是,他们两个人在回答别人的问题时,只通过点头与摇头来表示,不讲话。
有一天,一个人面对两条路:A与B,其中一条路是通向京城的,而另一条路是通向一个小村庄的。
这时,他面前站着甲与乙两人,但他不知道此人是甲还是乙,也不知道“点头”是表示“是”还是表示“否”。
现在,他必须问一个问题,才可能断定出哪条路通向京城。那么,这个问题应该怎样问?
答案:
任选一条路,例如 A,问其中一人:
“如果我问另一个人 A 是否通向京城,他会点头吗?”
把得到的动作反过来解释:对方点头则 A 不是京城,摇头则 A 是京城。内层回答会因说真话或说假话产生一次反转,外层由被问者再反转一次,所以两次反转抵消;点头和摇头的语义未知也不影响结论。
15. 囚犯抓绿豆问题
五个囚犯先后从100颗绿豆中抓绿豆。抓得最多和最少的人将被处死,不能交流,可以摸出剩下绿豆的数量,谁的存活几率最大?
提示:
- 1、他们都是很聪明的人;
- 2、他们的原则是先求保命,再去多杀人;
- 3、100颗不必都分完,但要保证每人至少抓一颗;
- 4、若有重复的情况,则也算最大和最小,一并处死。
答案:
5 号囚犯存活概率最大。前四人都以先保命为目标并可摸清余量:1 号先抓 1 颗以避免成为最大值,后续人会据已有数量选择既不与极值重复、又尽量让别人落入极值的数量。到 5 号时可观察前四人的精确分配和剩余豆数,再从可选数量中避开当前最小值、最大值及其相邻风险,选择安全数。该题依赖完全理性、顺序抓取和可感知余量的前提。
16. 连续自然数之和为1000的共有几组?(m,n都为自然数,单独1个数也算作“连续自然数”)
答案:
共有 4 组:1000、199+200+201+202+203、28+29+…+52、45+46+…+55。设连续正整数从 a 开始、长度为 k,则 1000=k(2a+k-1)/2,所以 2a=2000/k-k+1 必须为正偶数。枚举 2000 的因子可得 k=1、5、11、25,对应上述四组;长度超过 44 时首项已不为正。
17. 猴子搬香蕉问题
一个小猴子有100根香蕉,它要走过50米才能到家,每次它最多搬50根香蕉,而且每走1米就要吃掉一根香蕉,请问它最多能把多少根香蕉搬到家里?
答案:
最多能带回 16 根。前 16 米需要把 100 根分两趟向前搬:两次前进和一次返回共消耗每米 3 根,剩 52 根。再走 1 米消耗 3 根,恰好剩 49 根,之后只需一趟搬运;余下 33 米再消耗 33 根,到家为 16 根。核心是在香蕉超过 50 根前,必须往返补运,不能把 100 根一次带走。
18. 修改水果框标签问题
有三框水果,有一筐全是苹果,一筐全是橘子,还有一筐是两种水果的混合。
三框都分别标记了“苹果”“橘子”“混合”,但是标签全是错的,即标签是什么里面就一定不是那框水果。
你的任务是如何只把手伸进一个框子中,只拿出一个水果,然后准确的把三框水果的标签改正确。
答案:
从标有“混合”的箱子取一个水果。因三个标签全错,这个箱子不可能混合,只会是苹果或橘子;取出苹果就把它改标“苹果”,取出橘子同理。随后,原本标该单一水果的箱子不能是该水果,也不能是已确定的一类,只能标“混合”;最后一个箱子自然是另一种单一水果。
19. 盲人分袜子
有两位盲人,他们都各自买了两对黑袜和两对白袜,八对袜子的布质、大小完全相同,而每对袜子都有一张商标纸连着。两位盲人不小心将八对袜子混在一起。他们每人怎样才能取回黑袜和白袜各两对呢?
答案:
把每一对袜子的商标纸拆开,将这一对中的两只袜子分别交给两人。每一对原本同色,因此两人从每对各得到一只;总共四对黑袜和四对白袜时,两人必然各有两只黑袜、两只白袜,正好组成黑白各两对。无需辨别颜色,商标纸只用于识别原先配对的两只袜子。
20. 拿苹果问题
桌上有100个苹果,你和另一个人一起拿,一人一次,每次拿的数量大于等于1小于等于5,问:如何拿能保证最后一个苹果由你来拿?
答案:
你应先拿 4 个,之后每次拿 6-对方所拿数量 个。例如对方拿 2 个,你拿 4 个。这样每一轮两人合计拿 6 个,你会依次拿到第 4、10、16……、100 个苹果,保证最后一个由你拿。前提是每次允许拿 1 至 5 个且你先手;若对方先手或总数改变,目标余数也要相应调整。
21. 握手问题
有5对夫妇举行家庭聚会。每一个人都可能和其他人握手,但夫妇之间绝对不握手。
聚会结束时,A先生问大家握手几次,结果是每个人的握手次数都不相同,那么请问A先生的太太握手几次?
答案:
A 先生的太太握了 4 次手。A 问了其余九人,答案互不相同,只能是 0 到 8。握 8 次的人必与握 0 次的人是夫妻;去掉这对后,握 7 次与握 1 次者配对,如此递推得到 6 与 2、5 与 3。剩下的唯一次数 4 对应的就是 A 的太太。该推理利用夫妻之间不握手且每人至多握 8 次。
22. 盲人翻牌
给一个盲人52张扑克牌,并告诉他里面恰好有10张牌是正面朝上的。要求这个瞎子把牌分成两堆,使得每堆牌里正面朝上的牌的张数一样多。瞎子应该怎么做?
答案:
任取 10 张牌作为第一堆,将这 10 张全部翻面,剩余 42 张为第二堆。设第一堆原有 x 张正面,则第二堆有 10-x 张正面;翻转第一堆后,其中正面数变为 10-x,两堆相等。做法不需要知道每张牌朝向,只依赖总正面数恰好为 10。
23. 一百个囚犯和一盏灯
国王招来100个囚犯,对他们说:你们犯的是死罪,但我给你们一次求生的机会。15分钟以后,你们将被关进一个有100间隔离牢房的监狱里,每人一间牢房,都与外界隔绝,什么也听不见看不到,连时间都没法计算,无法获得外界的任何信息。
这所监狱有一个院子,每天只少随机(注意是完全随机)打开一间牢房的门,让一个囚犯到院子里来放风。院子里有一盏灯,放风的囚犯可以控制它的开关,将它打开或是关闭。除囚犯之外,其他人都不会去碰开关。这盏灯会永远有充足的能源供应,灯泡和电路不会出故障。
除了开关这盏灯,放风的囚犯放风时留下的任何其它痕迹都会在夜晚被清除干净(包括在灯上作的任何记号)。牢房是完全封闭的,院子里的灯光在牢房里看不到。只有放风到院子里的人才能看到。
国王:好了现在我向你们提出一个要求,只要你们做到了,就可以全部获得释放:
给你们15分钟商量你们的方案。15分钟以后,你们将被关进我刚才说的那个监狱,永远无法再交流,被关若干天后,你们中间如果任何一个人能够向我证明你们每个人都至少放风了一次,我就把你们放了,不然永远别想再出来。
如果你们有谁现在可以告诉我这个方法,也就是能够证明你们每人至少放风一次的方法,我就放掉你们!
其中一个囚犯想了几分钟,回答了这个问题,国王听后,如自己所说的把他们全部给放了。请问那个囚犯是用什么方法证明的?
答案:
先约定一名计数员,其余 99 人各只允许在自己第一次进院且灯灭时把灯打开一次;计数员见灯亮就关灯并计数一次。计数员数到 99 后即可宣布所有囚犯都至少来过。为消除灯初始状态未知的影响,可指定一名普通囚犯允许开灯两次、计数员数到 100;随机选择只保证最终概率为 1,不保证有限天数内一定完成。
24. 在点击p标签时,会输出什么?
html
<div onclick="console.log('div')">
<p onclick="console.log('p')">
Click here!
</p>
</div>A. p div B. div p C. p D. div
答案:
正确答案:A. p div。
点击目标 p 时,p 的内联 onclick 先在目标阶段执行,输出 p;随后事件默认冒泡到父元素 div,输出 div。若在 p 的处理函数中调用 stopPropagation(),父元素不会输出;使用捕获监听则执行顺序会不同。
25. 在点击 button 时,触发的 event.target 是哪个?
html
<div onclick="console.log('first div')">
<div onclick="console.log('second div')">
<button onclick="console.log('button')">
Click!
</button>
</div>
</div>A. 最外层div B. 第二层的div C. button D. 上面三个元素
答案:
正确答案:C. button。
event.target 始终是最初触发事件的元素,因此点击按钮时,无论事件冒泡到第二层或最外层 div,各处理函数看到的 event.target 都是该 button。与之对应,event.currentTarget 是当前正在执行监听器的元素,会随传播阶段变为相应的 div。
26. app中常提到的webview是什么?
答案:
WebView 是原生 App 内嵌的网页渲染组件,通常基于系统浏览器内核,用来加载线上页面或本地 HTML/CSS/JS。它没有完整浏览器的地址栏等外壳,但可提供历史、缓存、脚本执行和导航能力。原生与 WebView 通常通过 JavaScript bridge 双向通信;需限制可访问域名、校验消息来源,并防范不可信页面注入和 Cookie 泄露。
27. 原码、反码和补码分别是什么?
答案:
以 8 位有符号整数为例,原码最高位为符号位,其余位表示绝对值,-7 为 10000111。反码中正数不变,负数符号位不变、数值位取反,-7 为 11111000。补码中正数不变,负数反码加 1,-7 为 11111001。现代计算机普遍用补码,因为加减可统一为加法且只有一个零;8 位补码范围是 -128 到 127。
28. Unicode 和 UTF-8 之间有什么关系?
答案:
Unicode 是字符集与码位标准:它为字符分配码点,如 中 是 U+4E2D,但不规定字节如何存储。UTF-8 是 Unicode 的一种编码方案,将码点编码成 1 至 4 个字节,ASCII 与其完全兼容;常用汉字通常占 3 字节,补充平面字符占 4 字节。UTF-8 不是压缩算法,长度取决于码点范围;UTF-16、UTF-32 也是 Unicode 编码方式。
29. 说说你对操作系统的理解?核心概念有哪些?
答案:
操作系统是位于应用与硬件之间的资源管理和抽象层,内核通过系统调用向程序提供统一接口。核心包括:进程/线程调度与同步,虚拟内存和地址空间,文件系统与存储,设备驱动和 I/O,中断与权限隔离,以及网络和进程间通信。它的目标是在安全隔离、资源公平和性能之间权衡;Shell、GUI 属于用户交互层,不等同于内核。
30. 使用cookie、session维持登录状态的原理是什么?
答案:
HTTP 本身无状态。登录成功后,服务端创建会话并保存用户信息,以 Set-Cookie 将随机 session id 发给浏览器;后续同站请求自动携带 Cookie,服务端据 id 查找会话,从而识别登录用户。Cookie 也可直接承载签名令牌,但不能放敏感明文。应设置 HttpOnly、Secure、SameSite、过期和轮换策略,并防范 XSS、CSRF 与会话固定攻击。
31. 什么是内存泄漏?
答案:
内存泄漏是对象或已分配内存已无业务用途,却仍被引用或未被释放,导致运行期间可用内存持续减少。C/C++ 常因漏掉 free/delete 发生;JavaScript 也会因全局引用、未清除定时器或事件监听器、闭包持有大对象等使 GC 无法回收。它不等于瞬时内存高:应结合堆快照、引用链和长期趋势定位,并在生命周期结束时解除引用与清理资源。
32. 64匹马,8个赛道,找出最快的4匹马,要比赛多少轮?
答案:
最多需要 11 轮。先将 64 匹分 8 组比赛,需 8 轮;8 组第一名再赛第 9 轮,按结果将组重命名为 A 至 H。前四名只可能在 A、B、C、D 组的前四名中,且 A1 已确定最快。其余候选为 A2-A4、B1-B3、C1-C2、D1,共 9 匹;先赛其中 8 匹,第 10 轮,必要时再让其前三与 A3 赛第 11 轮,即可确定余下前三。
33. 什么是空间复杂度?
答案:
空间复杂度衡量算法运行时额外占用的存储空间随输入规模 n 的增长关系,通常用 Big-O 表示,并忽略常数和低阶项。原地交换等只需固定变量,辅助空间为 O(1);创建长度为 n 的数组是 O(n)。递归还要计入调用栈:每层 O(1)、深度 n 时通常为 O(n)。输入本身是否计入需按题目约定说明。
34. 介绍你知道的一些数据结构
答案:
常见结构包括:数组,连续存储,按下标随机访问 O(1);链表,节点通过指针连接,已知节点插删 O(1);栈,后进先出;队列,先进先出;哈希表,平均查找、插入、删除 O(1),需处理冲突;树用于层级数据,平衡搜索树查找约 O(log n);堆适合优先队列;图表示多对多关系。实际选择取决于读写、排序和内存需求。
35. 砝码称重问题(三)
现在有质量分别为1g、2g、3g、4g、8g的砝码各一枚.用这些砝码在天平上共可称出多少种不同的质量?
答案:
可称出 18 种,即 1g 到 18g 的每个整数。砝码总重为 1+2+3+4+8=18,并且已有 1、2、3、4 可连续表示 1~10;加入 8g 后可得到 8~18,与前段衔接,因此没有缺口。例如 17g=8+4+3+2,18g 为全部砝码之和。这里默认物体和砝码只放在天平两侧中的规定一侧,不利用砝码相减。
36. 砝码称重问题(二)
假设有280g食盐,有一架天平,有两个砝码,分别是14g、4g。
请问能否在3次内将280g食盐分为100g和180g两堆,请详细描述你的解决方法。
答案:
能,三次即可。
- 用 14g 砝码称出 14g 盐,余下 266g。
- 将 266g 盐分置两盘,在一侧放 14g 和 4g 砝码,平衡时两份盐分别为 128g、138g。
- 从 128g 盐中取一部分与 14g 盐、14g 砝码同盘,另一盘放 28g 盐;平衡时取出的盐为 28g,128g 余下 100g。
于是 14+28+138=180g,另一堆为 100g。
37. 砝码称重问题(一)
如何制造个数最少的单位砝码,如 1g,2g,3g,4g……,使得这些单位砝码能称出1g到100g之间的任何整数克的物体?
答案:
要分情况。若砝码只能放在物体对侧,最少 7 个:1、2、4、8、16、32、64g;二进制表示可覆盖 1~127g,且 2^6<100,所以少于 7 个不可能。若允许天平两侧都放砝码,最少 5 个:1、3、9、27、81g。每个砝码可取左、右、不放三种状态,平衡三进制可表示 1~(3^5-1)/2=121g,足以覆盖 1~100g。
38. 进程间有哪些通信方式?
答案:
常见进程间通信(IPC)有:匿名/命名管道,适合亲缘或本机字节流;消息队列,按消息传递并可异步消费;共享内存,吞吐高但必须配合互斥锁、信号量等同步;信号,用于简单异步通知;套接字,支持本机及跨网络通信;也可使用内存映射文件。选择时要权衡通信边界、序列化成本、同步和故障隔离。
39. 进程与线程有什么区别?
答案:
进程是资源隔离与保护的基本单位,拥有独立虚拟地址空间、文件描述符等;线程是进程内的执行流和 CPU 调度单位。同一进程的线程共享代码、堆和全局资源,但各自有栈、寄存器上下文和程序计数器。进程切换与通信成本通常更高但隔离更强;线程切换较轻,却需用锁、原子操作等避免共享数据竞争。一个进程至少有一个线程。
40. 绳子计时问题
有若干根相同的不均匀的绳子,烧完一根绳子的时间是1小时,问如何计时1小时15分钟?
答案:
用三根绳子。时刻 0:第一根两端同时点燃,第二、三根各点燃一端。30 分钟后第一根烧完,点燃第二根另一端;第二根已烧了半小时,剩余部分两端烧,会在 45 分钟时烧完。此时点燃第三根另一端;它已单端烧 45 分钟,剩余部分两端烧,15 分钟后烧完。总计 75 分钟。绳子燃速不均不影响“两端燃烧使剩余时间减半”。
41. 高楼逃生问题
如果你被困在一幢200米高的大楼的楼顶,手里有一根150米长的绳子和一把瑞士军刀。你所站的地方有一个铁钩子。往楼下看时,你发现大楼正中间,也就是100米高的位置上,有一个可以落脚的金属支架,上面还有另外一个钩子,问用现在的工具如何安全到达地面?
答案:
将 150m 绳切成 50m 和 100m。把 50m 段固定在楼顶钩子上,并在末端做一个小环;将 100m 段穿过小环、两端系成闭环。借此下降到 100m 处的支架,利用支架钩子固定或承重后,将 100m 绳从小环中抽回。再把 100m 绳的一端系在支架钩子上,沿绳下降 100m 至地面。关键是小环只作可回收的临时支点。
42. 计算聚会人数
一次朋友聚会,大家见面时总共握手45次。如果参加聚会的人和其余的每个人只握手一次,问参加聚会的共有多少人?
答案:
共有 10 人。n 人两两握手一次的次数为组合数 C(n,2)=n(n-1)/2。令 n(n-1)/2=45,得到 n^2-n-90=0,解得 n=10 或 -9;人数只能取正整数,因此为 10。该结论依赖每一对不同的人恰好握手一次,且不计与自己握手。
43. 药丸难题
医生给了病人两种药丸,每种两颗,两种药丸的成分不同,但外观一样,医生要求早上和晚上,每种药各吃一颗。现在药丸被混在了一起,难以分辨。如果病人没按照规定吃药或者不吃药,就会死亡。请问他要怎么做才能活下来?
答案:
把四颗药丸分别切成等重两半。早上从每颗药丸各取一半服下,晚上服用剩下的四半。无论哪两颗属于同一种药,每次服用都包含两种药各一整颗的剂量:同类的两半合为一颗。前提是每颗药的有效成分均匀分布,且切分和服用不会造成剂量损失;现实用药应遵医嘱,不能自行套用谜题方法。
44. 沙漠尸体
一个人被发现死在沙漠里,手中捏着一根火柴,周围没有任何足迹,也没有其他线索。他是怎么死的呢?
答案:
这是横向思维题:他从飞机上坠落而死。飞机因超载等事故必须有人离开,乘客用抽火柴决定人选;他抽到最短的一根,因此手里还握着火柴。沙地没有足迹是因为他不是步行到那里。题干并不足以唯一推出这一故事,它依赖常见谜题设定,而非严格的刑侦结论。
45. 球的重量
有8个球,其中1个比另外的要略重。在不用砝码的前提下,你最少要称几次,才能找出这个球?
答案:
最少 2 次。第一次把 8 个球分为 3、3、2,称两组 3 个:若一边重,重球在那 3 个中;第二次从中取 2 个称,较重者即答案,若相等则第三个较重。若第一次相等,重球在余下 2 个中,第二次直接称出较重者。一次称量只有三种结果,无法区分 8 种可能;两次最多区分 3^2=9 种。
46. 干脆面抽卡问题
假设小浣熊随机赠送的卡片共有 108 种(出现概率相同),那么集齐所有卡片所需购买小浣熊包数的数学期望是多少?
答案:
期望购买数为 108H_108,其中 H_108=1+1/2+...+1/108,数值约为 570.96 包,通常说约 571 包。已收集 k 种后,抽到新卡的概率是 (108-k)/108,等待下一张新卡的期望为 108/(108-k);把 k=0~107 的等待期望相加即得该式。519 不是此题的正确期望。
47. 海盗博弈问题
有五个理性的海盗(不妨以 A-E 命名)找到了100个金币,需要想办法分配金币。
而他们的分配原则是:海盗们从 A 到 E 依次提出一种分配方案。所有还活着的海盗投票决定是否接受这个提案,包括提议人。必须要多于半数的人投赞成票,提案才通过,此时按照提议分配金币。如果没有通过,那么提议人将被扔出船外,由下一个海盗提出新的分配方案。
现在假设海盗们都极其聪明,他们的首要目标是存活并且尽可能获得更多的金币。在此基础之上,他们也倾向于杀死更多的人。请问他们的最终结果是怎样的呢?
答案:
按“必须严格过半、同金币数时优先让更多人出局”的规则逆推:
- 2 人:D 会被否决,E 得 100。
- 3 人:C 需 2 票,给 D 0 即可,得 (100,0,0)。
- 4 人:B 需 3 票,收买 D、E 各 1,得 (98,0,1,1)。
- 5 人:A 需 3 票,C 在下一轮得 0,给 C 1;D、E 下一轮各得 1,给其中一人 2。
故可为 (A,B,C,D,E)=(97,0,1,2,0),D/E 可互换。
48. 白帽子问题
在一个房间里有100个学生。每个人头上都戴了一顶帽子,帽子的颜色是白色或者黑色。每个学生都只能看见别人的帽子的颜色,而不能看到自己帽子的颜色。
老师对所有人说:“你们每个人要么戴白帽子,要么戴黑帽子,并且有人戴白帽子,请戴白帽子的同学举手。” 如果没人举手,老师一分钟后再问:“请戴白帽子的同学举手。” 然后老师每个一分钟后重复同样的问题,直到所有戴白帽子的学生都举手为止。
假设每个学生都极其聪明,100个学生中只有5个人戴了白帽子。请问,什么时候戴白帽子的学生会全部举手?
答案:
第 5 分钟,5 名白帽学生会同时举手。归纳看:若仅 1 顶白帽,该生看不到白帽,听到“至少一顶白帽”后第一分钟即可确定自己是白帽;若有 k 顶,每名白帽都看到 k-1 顶,并会等待前 k-1 分钟。前面无人举手便排除较少白帽的情形,于第 k 分钟共同推出自己也是白帽。黑帽者始终不能确定自己颜色。
49. 圆桌射击游戏
圆桌上有1到1000号,1号右手边是2号,左手边是1000号。1号开枪打死2号,把枪交给3号,3号打死4号交给5号。如此继续下去,999号打死1000号后把枪交给1号,之后继续循环。请问最后留下来的是几号?
答案:
最后留下 977 号。这是约瑟夫环问题(每次淘汰当前持枪者右侧的人),零基递推为 J(1)=0,J(n)=(J(n-1)+2) mod n。代入 n=1000 得 J(1000)=976,换回题目的 1 基编号即 977。也可利用最大不超过 1000 的 2 的幂 512,答案为 2(1000-512)+1=977。
50. 小白鼠试毒问题进阶
有16瓶水,其中只有一瓶水有毒,小白鼠喝一滴之后一小时会死。 请问最少用多少只小白鼠,在1小时内一定可以找出至少14瓶无毒的水?
答案:
最少 3 只。把 16 瓶两两分成 8 组,给组编号 000~111;三只鼠分别喝所有编号对应位为 1 的组中混合的一滴。1 小时后,死亡组合正好给出有毒的那一组;即使不能区分组内哪瓶,也已能确定另外 7 组共 14 瓶无毒。两只鼠只有 4 种结果,不能覆盖 8 组,故 3 只是下界且可达。
51. 小白鼠试毒问题
现在有 1000 瓶药水,其中有 1 瓶毒药,毒药药性发作致死时间为 1 小时。现在有 1 个小时的时间找出毒药,那么至少需要多少只小白鼠来试毒?假设药水量无限,可以无限稀释,喝药时间不计。
答案:
至少 10 只。每只鼠在一小时后只有死、活两种结果,m 只鼠最多区分 2^m 瓶;2^9=512<1000,2^10=1024,因此至少 10 只。给每瓶编 0~999 的 10 位二进制号,第 i 只鼠喝所有第 i 位为 1 的瓶子混合样本。一小时后,将死亡鼠记为 1、存活记为 0,得到的二进制编号就是毒药瓶。
52. 汽车所停车位的编号是多少?

答案:
停车位编号是 87。将图案整体旋转 180 度后,连续数字会读作 86、87、88、89、90、91;被车遮住的位置正是 87。这个题利用的是视觉方向转换,不能按原图从左到右直接把字符当作正常数字读取。
53. 怎么用3升和5升的桶量出4升的水?
答案:
步骤如下:
- 装满 3L 桶倒入 5L 桶,5L 桶有 3L。
- 再装满 3L 桶,向 5L 桶倒至满;3L 桶剩 1L。
- 倒空 5L 桶,把这 1L 倒入 5L 桶。
- 再装满 3L 桶并倒入 5L 桶。
此时 5L 桶中为 4L。本质是容量差 5-3=2 可生成余数,且两桶容量互质,所以可量出任意 1L 的整数倍。
54. 输出什么?
javascript
// 🎉✨ This is my 100th question! ✨🎉
const output = `${[] && 'Im'}possible!
You should${'' && `n't`} see a therapist after so much JavaScript lol`A. possible! You should see a therapist after so much JavaScript lol B. Impossible! You should see a therapist after so much JavaScript lol C. possible! You shouldn't see a therapist after so much JavaScript lol D. Impossible! You shouldn't see a therapist after so much JavaScript lol
答案:
正确选项:B. Impossible! You should see a therapist after so much JavaScript lol。
[] 是真值,[] && 'Im' 返回 'Im',因此模板字符串开头为 Impossible!。空字符串 '' 是假值,'' && n't`` 返回 '',不会插入 n't。注意代码只是创建 output 常量,并未 console.log;选项表达的是该变量的字符串值。
55. 输出什么?
javascript
const name = "Lydia"
console.log(name())A. SyntaxError B. ReferenceError C. TypeError D. undefined
答案:
正确选项:C. TypeError。
name 已声明且值为字符串 "Lydia",执行 name() 是把非函数值当函数调用。变量存在,故不是 ReferenceError;代码语法也合法,故不是 SyntaxError。运行时会抛出类似 TypeError: name is not a function,因此后续没有正常输出。
56. 输出什么?
javascript
const getList = ([x, ...y]) => [x, y]
const getUser = user => ({ name: user.name, age: user.age })
const list = [1, 2, 3, 4]
const user = { name: "Lydia", age: 21 }
console.log(getList(list))
console.log(getUser(user))A. [1, [2, 3, 4]] 、 undefined B. [1, [2, 3, 4]] 、 { name: "Lydia", age: 21 } C. [1, 2, 3, 4] 、 { name: "Lydia", age: 21 } D. Error 、 { name: "Lydia", age: 21 }
答案:
正确选项:B. [1, [2, 3, 4]] 、 { name: "Lydia", age: 21 }。
参数 [x, ...y] 解构 list,得到 x=1、y=[2,3,4],返回 [1,[2,3,4]]。getUser 的对象字面量被圆括号包住,箭头函数会隐式返回该对象。若省略圆括号,花括号会被解析为函数体而不是返回对象。
57. 输出什么?
javascript
const info = {
[Symbol('a')]: 'b'
}
console.log(info)
console.log(Object.keys(info))A. {Symbol('a'): 'b'} and ["{Symbol('a')"] B. {} and [] C. { a: "b" } and ["a"] D. {Symbol('a'): 'b'} and []
答案:
正确选项:D. {Symbol('a'): 'b'} and []。
对象确实拥有一个 Symbol 键属性,所以控制台检查对象时通常会显示该属性。Object.keys 只返回自身的、键为字符串且可枚举的属性,不包含 Symbol 键,因此结果为 []。需要获取 Symbol 键应调用 Object.getOwnPropertySymbols(info),而不是把 Symbol 当作字符串键。
58. 输出什么?
javascript
class Person {
constructor() {
this.name = "Lydia"
}
}
Person = class AnotherPerson {
constructor() {
this.name = "Sarah"
}
}
const member = new Person()
console.log(member.name)A. "Lydia" B. "Sarah" C. Error: cannot redeclare Person D. SyntaxError
答案:
正确选项:B. "Sarah"。
类声明创建的外层 Person 绑定可被重新赋值;随后它指向 AnotherPerson 这个类构造器。new Person() 实际执行新类的构造函数,给实例写入 name = 'Sarah',故打印 Sarah。AnotherPerson 是类表达式的内部名称,不影响通过 Person 变量构造实例。
59. 输出是什么?
javascript
function nums(a, b) {
if
(a > b)
console.log('a is bigger')
else
console.log('b is bigger')
return
a + b
}
console.log(nums(4, 2))
console.log(nums(1, 2))A. a is bigger, 6 and b is bigger, 3 B. a is bigger, undefined and b is bigger, undefined C. undefined and undefined D. SyntaxError
答案:
正确选项:B. a is bigger, undefined and b is bigger, undefined。
两次调用分别先打印 a is bigger、b is bigger。return 后立即换行触发自动分号插入,等价于 return;;下一行 a + b 不可达。因此两个 nums 调用均返回 undefined,外层 console.log 随后打印它。if 与条件之间换行不影响语法。
60. 输出什么?
javascript
function getItems(fruitList, ...args, favoriteFruit) {
return [...fruitList, ...args, favoriteFruit]
}
getItems(["banana", "apple"], "pear", "orange")A. ["banana", "apple", "pear", "orange"] B. [["banana", "apple"], "pear", "orange"] C. ["banana", "apple", ["pear"], "orange"] D. SyntaxError
答案:
正确选项:D. SyntaxError。
剩余参数 ...args 必须是形参列表的最后一个参数,因为它负责收集后续全部实参。这里后面还有 favoriteFruit,函数声明阶段就违反语法,程序无法执行到调用或返回数组。将签名改为 function getItems(fruitList, favoriteFruit, ...args) 才是合法写法。
61. 输出什么?
javascript
const person = {
name: "Lydia",
age: 21
}
for (const [x, y] of Object.entries(person)) {
console.log(x, y)
}A. name Lydia and age 21 B. ["name", "Lydia"] and ["age", 21] C. ["name", "age"] and undefined D. Error
答案:
正确选项:A. name Lydia and age 21。
Object.entries(person) 产生 [['name','Lydia'], ['age',21]]。for...of 每轮取得一个键值对子数组,const [x,y] 再将其解构为键和值,所以依次执行 console.log('name', 'Lydia') 和 console.log('age', 21)。输出的具体排版由控制台决定,值的顺序不变。
62. 输出什么?
javascript
function giveLydiaPizza() {
return "Here is pizza!"
}
const giveLydiaChocolate = () => "Here's chocolate... now go hit the gym already."
console.log(giveLydiaPizza.prototype)
console.log(giveLydiaChocolate.prototype)A. { constructor: ...} { constructor: ...} B. {} { constructor: ...} C. { constructor: ...} {} D. { constructor: ...} undefined
答案:
正确选项:D. { constructor: ...} undefined。
普通函数可作为构造函数,默认有 prototype 对象,其中包含指向该函数的 constructor 属性。箭头函数没有 [[Construct]] 能力,不能用 new 调用,也不会创建自己的 prototype 属性;读取 giveLydiaChocolate.prototype 因而得到 undefined。控制台展示普通函数原型的细节可能略有差异。
63. 输出什么?
javascript
let newList = [1, 2, 3].push(4)
console.log(newList.push(5))A. [1, 2, 3, 4, 5] B. [1, 2, 3, 5] C. [1, 2, 3, 4] D. Error
答案:
正确选项:D. Error。
Array.prototype.push 会修改原数组,但返回修改后的长度。[1,2,3].push(4) 的结果是数值 4,所以 newList 不是数组。继续访问 newList.push 得到 undefined,再调用它会抛出 TypeError: newList.push is not a function,不会输出一个数组。
64. 下面的输出是什么?
javascript
for (let i = 1; i < 5; i++) {
if (i === 3) continue
console.log(i)
}A. 1 2 B. 1 2 3 C. 1 2 4 D. 1 3 4
答案:
正确选项:C. 1 2 4。
循环依次处理 1、2、3、4。i===3 时执行 continue,立即跳过本轮余下语句并进入更新表达式 i++,所以不会打印 3;其他三次都会执行 console.log(i)。continue 不会结束整个循环,若要直接结束应使用 break。
65. 输出是什么?
javascript
const obj = { a: 'one', b: 'two', a: 'three' }
console.log(obj)A. { a: "one", b: "two" } B. { b: "two", a: "three" } C. { a: "three", b: "two" } D. SyntaxError
答案:
正确选项:C. { a: "three", b: "two" }。对象字面量中同名的非计算属性允许重复,后面的 a: 'three' 会覆盖此前 a 的值,因此最终值为 three。属性的位置仍按首次创建时的顺序保留,所以打印顺序是 a、b;这不是语法错误。
66. 输出是什么?
javascript
const obj = { 1: 'a', 2: 'b', 3: 'c' }
const set = new Set([1, 2, 3, 4, 5])
obj.hasOwnProperty('1')
obj.hasOwnProperty(1)
set.has('1')
set.has(1)A. false true false true B. false true true true C. true true false true D. true true true true
答案:
正确选项:C. true true false true。普通对象的数字键会转换为字符串键,因此 hasOwnProperty('1') 和 hasOwnProperty(1) 都命中属性 "1"。Set 不做这种键名转换,成员比较基于 SameValueZero,字符串 '1' 与数字 1 不相等,故后两项为 false、true。
67. 输出是什么?
javascript
var num = 8
var num = 10
console.log(num)A. 8 B. 10 C. SyntaxError D. ReferenceError
答案:
正确选项:B. 10。同一作用域中可用 var 重复声明同名变量,第二次赋值将 num 更新为 10,所以输出最新值。若改为 let 或 const 在同一作用域重复声明,会在解析阶段抛出 SyntaxError;原因是它们不允许重复绑定。
68. cool_secret 可访问多长时间?
javascript
sessionStorage.setItem('cool_secret', 123)A. 永远,数据不会丢失。 B. 当用户关掉标签页时。 C. 当用户关掉整个浏览器,而不只是关掉标签页。 D. 当用户关闭电脑时。
答案:
正确选项:B. 当用户关掉标签页时。sessionStorage 按源和顶级浏览上下文分别保存,页面刷新或同一标签页内跳转通常仍可读取;关闭该标签页会结束会话并清除数据。它并非跨标签共享的持久存储;需要长期保存时应使用 localStorage 或服务端存储。
69. 下面代码中,sum 的值是什么?
javascript
const sum = eval('10*10+5')A. 105 B. "105" C. TypeError D. "10*10+5"
答案:
正确选项:A. 105。eval 将传入的字符串按 JavaScript 源码执行,10*10+5 是数值表达式,结果为数字 105,不是字符串。实际项目不应对不可信输入使用 eval:它可执行任意代码,且会带来安全、优化和可维护性问题;应改用受限解析器。
70. 输出是什么?
javascript
function getAge() {
'use strict'
age = 21
console.log(age)
}
getAge()A. 21 B. undefined C. ReferenceError D. TypeError
答案:
正确选项:C. ReferenceError。函数启用严格模式后,给未声明的标识符 age 赋值是非法操作,执行到该行即抛错,后面的 console.log 不会运行。非严格的经典脚本中,这类赋值可能创建全局属性;严格模式和 ES 模块都会禁止这种隐式全局变量。
71. 输出是什么?
javascript
function getAge(...args) {
console.log(typeof args)
}
getAge(21)A. "number" B. "array" C. "object" D. "NaN"
答案:
正确选项:C. "object"。剩余参数 ...args 会把传入的其余实参收集为一个真正的数组,本例为 [21]。JavaScript 的 typeof 对数组仍返回 "object",没有 "array" 这种结果;需判断数组时应使用 Array.isArray(args)。
72. 输出是什么?
javascript
function checkAge(data) {
if (data === { age: 18 }) {
console.log('You are an adult!')
} else if (data == { age: 18 }) {
console.log('You are still an adult.')
} else {
console.log(`Hmm.. You don't have an age I guess`)
}
}
checkAge({ age: 18 })A. You are an adult! B. You are still an adult. C. Hmm.. You don't have an age I guess
答案:
正确选项:C. Hmm.. You don't have an age I guess。两个对象字面量即使属性完全相同,也是在不同位置创建的两个引用。对象参与 === 时比较引用;== 在两个对象之间同样不会按属性深比较,因此两个条件均为 false。要比较结构,应显式比较字段或使用深比较函数。
73. 输出是什么?
javascript
function getPersonInfo(one, two, three) {
console.log(one)
console.log(two)
console.log(three)
}
const person = 'Lydia'
const age = 21
getPersonInfo`${person} is ${age} years old`A. "Lydia" 21 ["", " is ", " years old"] B. ["", " is ", " years old"] "Lydia" 21 C. "Lydia" ["", " is ", " years old"] 21
答案:
正确选项:B. ["", " is ", " years old"] "Lydia" 21。这里是标记模板调用,不是普通函数调用。标签函数的首个参数为模板静态片段组成的数组,后续参数依次是插值表达式的结果,即 person 的 Lydia 与 age 的 21。
74. 输出是什么?
javascript
let number = 0
console.log(number++)
console.log(++number)
console.log(number)A. 1 1 2 B. 1 2 2 C. 0 2 2 D. 0 1 2
答案:
正确选项:C. 0 2 2。后置自增 number++ 先返回旧值 0,再把变量改为 1;前置自增 ++number 先递增到 2,再返回新值 2。最后变量保持 2。两者都会修改原变量,区别仅在表达式取值的时机。
75. 以下代码的输出是什么?
javascript
function sum(a, b) {
return a + b
}
sum(1, '2')A. NaN B. TypeError C. "12" D. 3
答案:
正确选项:C. "12"。+ 遇到字符串操作数时会执行字符串拼接,数字 1 被转换为字符串,得到 "1" + "2"。这与减法不同,- 会尝试数值转换。业务代码应避免依赖隐式转换,可用 Number() 或模板字符串明确表达意图。
76. 输出是什么?
javascript
function Person(firstName, lastName) {
this.firstName = firstName
this.lastName = lastName
}
const lydia = new Person('Lydia', 'Hallie')
const sarah = Person('Sarah', 'Smith')
console.log(lydia)
console.log(sarah)A. Person {firstName: "Lydia", lastName: "Hallie"} and undefined B. Person {firstName: "Lydia", lastName: "Hallie"} and Person {firstName: "Sarah", lastName: "Smith"} C. Person {firstName: "Lydia", lastName: "Hallie"} and {} D. Person {firstName: "Lydia", lastName: "Hallie"} and ReferenceError
答案:
正确选项:A. Person {firstName: "Lydia", lastName: "Hallie"} and undefined。new Person(...) 会创建实例并把它作为构造函数的 this,故 lydia 是实例。第二次只是普通调用,函数未显式 return,所以结果为 undefined。在经典非严格脚本中 this 会指向全局对象;严格模式或模块中该调用会因 this 为 undefined 而抛错。
77. 输出是什么?
javascript
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
const member = new Person("Lydia", "Hallie");
Person.getFullName = function () {
return `${this.firstName} ${this.lastName}`;
}
console.log(member.getFullName());A. TypeError B. SyntaxError C. Lydia Hallie D. undefined undefined
答案:
正确选项:A. TypeError。Person.getFullName 是构造函数对象自身的静态属性,不在 member 实例的属性或原型链上,所以调用 member.getFullName() 失败。若希望所有实例可调用,应定义 Person.prototype.getFullName = function () { return ${this.firstName} ${this.lastName} }。
78. 当我们这么做时,会发生什么?
javascript
function bark() {
console.log('Woof!')
}
bark.animal = 'dog'A. 正常运行! B. SyntaxError. 你不能通过这种方式给函数增加属性。 C. undefined D. ReferenceError
答案:
正确选项:A. 正常运行! JavaScript 中函数是一等对象:它既可调用,也可以拥有可读写属性。因此 bark.animal = 'dog' 会在函数对象上新增属性,不会执行 bark 也不会输出内容。函数属性适合少量元数据,不宜用来替代清晰的对象结构。
79. 输出是什么?
javascript
let greeting
greetign = {} // Typo!
console.log(greetign)A. {} B. ReferenceError: greetign is not defined C. undefined
答案:
正确选项:A. {}。题中把已声明的 greeting 误写成 greetign;在非严格经典脚本中,对未声明标识符赋值会创建全局属性,因此可打印空对象。严格模式和 ES 模块会在赋值处抛出 ReferenceError,这也是应始终启用严格语义并使用 lint 的原因。
80. 输出是什么?
javascript
class Chameleon {
static colorChange(newColor) {
this.newColor = newColor
return this.newColor
}
constructor({ newColor = 'green' } = {}) {
this.newColor = newColor
}
}
const freddie = new Chameleon({ newColor: 'purple' })
console.log(freddie.colorChange('orange'));A. orange B. purple C. green D. TypeError
答案:
正确选项:D. TypeError。colorChange 由 static 定义,属于类构造函数 Chameleon,不属于实例 freddie,所以实例上找不到这个方法。应写 Chameleon.colorChange('orange');若要由每个实例调用,则去掉 static。静态方法中的 this 也会指向调用它的类。
81. 输出是什么?
javascript
let a = 3
let b = new Number(3)
let c = 3
console.log(a == b)
console.log(a === b)
console.log(b === c)A. true false true B. false false true C. true false false D. false true true
答案:
正确选项:C. true false false。a、c 是数值原始值,而 b 是 new Number(3) 创建的包装对象。宽松相等会把包装对象转换为原始数值,故 a == b 为 true;严格相等要求类型一致,且对象与数值不同,因此后两项均为 false。通常不要使用 new Number()。
82. 输出是什么?
javascript
let c = { greeting: 'Hey!' }
let d
d = c
c.greeting = 'Hello'
console.log(d.greeting)A. Hello B. undefined C. ReferenceError D. TypeError
答案:
正确选项:A. Hello。对象赋值复制的是引用值,d = c 后两变量指向同一个对象。修改 c.greeting 就是修改该共享对象,因此通过 d.greeting 也读到 Hello。若需独立副本,可浅拷贝 { ...c };嵌套对象则还需深拷贝策略。
83. 哪一个是正确的?
javascript
const bird = {
size: 'small'
}
const mouse = {
name: 'Mickey',
small: true
}A. mouse.bird.size是无效的 B. mouse[bird.size]是无效的 C. mouse[bird["size"]]是无效的 D. 以上三个选项都是有效的
答案:
正确选项:A. mouse.bird.size是无效的。mouse 没有 bird 属性,mouse.bird 为 undefined,继续访问 .size 会抛出 TypeError。而 bird.size 为 'small',故 mouse[bird.size] 等价于 mouse['small'],返回 true;mouse[bird['size']] 亦然。可用 mouse.bird?.size 安全访问。
84. 输出是什么?
javascript
console.log(+true,!"Lydia");A. 1 false B. false NaN C. false false
答案:
正确选项:A. 1 false。一元加号触发数值转换,true 转为 1;非空字符串 "Lydia" 是真值,逻辑非 ! 会得到 false。注意空字符串、0、null、undefined、NaN 才是假值,其余对象和非空字符串都是真值。
85. 输出是什么?
javascript
const shape = {
radius: 10,
diameter() {
return this.radius * 2
},
perimeter: () => 2 * Math.PI * this.radius
}
console.log(shape.diameter())
console.log(shape.perimeter())A. 20 and 62.83185307179586 B. 20 and NaN C. 20 and 63 D. NaN and 63
答案:
正确选项:B. 20 and NaN。简写方法 diameter() 由 shape 调用,动态 this 指向 shape,得到 20。perimeter 是箭头函数,不会因对象调用而绑定 this,它捕获外层 this;经典脚本中外层对象没有 radius,计算结果为 NaN。在 ES 模块顶层 this 为 undefined,第二次调用会抛出 TypeError。
86. 输出是什么?
javascript
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1)
}
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1)
}A. 0 1 2 和 0 1 2 B. 0 1 2 和 3 3 3 C. 3 3 3 和 0 1 2
答案:
正确选项:C. 3 3 3 和 0 1 2。定时器回调会在两轮同步循环结束后执行。var 在函数或全局作用域只有一个共享绑定,届时已递增为 3;let 的 for 循环每次迭代都有独立绑定,三个回调分别捕获 0、1、2。延迟时间不保证精确执行时刻。
87. 输出是什么?
javascript
function sayHi() {
console.log(name)
console.log(age)
var name = 'Lydia'
let age = 21
}
sayHi()A. Lydia 和 undefined B. Lydia 和 ReferenceError C. ReferenceError 和 21 D. undefined 和 ReferenceError
答案:
正确选项:D. undefined 和 ReferenceError。var name 的声明被提升并初始化为 undefined,所以第一次打印不报错。let age 也在作用域创建时建立绑定,但声明语句之前处于暂时性死区,访问它立即抛出 ReferenceError,函数随即终止,不会执行后续赋值。
88. 输出什么?
javascript
let randomValue = { name: "Lydia" }
randomValue = 23
if (!typeof randomValue === "string") {
console.log("It's not a string!")
} else {
console.log("Yay it's a string!")
}A. It's not a string! B. Yay it's a string! C. TypeError D. undefined
答案:
正确选项:B. Yay it's a string!。运算符优先级使条件按 (!typeof randomValue) === 'string' 计算。typeof 23 为真值字符串 'number',取反后是布尔值 false,再与字符串严格相等仍为 false,故进入 else。意图判断类型应写 typeof randomValue !== 'string'。
89. 输出什么?
javascript
const createMember = ({ email, address = {}}) => {
const validEmail = /.+\@.+\..+/.test(email)
if (!validEmail) throw new Error("Valid email pls")
return {
email,
address: address ? address : null
}
}
const member = createMember({ email: "my@email.com" })
console.log(member)A. { email: "my@email.com", address: null } B. { email: "my@email.com" } C. { email: "my@email.com", address: {} } D. { email: "my@email.com", address: undefined }
答案:
正确选项:C. { email: "my@email.com", address: {} }。调用时未提供 address,解构默认值生效,得到新建的空对象 {}。对象为真值,三元表达式返回该对象而非 null。默认值仅在属性值为 undefined 时触发;显式传入 null 时不会触发,结果的 address 才会是 null。
90. method 的值选择哪个时,会输出 { name: "Lydia", age: 22 } ?
javascript
const keys = ["name", "age"]
const values = ["Lydia", 22]
const method = /* ?? */
Object[method](keys.map((_, i) => {
return [keys[i], values[i]]
})) // { name: "Lydia", age: 22 }A. entries B. values C. fromEntries D. forEach
答案:
正确选项:C. fromEntries。keys.map 生成 [["name", "Lydia"], ["age", 22]] 这样的键值对可迭代对象,Object.fromEntries 将其转为 { name: "Lydia", age: 22 }。Object.entries 的方向相反,用于把对象转为键值对数组;该方法需要 ES2019 及以上环境。
91. 输出什么?
javascript
const promise1 = Promise.resolve('First')
const promise2 = Promise.resolve('Second')
const promise3 = Promise.reject('Third')
const promise4 = Promise.resolve('Fourth')
const runPromises = async () => {
const res1 = await Promise.all([promise1, promise2])
const res2 = await Promise.all([promise3, promise4])
return [res1, res2]
}
runPromises()
.then(res => console.log(res))
.catch(err => console.log(err))A. [['First', 'Second'], ['Fourth']] B. [['First', 'Second'], ['Third', 'Fourth']] C. [['First', 'Second']] D. 'Third'
答案:
正确选项:D. 'Third'。第一个 Promise.all 成功得到 ['First', 'Second'];第二个数组包含以 'Third' 拒绝的 promise,因此 Promise.all 立即以该原因拒绝。async 函数随之返回 rejected promise,外层 .catch 打印 Third。其他 promise 仍会继续执行,只是其结果不会组成 res2。
92. 输出什么?
javascript
const user = {
email: "my@email.com",
updateEmail: email => {
this.email = email
}
}
user.updateEmail("new@email.com")
console.log(user.email)A. my@email.com B. new@email.com C. undefined D. ReferenceError
答案:
正确选项:A. my@email.com。对象中的箭头函数不拥有自己的 this,this 词法捕获自定义对象时的外层作用域,不会因 user.updateEmail() 调用而变成 user。因此没有修改 user.email。应把方法写成 updateEmail(email) { this.email = email };模块顶层还可能因外层 this 为 undefined 而抛错。
93. 输出什么?
javascript
const animals = {};
let dog = { emoji: '🐶' }
let cat = { emoji: '🐈' }
animals[dog] = { ...dog, name: "Mara" }
animals[cat] = { ...cat, name: "Sara" }
console.log(animals[dog])A. { emoji: "🐶", name: "Mara" } B. { emoji: "🐈", name: "Sara" } C. undefined D. ReferenceError
答案:
正确选项:B. { emoji: "🐈", name: "Sara" }。用对象作为普通对象的计算属性键时会先转为属性键;两个普通对象默认都转成同一字符串 "[object Object]"。所以第二次 animals[cat] 覆盖第一次的值,随后 animals[dog] 读取到猫的数据。要以对象身份作键,应使用 Map。
94. 输出什么?
javascript
const fruit = ['🍌', '🍊', '🍎']
fruit.slice(0, 1)
fruit.splice(0, 1)
fruit.unshift('🍇')
console.log(fruit)A. ['🍌', '🍊', '🍎'] B. ['🍊', '🍎'] C. ['🍇', '🍊', '🍎'] D. ['🍇', '🍌', '🍊', '🍎']
答案:
正确选项:C. ['🍇', '🍊', '🍎']。slice(0, 1) 只返回新数组,不改变 fruit;splice(0, 1) 会原地删除首项香蕉,剩下橙子和苹果;unshift('🍇') 再原地在开头插入葡萄。数组的变异方法会影响共享引用,使用时需注意副作用。
95. 输出什么?
javascript
const user = {
email: "e@mail.com",
password: "12345"
}
const updateUser = ({ email, password }) => {
if (email) {
Object.assign(user, { email })
}
if (password) {
user.password = password
}
return user
}
const updatedUser = updateUser({ email: "new@email.com" })
console.log(updatedUser === user)A. false B. true C. TypeError D. ReferenceError
答案:
正确选项:B. true。updateUser 通过 Object.assign 和属性赋值直接修改外部的 user,并显式返回的也是同一个对象引用。因此 updatedUser 与 user 使用 === 比较为 true。这不是不可变更新;若需新对象应返回 { ...user, email, password } 并避免修改原对象。
96. 输出什么?
javascript
class Calc {
constructor() {
this.count = 0
}
increase() {
this.count ++
}
}
const calc = new Calc()
new Calc().increase()
console.log(calc.count)A. 0 B. 1 C. undefined D. ReferenceError
答案:
正确选项:A. 0。calc 与 new Calc().increase() 创建的是两个不同实例,count 是构造函数写入到各实例自身的属性,并不在实例间共享。increase() 只把那个临时实例的计数改为 1,calc.count 仍为初始值 0。共享状态需要显式放在静态字段或外部存储中。
97. 输出是什么?
javascript
function getFruit(fruits) {
console.log(fruits?.[1]?.[1])
}
getFruit([['🍊', '🍌'], ['🍍']])
getFruit()
getFruit([['🍍'], ['🍊', '🍌']])A. null, undefined, 🍌 B. [], null, 🍌 C. [], [], 🍌 D. undefined, undefined, 🍌
答案:
正确选项:D. undefined, undefined, 🍌。三次输出依次为 undefined、undefined、🍌。可选链在 fruits 缺失、索引 1 不存在或子数组索引 1 不存在时短路并返回 undefined,不会抛出访问属性的异常;第三个实参的第二个子数组为 ['🍊', '🍌']。
98. 输出什么?
javascript
let count = 0;
const nums = [0, 1, 2, 3];
nums.forEach(num => {
if (num) count += 1
})
console.log(count)A. 1 B. 2 C. 3 D. 4
答案:
正确选项:C. 3。输出为 3。if 会把条件转为布尔值,数字 0 是 falsy,因此遍历到第一个元素时不累加;1、2、3 都是 truthy,各使 count 加一。注意不要把数值 0 的真假判断与数组下标是否存在混为一谈。
99. 向对象 person 添加什么时,可以通过执行 [...person] 获得类似 ["Lydia Hallie", 21] 的输出?
javascript
const person = {
name: "Lydia Hallie",
age: 21
}
[...person] // ["Lydia Hallie", 21]A. 不需要,对象默认就是可迭代的 B. *Symbol.iterator { for (let x in this) yield this[x] } C. Symbol.iterator { for (let x in this) yield Object.values(this) } D. *Symbol.iterator { for (let x in this) yield this }
答案:
正确选项:B. *[Symbol.iterator]() { for (let x in this) yield this[x] }。普通对象默认不可迭代,展开运算符需要其提供 Symbol.iterator。该生成器按可枚举属性依次产出 name 和 age 的值,故 [...person] 得到 ['Lydia Hallie', 21];实际项目中应避免枚举继承属性。
100. 哪一个选项会导致报错?
javascript
const emojis = ["🎄", "🎅🏼", "🎁", "⭐"];
/* 1 */ emojis.push("🦌");
/* 2 */ emojis.splice(0, 2);
/* 3 */ emojis = [...emojis, "🥂"];
/* 4 */ emojis.length = 0;A. 1 B. 1 and 2 C. 3 and 4 D. 3
答案:
正确选项:D. 3。第 3 行会抛出错误,因为 const 绑定不能重新赋值,emojis = [...] 试图替换变量所指向的数组。const 限制的是绑定而非对象内容,所以 push、splice 和修改 length 都是在原数组上操作,语法上允许。
101. 输出什么?
javascript
class Bird {
constructor() {
console.log("I'm a bird. 🦢");
}
}
class Flamingo extends Bird {
constructor() {
console.log("I'm pink. 🌸");
super();
}
}
const pet = new Flamingo();A. I'm pink. 🌸 B. I'm pink. 🌸 I'm a bird. 🦢 C. I'm a bird. 🦢 I'm pink. 🌸 D. Nothing, we didn't call any method
答案:
正确选项:B. I'm pink. 🌸 I'm a bird. 🦢。实例化 Flamingo 时先进入子类构造器,第一条日志先执行;随后 super() 调用父类 Bird 的构造器,输出第二条日志。派生类构造器中若要访问 this,必须先执行 super(),但本例在此前仅执行了日志。
102. 输出什么?
javascript
const person = {
name: "Lydia Hallie",
hobbies: ["coding"]
};
function addHobby(hobby, hobbies = person.hobbies) {
hobbies.push(hobby);
return hobbies;
}
addHobby("running", []);
addHobby("dancing");
addHobby("baking", person.hobbies);
console.log(person.hobbies);A. ["coding"] B. ["coding", "dancing"] C. ["coding", "dancing", "baking"] D. ["coding", "running", "dancing", "baking"]
答案:
正确选项:C. ["coding", "dancing", "baking"]。第一次传入独立的空数组,running 不会影响 person.hobbies。第二次未传第二参,默认参数直接引用 person.hobbies;第三次也显式传入同一数组,因此依次追加 dancing 和 baking。默认参数不是深拷贝。
103. 选择哪一个?
javascript
const teams = [
{ name: "Team 1", members: ["Paul", "Lisa"] },
{ name: "Team 2", members: ["Laura", "Tim"] }
];
function* getMembers(members) {
for (let i = 0; i < members.length; i++) {
yield members[i];
}
}
function* getTeams(teams) {
for (let i = 0; i < teams.length; i++) {
// ✨ SOMETHING IS MISSING HERE ✨
}
}
const obj = getTeams(teams);
obj.next(); // { value: "Paul", done: false }
obj.next(); // { value: "Lisa", done: false }A. yield getMembers(teams[i].members) B. yield* getMembers(teams[i].members) C. return getMembers(teams[i].members) D. return yield getMembers(teams[i].members)
答案:
正确选项:B. yield* getMembers(teams[i].members)。getMembers 返回的是生成器对象;yield* 会委托迭代它,并把其中每个成员逐个产出,所以连续两次 next() 得到 Paul、Lisa。仅用 yield 会把整个生成器对象作为一个值产出,而不是成员字符串。
104. 输出是什么?
javascript
class Counter {
#number = 10
increment() {
this.#number++
}
getNum() {
return this.#number
}
}
const counter = new Counter()
counter.increment()
console.log(counter.#number)A. 10 B. 11 C. undefined D. SyntaxError
答案:
正确选项:D. SyntaxError。#number 是类私有字段,只能在声明它的类体内通过 this.#number 访问。虽然 increment() 后其内部值为 11,但 counter.#number 在类外属于非法私有字段访问,代码解析阶段即报语法错误;应调用 counter.getNum()。
105. 输出什么?
javascript
const add = x => x + x;
function myFunc(num = 2, value = add(num)) {
console.log(num, value);
}
myFunc();
myFunc(3);A. 2 4 and 3 6 B. 2 NaN and 3 NaN C. 2 Error and 3 6 D. 2 4 and 3 Error
答案:
正确选项:A. 2 4 and 3 6。输出依次为 2 4 与 3 6。形参默认值按从左到右求值,value = add(num) 能使用已经确定的 num:首次取默认值 2,第二次使用传入的 3。只有实参为 undefined 时才会启用默认参数。
106. 以下哪一项会对对象 person 有副作用?
javascript
const person = {
name: "Lydia Hallie",
address: {
street: "100 Main St"
}
};
Object.freeze(person);A. person.name = "Evan Bacon" B. delete person.address C. person.address.street = "101 Main St" D. person.pet = { name: "Mara" }
答案:
正确选项:C. person.address.street = "101 Main St"。Object.freeze(person) 只冻结第一层对象:不能新增、删除或改写 name、address 等直接属性,但 address 本身仍是可变对象,所以其 street 可被改写。需要深度不可变时,必须递归冻结或使用不可变数据更新。
107. 以下哪一项会对对象 person 有副作用?
javascript
const person = { name: "Lydia Hallie" };
Object.seal(person);A. person.name = "Evan Bacon" B. person.age = 21 C. delete person.name D. Object.assign(person, { age: 21 })
答案:
正确选项:A. person.name = "Evan Bacon"。Object.seal 禁止给对象新增属性或删除已有属性,并将对象设为不可扩展;但已有数据属性在仍可写时可以修改。因此改写 name 有副作用,新增 age、删除 name 以及用 Object.assign 新增 age 都不会成功。
108. 输出什么?
javascript
const handler = {
set: () => console.log("Added a new property!"),
get: () => console.log("Accessed a property!")
};
const person = new Proxy({}, handler);
person.name = "Lydia";
person.name;A. Added a new property! B. Accessed a property! C. Added a new property! Accessed a property! D. 没有任何输出
答案:
正确选项:C. Added a new property! Accessed a property!。先执行赋值,Proxy 的 set 捕获器输出第一句;随后读取 person.name,get 捕获器输出第二句。捕获器没有调用 Reflect.set 或 Reflect.get,因此这里主要演示拦截行为,属性本身未必会真正写入目标对象。
109. 怎样能在 index.js 中调用 sum.js 中的 sum 方法?
javascript
// sum.js
export default function sum(x) {
return x + x;
}
// index.js
import * as sum from "./sum";A. sum(4) B. sum.sum(4) C. sum.default(4) D. 默认导出不用 * 来导入,只能具名导出
答案:
正确选项:C. sum.default(4)。import * as sum 得到模块命名空间对象,默认导出挂在其 default 属性上,因此调用结果为 8。sum 本身不是函数,且模块没有名为 sum 的具名导出。更直接的写法是 import sum from './sum'。
110. 输出什么?
javascript
const myPromise = Promise.resolve(Promise.resolve("Promise!"));
function funcOne() {
myPromise.then(res => res).then(res => console.log(res));
setTimeout(() => console.log("Timeout!"), 0);
console.log("Last line!");
}
async function funcTwo() {
const res = await myPromise;
console.log(await res);
setTimeout(() => console.log("Timeout!"), 0);
console.log("Last line!");
}
funcOne();
funcTwo();A. Promise! Last line! Promise! Last line! Last line! Promise! B. Last line! Timeout! Promise! Last line! Timeout! Promise! C. Promise! Last line! Last line! Promise! Timeout! Timeout! D. Last line! Promise! Promise! Last line! Timeout! Timeout!
答案:
正确选项:D. Last line! Promise! Promise! Last line! Timeout! Timeout!。funcOne 同步打印第一句后返回;两个 await/then 的后续进入微任务队列,均先于定时器宏任务执行。funcTwo 恢复后先输出已解析值,再注册定时器并输出最后一行,两个 setTimeout 最后依次执行。
111. 输出什么?
javascript
class Counter {
constructor() {
this.count = 0;
}
increment() {
this.count++;
}
}
const counterOne = new Counter();
counterOne.increment();
counterOne.increment();
const counterTwo = counterOne;
counterTwo.increment();
console.log(counterOne.count);A. 0 B. 1 C. 2 D. 3
答案:
正确选项:D. 3。counterTwo = counterOne 不会创建新实例或复制状态,两个变量保存的是同一个 Counter 对象引用。前两次通过 counterOne 加到 2,随后通过 counterTwo 再加一次,读取 counterOne.count 时看到共享对象中的 3。
112. 输出什么?
javascript
const emojis = ["🥑", ["✨", "✨", ["🍕", "🍕"]]];
console.log(emojis.flat(1));A. ['🥑', ['✨', '✨', ['🍕', '🍕']]] B. ['🥑', '✨', '✨', ['🍕', '🍕']] C. ['🥑', ['✨', '✨', '🍕', '🍕']] D. ['🥑', '✨', '✨', '🍕', '🍕']
答案:
正确选项:B. ['🥑', '✨', '✨', ['🍕', '🍕']]。flat(1) 仅展开一层嵌套:外层中的第二个数组被展开,里面的披萨数组仍保留为数组。若想完全展开可使用 flat(Infinity),但要注意深层或超大数据的性能和栈深度问题。
113. 输出什么?
javascript
const myPromise = Promise.resolve("Woah some cool data");
(async () => {
try {
console.log(await myPromise);
} catch {
throw new Error(`Oops didn't work`);
} finally {
console.log("Oh finally!");
}
})();A. Woah some cool data B. Oh finally! C. Woah some cool data Oh finally! D. Oops didn't work Oh finally!
答案:
正确选项:C. Woah some cool data Oh finally!。myPromise 已成功兑现,await 输出其值,catch 不会运行;无论 try 成功、失败或提前返回,finally 都会执行,因此随后输出 Oh finally!。若 finally 抛错或返回被拒绝的 Promise,则会覆盖原有控制流。
114. 输出什么?
javascript
const randomValue = 21;
function getInfo() {
console.log(typeof randomValue);
const randomValue = "Lydia Hallie";
}
getInfo();A. "number" B. "string" C. undefined D. ReferenceError
答案:
正确选项:D. ReferenceError。函数体内的 const randomValue 会遮蔽外层同名变量;从函数开始到该声明初始化完成前,它处于暂时性死区。第一行读取命中的正是这个尚未初始化的内层绑定,所以不能得到外层数字类型,而是直接报错。
115. 输出什么?
javascript
const name = "Lydia Hallie";
const age = 21;
console.log(Number.isNaN(name));
console.log(Number.isNaN(age));
console.log(isNaN(name));
console.log(isNaN(age));A. true false true false B. true false false false C. false false true false D. false true false true
答案:
正确选项:C. false false true false。Number.isNaN 不做类型转换,字符串和数字都不是实际的 NaN,故均为 false。全局 isNaN(name) 会先把字符串转换为数值,'Lydia Hallie' 转换失败得到 NaN,故为 true;业务代码通常优先用 Number.isNaN。
116. 输出什么?
javascript
const spookyItems = ["👻", "🎃", "🕸"];
({ item: spookyItems[3] } = { item: "💀" });
console.log(spookyItems);A. ["👻", "🎃", "🕸"] B. ["👻", "🎃", "🕸", "💀"] C. ["👻", "🎃", "🕸", { item: "💀" }] D. ["👻", "🎃", "🕸", "[object Object]"]
答案:
正确选项:B. ["👻", "🎃", "🕸", "💀"]。解构赋值右侧对象的 item 属性,并把其值写入左侧的 spookyItems[3]。数组原先长度为 3,给索引 3 赋值会扩展数组并追加该元素;圆括号用于避免语句开头的 {} 被解析成代码块。
117. 输出什么?
javascript
function getFine(speed, amount) {
const formattedSpeed = new Intl.NumberFormat('en-US', {
style: 'unit', unit: 'mile-per-hour'
}).format(speed)
const formattedAmount = new Intl.NumberFormat('en-US', {
style: 'currency', currency: 'USD'
}).format(amount)
return `The driver drove ${formattedSpeed} and has to pay ${formattedAmount}`
}
console.log(getFine(130, 300))A. The driver drove 130 and has to pay 300 B. The driver drove 130 mph and has to pay $300.00 C. The driver drove undefined and has to pay undefined D. The driver drove 130.00 and has to pay 300.00
答案:
正确选项:B. The driver drove 130 mph and has to pay $300.00。Intl.NumberFormat('en-US', { style: 'unit', unit: 'mile-per-hour' }) 把 130 格式化为 130 mph;货币格式且币种为 USD 时,300 被格式化为 $300.00。不同 locale 的符号、空格和小数展示可能不同。
118. 输出什么?
javascript
const myFunc = ({ x, y, z }) => {
console.log(x, y, z);
};
myFunc(1, 2, 3);A. 1 2 3 B. {1: 1} {2: 2} {3: 3} C. { 1: undefined } undefined undefined D. undefined undefined undefined
答案:
正确选项:D. undefined undefined undefined。函数只接收第一个实参,并在参数位置执行对象解构;传入数字 1 会被装箱为对象,但没有 x、y、z 属性,因此三项均为 undefined。后两个实参 2、3 没有对应形参,完全不会参与解构。
119. 输出什么?
javascript
async function* range(start, end) {
for (let i = start; i <= end; i++) {
yield Promise.resolve(i);
}
}
(async () => {
const gen = range(1, 3);
for await (const item of gen) {
console.log(item);
}
})();A. Promise {1} Promise {2} Promise {3} B. Promise {<pending>} Promise {<pending>} Promise {<pending>} C. 1 2 3 D. undefined undefined undefined
答案:
正确选项:C. 1 2 3。异步生成器依次产出三个已兑现的 Promise;for await...of 会等待每次迭代的值完成后再赋给 item,因此打印兑现值而非 Promise 对象。循环按顺序等待,适合有序异步流,但慢项会阻塞后续项的处理。
120. 输出什么?
javascript
const add = x => y => z => {
console.log(x, y, z);
return x + y + z;
};
add(4)(5)(6);A. 4 5 6 B. 6 5 4 C. 4 function function D. undefined undefined 6
答案:
正确选项:A. 4 5 6。add 是柯里化函数:add(4) 返回接收 y 的函数,再调用 (5) 返回接收 z 的函数,最后 (6) 执行最内层函数。闭包保留外层调用的 x=4、y=5,所以日志按参数声明顺序打印三个数字。
121. 输出什么?
javascript
const name = "Lydia Hallie";
console.log(!typeof name === "object");
console.log(!typeof name === "string");A. false true B. true false C. false false D. true true
答案:
正确选项:C. false false。typeof name 的结果是非空字符串 'string',它为 truthy;一元 ! 优先执行后得到布尔值 false,再分别与字符串 'object'、'string' 严格比较,结果都为 false。类型判断应写成 typeof name === 'string'。
122. 输出什么?
javascript
const config = {
languages: [],
set language(lang) {
return this.languages.push(lang);
}
};
console.log(config.language);A. function language(lang) { this.languages.push(lang } B. 0 C. [] D. undefined
答案:
正确选项:D. undefined。language 只定义了 setter,没有定义 getter;读取 config.language 时不存在可调用的 getter,因此表达式值为 undefined,也不会向 languages 中添加元素。setter 的 return 值会被赋值表达式忽略,不能作为属性读取结果。
123. 输出什么?
javascript
const groceries = ["banana", "apple", "peanuts"];
if (groceries.indexOf("banana")) {
console.log("We have to buy bananas!");
} else {
console.log(`We don't have to buy bananas!`);
}A. We have to buy bananas! B. We don't have to buy bananas C. undefined D. 1
答案:
正确选项:B. We don't have to buy bananas。实际日志带有感叹号:We don't have to buy bananas!。indexOf('banana') 返回首次匹配下标 0,而 0 是 falsy,所以进入 else。判断元素是否存在应使用 indexOf(...) !== -1 或更清晰的 includes(...)。
124. 下面的输出是什么?
javascript
const person = {
firstName: "Lydia",
lastName: "Hallie",
pet: {
name: "Mara",
breed: "Dutch Tulip Hound"
},
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
};
console.log(person.pet?.name);
console.log(person.pet?.family?.name);
console.log(person.getFullName?.());
console.log(person.getLastName?.());A. undefined undefined undefined undefined B. Mara undefined Lydia Hallie undefined C. Mara null Lydia Hallie null D. null ReferenceError null ReferenceError
答案:
正确选项:B. Mara undefined Lydia Hallie undefined。第一行读取已有宠物名;第二行因 family 缺失,经可选链返回 undefined;第三行可选调用已有方法并取得全名;第四行对不存在的方法进行可选调用,同样返回 undefined。可选链只短路 null 或 undefined。
125. 输出什么?
javascript
let num = 1;
const list = ["🥳", "🤠", "🥰", "🤪"];
console.log(list[(num += 1)]);A. 🤠 B. 🥰 C. SyntaxError D. ReferenceError
答案:
正确选项:B. 🥰。复合赋值表达式 num += 1 先将 num 从 1 更新为 2,且整个表达式的值也是 2;随后访问 list[2]。数组采用零基下标,索引 0、1、2 分别对应 🥳、🤠、🥰。
126. 下面那个选项将会返回 '6' ?
javascript
function sumValues(x, y, z) {
return x + y + z;
}A. sumValues([...1, 2, 3]) B. sumValues([...[1, 2, 3]]) C. sumValues(...[1, 2, 3]) D. sumValues([1, 2, 3])
答案:
正确选项:C. sumValues(...[1, 2, 3])。展开运算符将数组迭代为三个独立实参,等价于 sumValues(1, 2, 3),返回数值 6。其余写法要么语法无效,要么只把一个数组传给第一个形参,导致后续形参为 undefined 并产生非预期结果。
127. 输出什么?
javascript
const person = {
name: "Lydia",
age: 21
}
const changeAge = (x = { ...person }) => x.age += 1
const changeAgeAndName = (x = { ...person }) => {
x.age += 1
x.name = "Sarah"
}
changeAge(person)
changeAgeAndName()
console.log(person)A. {name: "Sarah", age: 22} B. {name: "Sarah", age: 23} C. {name: "Lydia", age: 22} D. {name: "Lydia", age: 23}
答案:
正确选项:C. {name: "Lydia", age: 22}。changeAge(person) 传入原对象,直接把其年龄改为 22。changeAgeAndName() 未传参,默认值 { ...person } 创建了第一层副本,改名和加年龄仅作用于副本。对象展开是浅拷贝,嵌套对象仍会共享引用。
128. 哪一个方法会返回 'Hello world!' ?
javascript
const myMap = new Map()
const myFunc = () => 'greeting'
myMap.set(myFunc, 'Hello world!')
//1
myMap.get('greeting')
//2
myMap.get(myFunc)
//3
myMap.get(() => 'greeting')A. 1 B. 2 C. 2 and 3 D. All of them
答案:
正确选项:B. 2。Map 的键按 SameValueZero 比较,对对象和函数比较的是引用身份。set 时使用的键是变量 myFunc 所指向的那个函数,因此只有 myMap.get(myFunc) 能取到 'Hello world!';字符串 'greeting' 和新建的同形箭头函数都不是同一键。
129. 将会发生什么?
javascript
let config = {
alert: setInterval(() => {
console.log('Alert!')
}, 1000)
}
config = nullA. setInterval 的回调不会被调用 B. setInterval 的回调被调用一次 C. setInterval 的回调仍然会被每秒钟调用 D. 我们从没调用过 config.alert(), config 为 null
答案:
正确选项:C. setInterval 的回调仍然会被每秒钟调用。config = null 只断开变量对对象的引用,并不会取消已注册的定时器;定时器任务仍由宿主环境持有并持续触发。要停止它,必须在丢失句柄前调用 clearInterval(config.alert)。
130. 输出什么?
javascript
console.log(`${(x => x)('I love')} to program`)A. I love to program B. undefined to program C. ${(x => x)('I love') to program D. TypeError
答案:
正确选项:A. I love to program。模板字面量会先求值 ${...} 中的表达式。箭头函数 x => x 接收 'I love' 后原样返回,因此插值结果为 I love,再与后面的文本拼接,输出 I love to program。
131. 依次输出什么?
javascript
const myPromise = () => Promise.resolve('I have resolved!')
function firstFunction() {
myPromise().then(res => console.log(res))
console.log('second')
}
async function secondFunction() {
console.log(await myPromise())
console.log('second')
}
firstFunction()
secondFunction()A. I have resolved!, second, I have resolved!, second B. second, I have resolved!, second, I have resolved! C. I have resolved!, second, second, I have resolved! D. second, I have resolved!, I have resolved!, second
答案:
正确选项:D. second, I have resolved!, I have resolved!, second。firstFunction 先注册 .then 微任务,再同步输出 second。secondFunction 遇到 await 暂停;同步代码清空后,先执行前者的 .then,再恢复 async 函数,依次输出已解析值和 second。
132. 输出什么?
javascript
const one = (false || {} || null)
const two = (null || false || "")
const three = ([] || 0 || true)
console.log(one, two, three)A. false null [] B. null "" true C. {} "" [] D. null null true
答案:
正确选项:C. {} "" []。|| 从左到右返回第一个真值;若全是假值则返回最后一个操作数。空对象 {} 和空数组 [] 都是真值,故 one 为 {}、three 为 [];null || false || '' 全为假值,two 为空字符串。
133. 输出什么?
javascript
function* generatorOne() {
yield ['a', 'b', 'c'];
}
function* generatorTwo() {
yield* ['a', 'b', 'c'];
}
const one = generatorOne()
const two = generatorTwo()
console.log(one.next().value)
console.log(two.next().value)A. a and a B. a and undefined C. ['a', 'b', 'c'] and a D. a and ['a', 'b', 'c']
答案:
正确选项:C. ['a', 'b', 'c'] and a。yield 将整个数组作为一次产出,所以 one.next().value 是数组。yield* 会委托给可迭代对象,逐个产出其元素,因此 two.next().value 是第一个元素 'a'。
134. 输出什么?
javascript
let name = 'Lydia'
function getName() {
console.log(name)
let name = 'Sarah'
}
getName()A. Lydia B. Sarah C. undefined D. ReferenceError
答案:
正确选项:D. ReferenceError。函数内的 let name 在本作用域中遮蔽外层同名变量;它从进入块到声明初始化前处于暂时性死区。console.log(name) 发生在初始化之前,不能回退读取外层的 'Lydia',因此抛出引用错误。
135. 这个函数干了什么?
javascript
JSON.parse()A. Parses JSON to a JavaScript value B. Parses a JavaScript object to JSON C. Parses any JavaScript value to JSON D. Parses JSON to a JavaScript object only
答案:
正确选项:A. Parses JSON to a JavaScript value。JSON.parse 接收合法 JSON 文本并解析成 JavaScript 值,不限于对象,也可以得到数字、字符串、布尔值、数组或 null。传入不符合 JSON 语法的文本会抛出 SyntaxError。
136. 下面代码输出什么?
javascript
const food = ['🍕', '🍫', '🥑', '🍔']
const info = { favoriteFood: food[0] }
info.favoriteFood = '🍝'
console.log(food)A. ['🍕', '🍫', '🥑', '🍔'] B. ['🍝', '🍫', '🥑', '🍔'] C. ['🍝', '🍕', '🍫', '🥑', '🍔'] D. ReferenceError
答案:
正确选项:A. ['🍕', '🍫', '🥑', '🍔']。food[0] 取到的是字符串值,赋给 info.favoriteFood 后只是该原始值的一份拷贝。之后重新赋值的是对象属性,并没有写入 food[0],所以数组保持不变。
137. 哪些方法修改了原数组?
javascript
const emojis = ['✨', '🥑', '😍']
emojis.map(x => x + '✨')
emojis.filter(x => x !== '🥑')
emojis.find(x => x !== '🥑')
emojis.reduce((acc, cur) => acc + '✨')
emojis.slice(1, 2, '✨')
emojis.splice(1, 2, '✨')A. All of them B. map reduce slice splice C. map slice splice D. splice
答案:
正确选项:D. splice。splice 会在原数组上删除、插入或替换元素,本题执行后数组变为 ['✨', '✨']。map、filter、slice 创建新数组,find 返回元素,reduce 返回累计结果,均不修改原数组。
138. 输出什么?
javascript
console.log('❤️' === '❤️')A. true B. false
答案:
正确选项:A. true。两侧是内容完全相同的字符串字面量,严格相等会比较其原始字符串值,因此结果为 true。表情在内部由 Unicode 码元序列表示;只要序列相同,字符串就严格相等。
139. 输出什么?
javascript
const colorConfig = {
red: true,
blue: false,
green: true,
black: true,
yellow: false,
}
const colors = ["pink", "red", "blue"]
console.log(colorConfig.colors[1])A. true B. false C. undefined D. TypeError
答案:
正确选项:D. TypeError。点语法 colorConfig.colors 查找键名恰为 colors 的属性,而对象并没有该属性,结果是 undefined。随后求 undefined[1] 不合法,运行时抛出 TypeError;它不会使用外部变量 colors。
140. 输出什么?
javascript
function compareMembers(person1, person2 = person) {
if (person1 !== person2) {
console.log("Not the same!")
} else {
console.log("They are the same!")
}
}
const person = { name: "Lydia" }
compareMembers(person)A. Not the same! B. They are the same! C. ReferenceError D. SyntaxError
答案:
正确选项:B. They are the same!。调用时 person1 接收 person 的对象引用;未传第二个参数,person2 的默认值也求得同一个 person 引用。对象的 !== 比较身份而非结构,两个引用相同,故进入 else。
141. 结果是什么?
javascript
Promise.resolve(5)A. 5 B. Promise {<pending>: 5} C. Promise {<fulfilled>: 5} D. Error
答案:
正确选项:C. Promise {<fulfilled>: 5}。Promise.resolve(5) 会返回一个 Promise,并以值 5 完成兑现,不会直接返回数字。不同开发者工具对 Promise 的展示文本可能略有差异,但其语义确定为 fulfilled,兑现值为 5。
142. 输出什么?
javascript
const set = new Set()
set.add(1)
set.add("Lydia")
set.add({ name: "Lydia" })
for (let item of set) {
console.log(item + 2)
}A. 3, NaN, NaN B. 3, 7, NaN C. 3, Lydia2, [object Object]2 D. "12", Lydia2, [object Object]2
答案:
正确选项:C. 3, Lydia2, [object Object]2。Set 按插入顺序迭代:1 + 2 为 3;字符串与数字相加发生拼接,得到 Lydia2;普通对象转为默认字符串 [object Object] 后再拼接 2。
143. 输出什么?
javascript
class Person {
constructor(name) {
this.name = name
}
}
const member = new Person("John")
console.log(typeof member)A. "class" B. "function" C. "object" D. "string"
答案:
正确选项:C. "object"。class 定义的是可用 new 调用的构造器;new Person('John') 创建的是该类的实例对象。typeof 对普通对象和类实例均返回字符串 "object",不会返回 "class"。
144. 输出什么?
javascript
// module.js
export default () => "Hello world"
export const name = "Lydia"
// index.js
import * as data from "./module"
console.log(data)A. { default: function default(), name: "Lydia" } B. { default: function default() } C. { default: "Hello world", name: "Lydia" } D. Global object of module.js
答案:
正确选项:A. { default: function default(), name: "Lydia" }。import * as data 创建模块命名空间对象,收集该模块全部导出。默认导出挂在 data.default,且其值仍是函数本身,不会因导入而执行;命名导出以原名称成为 data.name。
145. 输出什么?
javascript
function sum(num1, num2 = num1) {
console.log(num1 + num2)
}
sum(10)A. NaN B. 20 C. ReferenceError D. undefined
答案:
正确选项:B. 20。调用 sum(10) 时,num1 为 10,未传入的 num2 使用默认表达式 num1,也为 10,所以输出 20。默认参数可引用其左侧已初始化的参数;引用右侧参数则可能触发暂时性死区错误。
146. 输出什么?
javascript
console.log("I want pizza"[0])A. """ B. "I" C. SyntaxError D. undefined
答案:
正确选项:B. "I"。字符串可通过方括号按零基索引读取字符,'I want pizza'[0] 取到第一个字符 I。字符串本身不可变,索引越界只会得到 undefined,不会因读取操作而修改原字符串。
147. 哪个选项是将 hasName 设置为 true 的方法(不能将true作为参数传递)?
javascript
function getName(name) {
const hasName = //
}A. !!name B. name C. new Boolean(name) D. name.length
答案:
正确选项:A. !!name。第一次 ! 将值转为布尔值并取反,第二次再取反,最终得到与 name 真值性对应的原始布尔值。直接写 name 可能不是布尔值;new Boolean(name) 返回对象,所有对象在条件判断中都是真值。
148. 下面代码的输出是什么?
javascript
fetch('https://www.website.com/api/user/1')
.then(res => res.json())
.then(res => console.log(res))A. fetch方法的结果 B. 第二次调用fetch方法的结果 C. 前一个.then()中回调方法返回的结果 D. 总是undefined
答案:
正确选项:C. 前一个.then()中回调方法返回的结果。第一个回调返回 res.json() 产生的 Promise;Promise 链会等待它完成,并将其兑现值传给下一个 .then 的参数 res。若前一步抛错或拒绝,后续成功回调不会执行。
149. 输出什么?
javascript
function checkAge(age) {
if (age < 18) {
const message = "Sorry, you're too young."
} else {
const message = "Yay! You're old enough!"
}
return message
}
console.log(checkAge(21))A. "Sorry, you're too young." B. "Yay! You're old enough!" C. ReferenceError D. undefined
答案:
正确选项:C. ReferenceError。两个 message 分别由 const 声明在 if 与 else 的块内,只能在各自花括号内访问。return message 位于块外,函数作用域中没有该绑定,因此执行到此处会抛出 ReferenceError。
150. 输出什么?
javascript
const person = {
name: "Lydia",
age: 21
}
let city = person.city
city = "Amsterdam"
console.log(person)A. { name: "Lydia", age: 21 } B. { name: "Lydia", age: 21, city: "Amsterdam" } C. { name: "Lydia", age: 21, city: undefined } D. "Amsterdam"
答案:
正确选项:A. { name: "Lydia", age: 21 }。读取不存在的 person.city 得到 undefined,赋给变量 city;随后让变量指向字符串 Amsterdam,并未给对象新增属性。只有 person.city = 'Amsterdam' 才会改变对象。
151. 输出什么?
javascript
var status = "😎"
setTimeout(() => {
const status = "😍"
const data = {
status: "🥑",
getStatus() {
return this.status
}
}
console.log(data.getStatus())
console.log(data.getStatus.call(this))
}, 0)A. "🥑" and "😍" B. "🥑" and "😎" C. "😍" and "😎" D. "😎" and "😎"
答案:
正确选项:B. "🥑" and "😎"。普通方法调用 data.getStatus() 中的 this 是 data,故返回其 status。call(this) 显式传入外层回调的 this;在传统浏览器脚本中它是全局对象,var status 成为全局属性,故返回 😎。模块或 Node 环境的外层 this 不同。
152. 输出什么?
javascript
function sayHi(name) {
return `Hi there, ${name}`
}
console.log(sayHi())A. Hi there, B. Hi there, undefined C. Hi there, null D. ReferenceError
答案:
正确选项:B. Hi there, undefined。未提供实参且没有默认参数时,形参 name 的值为 undefined。模板字面量会把插值按字符串形式转换,因此函数返回并输出 Hi there, undefined;它不会自动替换为空字符串或 null。
153. 输出什么?
javascript
const list = [1 + 2, 1 * 2, 1 / 2]
console.log(list)A. ["1 + 2", "1 * 2", "1 / 2"] B. ["12", 2, 0.5] C. [3, 2, 0.5] D. [1, 1, 1]
答案:
正确选项:C. [3, 2, 0.5]。数组字面量中的每个元素都是表达式,会在数组创建时先计算:1 + 2 为 3,1 * 2 为 2,1 / 2 为 0.5。没有引号,所以它们不是保存表达式文本的字符串。
154. 输出什么?
javascript
const myLifeSummedUp = ["☕", "💻", "🍷", "🍫"]
for (let item in myLifeSummedUp) {
console.log(item)
}
for (let item of myLifeSummedUp) {
console.log(item)
}A. 0 1 2 3 and "☕" "💻" "🍷" "🍫" B. "☕" "💻" "🍷" "🍫" and "☕" "💻" "🍷" "🍫" C. "☕" "💻" "🍷" "🍫" and 0 1 2 3 D. 0 1 2 3 and {0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}
答案:
正确选项:A. 0 1 2 3 and "☕" "💻" "🍷" "🍫"。for...in 枚举数组的可枚举属性名,即字符串形式的索引;for...of 消费数组迭代器,得到每个元素值。遍历数组通常应使用 for...of,以避免枚举到附加属性。
155. 输出什么?
javascript
const add = () => {
const cache = {};
return num => {
if (num in cache) {
return `From cache! ${cache[num]}`;
} else {
const result = num + 10;
cache[num] = result;
return `Calculated! ${result}`;
}
};
};
const addFunction = add();
console.log(addFunction(10));
console.log(addFunction(10));
console.log(addFunction(5 * 2));A. Calculated! 20 Calculated! 20 Calculated! 20 B. Calculated! 20 From cache! 20 Calculated! 20 C. Calculated! 20 From cache! 20 From cache! 20 D. Calculated! 20 From cache! 20 Error
答案:
正确选项:C. Calculated! 20 From cache! 20 From cache! 20。闭包让 addFunction 一直持有同一个 cache。首次参数 10 未命中,计算并缓存 20;第二次命中;5 * 2 先计算为同一个键 10,所以第三次也直接读取缓存。
156. 以下是个纯函数么?
javascript
function sum(a, b) {
return a + b;
}A. Yes B. No
答案:
正确选项:A. Yes。sum 的返回值只由参数 a、b 决定:相同输入恒得相同输出,且函数不读取可变外部状态、不执行 I/O,也不修改外部数据,因此符合纯函数定义。前提是传入值的加法行为本身不依赖外部副作用。
157. 输出什么?
javascript
const { name: myName } = { name: "Lydia" };
console.log(name);A. "Lydia" B. "myName" C. undefined D. ReferenceError
答案:
正确选项:D. ReferenceError。对象解构 { name: myName } 的意思是读取右侧 name 属性,并声明局部变量 myName,值为 Lydia。它没有声明名为 name 的变量;随后访问未声明标识符 name 会抛出 ReferenceError。
158. 输出什么?
javascript
const box = { x: 10, y: 20 };
Object.freeze(box);
const shape = box;
shape.x = 100;
console.log(shape)A. { x: 100, y: 20 } B. { x: 10, y: 20 } C. { x: 100 } D. ReferenceError
答案:
正确选项:B. { x: 10, y: 20 }。shape 与 box 指向同一个被冻结对象,Object.freeze 使其自有数据属性不可写,因此非严格模式下赋值失败并保持原值。严格模式下该赋值会抛出 TypeError;冻结是浅层的,不会冻结嵌套对象。
159. 输出什么?
javascript
function addToList(item, list) {
return list.push(item);
}
const result = addToList("apple", ["banana"]);
console.log(result);A. ['apple', 'banana'] B. 2 C. true D. undefined
答案:
正确选项:B. 2。Array.prototype.push 会修改传入数组,在末尾加入 apple 后数组长度从 1 变成 2;它的返回值正是新长度,而不是数组本身。因此 addToList 返回并输出数字 2。
160. 输出什么?
javascript
async function getData() {
return await Promise.resolve("I made it!");
}
const data = getData();
console.log(data);A. "I made it!" B. Promise {<resolved>: "I made it!"} C. Promise {<pending>} D. undefined
答案:
正确选项:C. Promise {<pending>}。async 函数调用总会立即返回 Promise。虽然内部等待的是已兑现的 Promise,await 仍会让后续完成逻辑进入微任务队列,所以当前同步的 console.log(data) 看到的是待完成 Promise;用 await data 或 .then 才能得到字符串。
161. 输出是什么?
javascript
const settings = {
username: "lydiahallie",
level: 19,
health: 90
};
const data = JSON.stringify(settings, ["level", "health"]);
console.log(data);A. "{"level":19, "health":90}" B. "{"username": "lydiahallie"}" C. "["level", "health"]" D. "{"username": "lydiahallie", "level":19, "health":90}"
答案:
正确选项:A。{"level":19, "health":90}。
输出的 JSON 文本为 {"level":19,"health":90}(控制台显示格式可能不同)。JSON.stringify 的第二个参数为数组时充当属性白名单,只有数组列出的可枚举属性会被序列化,且顺序按白名单处理;username 被排除。
162. 输出是什么?
javascript
const person = { name: "Lydia" };
Object.defineProperty(person, "age", { value: 21 });
console.log(person);
console.log(Object.keys(person));A. { name: "Lydia", age: 21 }, ["name", "age"] B. { name: "Lydia", age: 21 }, ["name"] C. { name: "Lydia"}, ["name", "age"] D. { name: "Lydia"}, ["age"]
答案:
正确选项:B。{ name: "Lydia", age: 21 }, ["name"]。
第一次会显示对象的两个自有属性;age 虽存在,但 Object.defineProperty 未指定描述符时,enumerable 默认为 false。Object.keys 只返回自有且可枚举的字符串键,因此只有 name。writable、configurable 也同样默认是 false。
163. 输出是什么?
javascript
const user = { name: "Lydia", age: 21 };
const admin = { admin: true, ...user };
console.log(admin);A. { admin: true, user: { name: "Lydia", age: 21 } } B. { admin: true, name: "Lydia", age: 21 } C. { admin: true, user: ["Lydia", 21] } D. { admin: true }
答案:
正确选项:B。{ admin: true, name: "Lydia", age: 21 }。
对象展开会把 user 的自有可枚举属性复制到新对象,而不是创建名为 user 的嵌套字段。这里得到三个并列属性。它是浅复制:若属性值本身是对象,复制的仍是该对象引用;后出现的同名属性会覆盖前面的值。
164. 输出是什么?
javascript
const numbers = [1, 2, 3, 4, 5];
const [y] = numbers;
console.log(y);A. [[1, 2, 3, 4, 5]] B. [1, 2, 3, 4, 5] C. 1 D. [1]
答案:
正确选项:C。1。
数组解构模式 [y] 会按迭代顺序取第一个元素并赋给 y,不会把整个数组或单元素数组赋给它。因此 console.log(y) 输出数值 1。可用逗号跳过元素,例如 const [, second] = numbers 取得第二项。
165. 输出是什么?
javascript
const name = "Lydia";
age = 21;
console.log(delete name);
console.log(delete age);A. false, true B. "Lydia", 21 C. true, true D. undefined, undefined
答案:
正确选项:A。false, true。
在非严格模式的经典脚本中,const name 是词法绑定,不能被 delete 删除,所以返回 false;未声明就赋值的 age 会成为可配置的全局对象属性,删除成功返回 true。严格模式或 ES module 中未声明赋值会先抛出 ReferenceError。
166. 输出是什么?
javascript
// counter.js
let counter = 10;
export default counter;
// index.js
import myCounter from './counter';
myCounter += 1;
console.log(myCounter);A. 10 B. 11 C. Error D. NaN
答案:
正确选项:C。Error。
ES module 的导入绑定是只读绑定,myCounter += 1 等价于尝试给导入名重新赋值,会在执行时抛出 TypeError,不会输出 11。若要改变导出的状态,应由导出模块提供修改函数,或导出可变对象后修改其属性,而非给导入绑定赋值。
167. 输出是什么?
javascript
const set = new Set([1, 1, 2, 3, 4]);
console.log(set);A. [1, 1, 2, 3, 4] B. [1, 2, 3, 4] C. {1, 1, 2, 3, 4} D. {1, 2, 3, 4}
答案:
正确选项:D。{1, 2, 3, 4}。
Set 保存按 SameValueZero 判等后的唯一值,重复的 1 只保留一次,因此集合含 1、2、3、4。控制台通常以 Set(4) { 1, 2, 3, 4 } 展示;它不是数组,若需数组可使用 [...set]。
168. 下面代码的输出是什么?
javascript
class Dog {
constructor(name) {
this.name = name;
}
}
Dog.prototype.bark = function() {
console.log(`Woof I am ${this.name}`);
};
const pet = new Dog("Mara");
pet.bark();
delete Dog.prototype.bark;
pet.bark();A. "Woof I am Mara", TypeError B. "Woof I am Mara","Woof I am Mara" C. "Woof I am Mara", undefined D. TypeError, TypeError
答案:
正确选项:A。"Woof I am Mara", TypeError。
第一次调用通过原型链找到 Dog.prototype.bark,输出问候语。删除该原型属性后,实例自身没有 bark,查找结果为 undefined;继续以函数形式调用 pet.bark() 会抛出 TypeError: pet.bark is not a function。
169. 输出是什么?
javascript
(() => {
let x = (y = 10);
})();
console.log(typeof x);
console.log(typeof y);A. "undefined", "number" B. "number", "number" C. "object", "number" D. "number", "undefined"
答案:
正确选项:A。"undefined", "number"。
在非严格模式脚本中,y = 10 创建全局属性;x 则用 let 声明在 IIFE 的块级作用域内,外部不可见。对未声明标识符使用 typeof 安全地得到 "undefined"。严格模式或模块中给未声明的 y 赋值会抛出 ReferenceError。
170. 输出是什么?
javascript
function Car() {
this.make = "Lamborghini";
return { make: "Maserati" };
}
const myCar = new Car();
console.log(myCar.make);A. "Lamborghini" B. "Maserati" C. ReferenceError D. TypeError
答案:
正确选项:B。"Maserati"。
使用 new 调用构造函数时,通常返回新建的 this;但构造函数显式返回对象(包括函数)时,该对象会替代实例结果。因此 myCar 是 { make: "Maserati" }。若显式返回的是原始值,则会被忽略,仍返回新创建的实例。
171. 输出什么?
javascript
console.log(String.raw`Hello\nworld`);A. Hello world! B. Hello <br /> world C. Hello\nworld D. Hello\n <br /> world
答案:
正确选项:C。Hello\nworld。
String.raw 是标签模板函数,它按模板的原始片段组装字符串,不把 \n 解释成换行字符。因此控制台显示一个反斜杠、字母 n 与其余文本。它只影响模板字面量的转义处理,不会重新转义插值表达式产生的字符串。
172. 如何能打印出 console.log 语句后注释掉的值?
javascript
function* startGame() {
const answer = yield "Do you love JavaScript?";
if (answer !== "Yes") {
return "Oh wow... Guess we're gone here";
}
return "JavaScript loves you back ❤️";
}
const game = startGame();
console.log(/* 1 */); // Do you love JavaScript?
console.log(/* 2 */); // JavaScript loves you back ❤️A. game.next("Yes").value and game.next().value B. game.next.value("Yes") and game.next.value() C. game.next().value and game.next("Yes").value D. game.next.value() and game.next.value("Yes")
答案:
正确选项:C。game.next().value and game.next("Yes").value。
第一次 next() 启动生成器并停在 yield,其 value 是 Do you love JavaScript?。第二次 next("Yes") 会把该参数作为暂停处 yield 表达式的结果,使 answer 为 Yes,随后函数 return 对应的 value 是 JavaScript loves you back ❤️。
173. 输出什么?
javascript
console.log("🥑" + "💻");A. "🥑💻" B. 257548 C. A string containing their code points D. Error
答案:
正确选项:A。"🥑💻"。
两个操作数都是字符串,+ 执行字符串拼接,输出两个 emoji 连在一起的字符串。JavaScript 字符串以 UTF-16 code unit 存储,某些 emoji 占两个 code unit;但拼接不会把它们转换为码点数,也不会影响其正常显示。
174. 输出什么?
javascript
const name = "Lydia Hallie"
console.log(name.padStart(13))
console.log(name.padStart(2))A. "Lydia Hallie", "Lydia Hallie" B. " Lydia Hallie", " Lydia Hallie" ("[13x whitespace]Lydia Hallie", "[2x whitespace]Lydia Hallie") C. " Lydia Hallie", "Lydia Hallie" ("[1x whitespace]Lydia Hallie", "Lydia Hallie") D. "Lydia Hallie", "Lyd"
答案:
正确选项:C。" Lydia Hallie", "Lydia Hallie" ("[1x whitespace]Lydia Hallie", "Lydia Hallie")。
padStart(targetLength) 的参数是目标总长度,不是要补齐的字符数。Lydia Hallie 长度为 12,目标 13 时左侧补一个默认空格;目标 2 小于当前长度,不截断也不补齐,仍返回原字符串。
175. 输出什么?
javascript
console.log(Number(2) === Number(2))
console.log(Boolean(false) === Boolean(false))
console.log(Symbol('foo') === Symbol('foo'))A. true, true, false B. false, true, false C. true, false, true D. true, true, true
答案:
正确选项:A。true, true, false。
Number(2) 与 Boolean(false) 分别得到相同的原始值,严格相等为 true。每次调用 Symbol('foo') 都会创建全新的唯一符号,参数仅为描述文本,因此两个结果不相等。需要共享同一符号时可使用 Symbol.for('foo')。
176. 输出什么?
javascript
// index.js
console.log('running index.js');
import { sum } from './sum.js';
console.log(sum(1, 2));
// sum.js
console.log('running sum.js');
export const sum = (a, b) => a + b;A. running index.js, running sum.js, 3 B. running sum.js, running index.js, 3 C. running sum.js, 3, running index.js D. running index.js, undefined, running sum.js
答案:
正确选项:B。running sum.js, running index.js, 3。
ESM 会先加载并执行依赖模块,再执行导入它的模块主体,所以先打印 sum.js 的日志;随后 index.js 输出自己的日志并调用已初始化的 sum。import 声明在语义上会提升,不能按其书写位置延后依赖模块的执行。
177. 使用哪个构造函数可以成功继承 Dog 类?
javascript
class Dog {
constructor(name) {
this.name = name;
}
};
class Labrador extends Dog {
// 1
constructor(name, size) {
this.size = size;
}
// 2
constructor(name, size) {
super(name);
this.size = size;
}
// 3
constructor(size) {
super(name);
this.size = size;
}
// 4
constructor(name, size) {
this.name = name;
this.size = size;
}
};A. 1 B. 2 C. 3 D. 4
答案:
正确选项:B。2。
题意应将四段候选构造器分别考虑,实际类中不能同时声明多个 constructor。派生类构造器必须先调用 super(name) 才能访问 this,并将父类需要的 name 传入;随后可设置 this.size。选项 1、4 在 super 前访问 this,选项 3 使用了未定义的 name。
178. 输出什么?
javascript
[1, 2, 3, 4].reduce((x, y) => console.log(x, y));A. 1 2 and 3 3 and 6 4 B. 1 2 and 2 3 and 3 4 C. 1 undefined and 2 undefined and 3 undefined and 4 undefined D. 1 2 and undefined 3 and undefined 4
答案:
正确选项:D。1 2 and undefined 3 and undefined 4。
未提供初始累计值时,reduce 首次以 1 为累计器、2 为当前值。回调只执行 console.log,其返回值为 undefined,于是下一轮累计器变为 undefined;后两次依次打印 undefined 3、undefined 4。最终 reduce 的结果也是 undefined。
179. 输出什么?
javascript
const value = { number: 10 };
const multiply = (x = { ...value }) => {
console.log(x.number *= 2);
};
multiply();
multiply();
multiply(value);
multiply(value);A. 20, 40, 80, 160 B. 20, 40, 20, 40 C. 20, 20, 20, 40 D. NaN, NaN, 20, 40
答案:
正确选项:C。20, 20, 20, 40。
默认参数在每次缺参调用时才求值,{ ...value } 都会新建 { number: 10 },前两次各输出 20,不会相互影响。后两次传入同一个 value 对象,*= 原地修改其 number,故依次为 20、40。
180. 输出是什么?
javascript
let num = 10;
const increaseNumber = () => num++;
const increasePassedNumber = number => number++;
const num1 = increaseNumber();
const num2 = increasePassedNumber(num1);
console.log(num1);
console.log(num2);A. 10, 10 B. 10, 11 C. 11, 11 D. 11, 12
答案:
正确选项:A。10, 10。
后缀自增 num++ 先产生自增前的值,再完成加一。increaseNumber() 返回 10,同时外部 num 变为 11;传入 num1 的是数值 10,形参 number++ 同样先返回 10。数值为原始值,形参自增不会改动 num1。
181. 输出是什么?
javascript
function greeting() {
throw "Hello world!";
}
function sayHi() {
try {
const data = greeting();
console.log("It worked!", data);
} catch (e) {
console.log("Oh no an error:", e);
}
}
sayHi();A. "It worked! Hello world!" B. "Oh no an error: undefined C. SyntaxError: can only throw Error objects D. "Oh no an error: Hello world!
答案:
正确选项:D。"Oh no an error: Hello world!。
greeting 抛出的值是字符串 Hello world!,JavaScript 的 throw 可抛出任意值,并不要求是 Error 对象。控制流立即跳到 catch,e 接收该字符串,因此日志的两个参数组合显示为 Oh no an error: Hello world!。实践中仍建议抛出 Error 以保留堆栈。
182. 输出的是什么?
javascript
function getInfo(member, year) {
member.name = "Lydia";
year = "1998";
}
const person = { name: "Sarah" };
const birthYear = "1997";
getInfo(person, birthYear);
console.log(person, birthYear);A. { name: "Lydia" }, "1997" B. { name: "Sarah" }, "1998" C. { name: "Lydia" }, "1998" D. { name: "Sarah" }, "1997"
答案:
正确选项:A。{ name: "Lydia" }, "1997"。
JavaScript 参数一律按值传递;对象参数传递的是对象引用这个值。member 与 person 持有同一对象,修改其 name 会反映到外部;year = '1998' 只是让形参改指向新字符串,不会改变外层的 birthYear。
183. 输出是什么?
javascript
[1, 2, 3].map(num => {
if (typeof num === "number") return;
return num * 2;
});A. [] B. [null, null, null] C. [undefined, undefined, undefined] D. [ 3 x empty ]
答案:
正确选项:C。[undefined, undefined, undefined]。
每个数组元素都是 number,条件恒成立,裸 return 返回 undefined。map 会为原数组每个已存在元素创建对应位置并写入回调返回值,所以得到三个显式的 undefined,不是空数组、null 数组,也不是稀疏数组空槽。
184. num的值是什么?
javascript
const num = parseInt("7*6", 10);A. 42 B. "42" C. 7 D. NaN
答案:
正确选项:C。7。
parseInt 按指定的十进制从字符串起始处连续读取合法数字,遇到不合法的 * 就停止,已读取的 7 转为数值返回。它不会计算算术表达式;若首个非空字符就不合法才返回 NaN。解析完整数值字符串时优先考虑 Number。
185. 输出是什么?
javascript
console.log(3 + 4 + "5");A. "345" B. "75" C. 12 D. "12"
答案:
正确选项:B。"75"。
+ 同级运算符按从左到右结合:先计算数值加法 3 + 4 得到 7;接着 7 + '5' 中存在字符串操作数,数值被转成字符串并拼接,结果为字符串 "75"。若写成 3 + '4' + 5,结果则会是 "345"。
186. 输出是什么?
javascript
const person = {
name: "Lydia",
age: 21
};
for (const item in person) {
console.log(item);
}A. { name: "Lydia" }, { age: 21 } B. "name", "age" C. "Lydia", 21 D. ["name", "Lydia"], ["age", 21]
答案:
正确选项:B。"name", "age"。
for...in 遍历对象可枚举的字符串属性键,因此每轮 item 依次是 name、age,而不是属性值或键值对。它还会遍历原型链上的可枚举属性;只需要对象自身键时,通常用 Object.keys(person) 或配合 Object.hasOwn 过滤。
187. 输出是什么?
javascript
let person = { name: "Lydia" };
const members = [person];
person = null;
console.log(members);A. null B. [null] C. [{}] D. [{ name: "Lydia" }]
答案:
正确选项:D。[{ name: "Lydia" }]。
创建数组时,members[0] 保存了对原对象的引用。之后 person = null 只是把变量 person 重新绑定为 null,没有修改对象,也没有修改数组元素,因此数组仍能访问原对象。只有把 members[0] 改为 null 才会改变该数组内容。
188. 返回值是什么?
javascript
const firstPromise = new Promise((res, rej) => {
setTimeout(res, 500, "one");
});
const secondPromise = new Promise((res, rej) => {
setTimeout(res, 100, "two");
});
Promise.race([firstPromise, secondPromise]).then(res => console.log(res));A. "one" B. "two" C. "two" "one" D. "one" "two"
答案:
正确选项:B。"two"。
Promise.race 返回第一个敲定(fulfilled 或 rejected)的输入 Promise 的结果。第二个定时器在约 100ms 后 fulfilled,早于第一个约 500ms 的结果,所以 then 接收到并打印 two。其余 Promise 不会被自动取消,仍会在后台继续完成。
189. 输出是什么?
javascript
function* generator(i) {
yield i;
yield i * 2;
}
const gen = generator(10);
console.log(gen.next().value);
console.log(gen.next().value);A. [0, 10], [10, 20] B. 20, 20 C. 10, 20 D. 0, 10 and 10, 20
答案:
正确选项:C。10, 20。
调用生成器函数只得到迭代器,不立即执行函数体。第一次 gen.next() 运行至第一个 yield i 并给出 10;第二次从暂停处继续,到 yield i * 2 并给出 20。每次 next() 返回的是 { value, done },代码读取其中的 value。
190. 输出是什么?
javascript
[...'Lydia']A. ["L", "y", "d", "i", "a"] B. ["Lydia"] C. [[], "Lydia"] D. [["L", "y", "d", "i", "a"]]
答案:
正确选项:A。["L", "y", "d", "i", "a"]。
字符串是可迭代对象,数组字面量中的展开运算符会消费它的迭代器,并将每次迭代得到的字符放入新数组。因此字符串 Lydia 被拆成五个字符。对 Unicode 代理对字符,字符串迭代器会按 Unicode 码点迭代,优于简单按索引切分。
191. setInterval 方法的返回值是什么?
javascript
setInterval(() => console.log('Hi'), 1000)A. 一个唯一的id B. 该方法指定的毫秒数 C. 传递的函数 D. undefined
答案:
正确选项:A。一个唯一的id。
setInterval 返回用于标识该重复定时任务的句柄,可传给 clearInterval(handle) 停止后续触发。浏览器通常返回数字,Node.js 常返回 Timeout 对象,因此不应依赖其具体类型或数值。回调至少在给定延迟后才会执行,实际间隔还受事件循环影响。
192. 输出是什么?
javascript
!!null
!!''
!!1A. false true false B. false false true C. false true true D. true true false
答案:
正确选项:B。false false true。
双重逻辑非 !! 会把值规范为布尔值:null 和空字符串 '' 都是 falsy,结果为 false;数值 1 是 truthy,结果为 true。注意 0、NaN、undefined 也为 falsy,而空数组和空对象在 JavaScript 中仍是 truthy。
193. 下面代码的输出是什么?
javascript
[[0, 1], [2, 3]].reduce(
(acc, cur) => {
return acc.concat(cur)
},
[1, 2]
)A. [0, 1, 2, 3, 1, 2] B. [6, 1, 2] C. [1, 2, 0, 1, 2, 3] D. [1, 2, 6]
答案:
正确选项:C. [1, 2, 0, 1, 2, 3]。reduce 的第二个参数 [1, 2] 是初始累加器,第一次把它与 [0, 1] 用 concat 拼接,得到 [1, 2, 0, 1];第二次再拼接 [2, 3],得到最终数组。concat 返回新数组,不会修改原数组或累加器引用。
194. 输出是什么?
javascript
(() => {
let x, y
try {
throw new Error()
} catch (x) {
(x = 1), (y = 2)
console.log(x)
}
console.log(x)
console.log(y)
})()A. 1 undefined 2 B. undefined undefined undefined C. 1 1 2 D. 1 undefined undefined
答案:
正确选项:A. 1 undefined 2。实际依次输出 1、undefined、2。catch (x) 声明的参数仅在 catch 块的词法作用域内有效,它遮蔽了外层的 let x;块内赋值不会影响外层 x。y 没有同名遮蔽,给它赋值后外层变量值变为 2。
195. 输出是什么?
javascript
const numbers = [1, 2, 3]
numbers[10] = 11
console.log(numbers)A. [1, 2, 3, 7 x null, 11] B. [1, 2, 3, 11] C. [1, 2, 3, 7 x empty, 11] D. SyntaxError
答案:
正确选项:C. [1, 2, 3, 7 x empty, 11]。给下标 10 赋值会把数组长度扩展为 11,下标 3 到 9 形成 7 个稀疏空位,因此控制台通常以 empty 表示。空位不是已存入的 undefined:它没有自有元素属性,部分数组方法会跳过它;控制台文案可能随运行时略有不同。
196. 输出是什么?
javascript
console.log(typeof typeof 1)A. "number" B. "string" C. "object" D. "undefined"
答案:
正确选项:B. "string"。表达式按从右向左的嵌套结果理解:typeof 1 得到字符串 "number",再对这个字符串执行 typeof,结果便是 "string"。typeof 的返回值始终是描述类型名称的字符串,而不是类型对象本身。
197. 下面哪些值是 falsy?
javascript
0
new Number(0)
('')
(' ')
new Boolean(false)
undefinedA. 0, '', undefined B. 0, new Number(0), '', new Boolean(false), undefined C. 0, '', new Boolean(false), undefined D. All of them are falsy
答案:
正确选项:A. 0, '', undefined。在给出的值中,数值 0、空字符串和 undefined 转布尔值为 false。' ' 含有空格字符,所以是真值;new Number(0) 与 new Boolean(false) 创建的是对象,对象即使包装的原始值为假也是真值。另有 false、null、NaN 等 falsy 值。
198. 输出是什么?
javascript
function sayHi() {
return (() => 0)()
}
console.log(typeof sayHi());A. "object" B. "number" C. "function" D. "undefined"
答案:
正确选项:B. "number"。sayHi 调用并返回内部箭头函数的结果;该立即执行函数返回数值 0。因此 typeof sayHi() 等价于 typeof 0,输出 "number"。这里检测的是函数调用的返回值,而不是 sayHi 函数对象;后者的 typeof 才会是 "function"。
199. 下面会输出什么?
javascript
const person = { name: 'Lydia' }
function sayHi(age) {
console.log(`${this.name} is ${age}`)
}
sayHi.call(person, 21)
sayHi.bind(person, 21)A. undefined is 21 Lydia is 21 B. function function C. Lydia is 21 Lydia is 21 D. Lydia is 21 function
答案:
正确选项:D. Lydia is 21 function。sayHi.call(person, 21) 会立刻以 person 作为 this 执行,所以输出 Lydia is 21。bind 不执行原函数,只返回一个已绑定 this 和预置参数的新函数;第二行表达式的值是函数,且代码没有调用它,因此没有第二次文本输出。
200. 输出是什么?
javascript
const foo = () => console.log('First')
const bar = () => setTimeout(() => console.log('Second'))
const baz = () => console.log('Third')
bar()
foo()
baz()A. First Second Third B. First Third Second C. Second First Third D. Second Third First
答案:
正确选项:B. First Third Second。bar() 只注册 setTimeout 回调,随后主线程继续同步执行 foo()、baz(),依次输出 First 与 Third。当前调用栈清空后,计时器到期的回调才作为任务进入队列并输出 Second。即使省略延迟时间,也不是同步调用。
201. 输出是什么?
javascript
const a = {}
const b = { key: 'b' }
const c = { key: 'c' }
a[b] = 123
a[c] = 456
console.log(a[b])A. 123 B. 456 C. undefined D. ReferenceError
答案:
正确选项:B. 456。普通对象的属性键只能是字符串或 Symbol;以对象作为方括号键时会先转成属性键。b 和 c 默认都会转成相同的字符串 "[object Object]",所以第二次赋值覆盖第一次:先写入 123,再写入 456。若需按对象身份区分键,应使用 Map。
202. 输出是什么?
javascript
String.prototype.giveLydiaPizza = () => {
return 'Just give Lydia pizza already!'
}
const name = 'Lydia'
name.giveLydiaPizza()A. "Just give Lydia pizza already!" B. TypeError: not a function C. SyntaxError D. undefined
答案:
正确选项:A. "Just give Lydia pizza already!"。代码给 String.prototype 新增了方法。调用 name.giveLydiaPizza() 时,原始字符串会临时装箱为 String 对象并沿原型链找到该方法,返回这段字符串。实际项目不建议修改内置原型:它会污染全局行为,并可能与框架或未来标准发生冲突。