八股文-JavaScript(第一天)

1.不会冒泡的事件有哪些?

答:focus、blur、load、unload、stop、readystatechange、scroll

以下是一些不会冒泡的事件列表:

  • focus:元素获得焦点时触发,不会冒泡。
  • blur:元素失去焦点时触发,不会冒泡。
  • load:资源加载完成时触发,不会冒泡。
  • unload:资源卸载时触发,不会冒泡。
  • stop:某些媒体播放停止时触发,不会冒泡。
  • readystatechange:文档或元素状态变化时触发,不会冒泡。
  • scroll:元素滚动时触发,不会冒泡。

这些事件的特点是仅作用于目标元素本身,不会向上传播到父元素。

2.mouseEnter与mouseOver有什么区别?

答:mouseEnter只会在鼠标首次移入时触发函数,不会冒泡

mouseOver每次进入元素或子元素的边界时触发,包括从子元素移动到父元素,会冒泡

3.MessageChannel是什么?使用场景?

答:是一个JavaScript的API,可以用于浏览器中不同的标签页之间的通信,通过端口传递消息

核心特点:

1.可以双向通信:通道两端均可发送和接收消息

2.结构化克隆算法,支持传输复杂的对象,但是函数、DOM节点的那个不可克隆类型会被忽略

3.跨上下文兼容性

使用场景:

1.跨标签页通信

2.主线程与Web Workr通信

3.微前端架构

4.async、await原理?

答:他是异步操作的语法糖,为了解决回调函数的回调地域问题,引入的promise 写成了链式调用。

async 函数本质上返回一个 Promise 对象。当函数内部执行到 await 时,会暂停当前函数的执行,等待 Promise 解析完成。如果 await 后的表达式是一个非 Promise 值,它会自动被包装成 Promise.resolve。

5.Proxy能监听到对象中的对象的引入吗?

答:可以,当使用Proxy包装对象时,可以为这个对象中的任何属性设置拦截器,包括属性值是对象的情况。但是默认情况下不能自动进行自动深度监听嵌套,需要手动处理

6.如何能让var [a,b] = {a:1,b:1}解构赋值成功?

javascript 复制代码
const obj = {a: 1, b: 1};
const arr = Object.values(obj); // 转换为 [1, 1]
const [a, b] = arr;
console.log(a, b); // 输出 1, 1
 

可以这样转,但是需要注意

  • 数组解构要求右侧必须是可迭代对象
  • 解构失败时变量值为 undefined,除非设置默认值

7.下面这段代码会输出什么?

javascript 复制代码
foo();
var foo;
function foo()
{
   console.log(1); 
}
foo = function(){
    console.log(2)
}

输出1,函数会在最前面,然后在是变量定义,但是一般来讲,函数声明优先级高于变量声明。

  • 函数表达式(如 foo = function(){...})在赋值时才生效,不会提升函数体。

8.描述下面代码的执行结果

javascript 复制代码
foo(typeof a);
function foo(){
    console.log(this);
    console.log(p)
    console.log(typeof b)
}
let b = 0;
  • 变量 atypeof a
    a 未声明,但 typeof a 不会报错,而是返回字符串 "undefined"。因此 foo 的参数是 "undefined",但函数内部未使用参数。

  • 函数与变量提升
    function foo 被提升到作用域顶部,因此可以在定义前调用。
    let b = 0 不会被提升,在 foo 内部访问 typeof b 时,由于暂时性死区(TDZ),b 被视为未声明,返回 "undefined"。但实际不会执行到此步。

  • 错误中断
    console.log(p) 的引用错误会阻止后续的 console.log(typeof b) 执行。

9.什么是作用域链?

作用域链由执行上下文的变量对象(VO/AO)和外部环境的引用构成。每个函数在被调用时都会创建一个新的执行上下文,并将其变量对象添加到作用域链的前端。

  • 全局作用域:位于作用域链的最外层,包含全局变量和函数。
  • 局部作用域:函数内部的作用域,可以访问自身变量和外部作用域的变量。

10.bind、call、apply有何区别,如何实现一个bind?

bind

创建一个新函数,将指定的this值和参数绑定到原函数,调用时需手动执行。

语法:func.bind(thisArg, arg1, arg2...)

call

立即调用函数,显式指定this值和逐个传递的参数。

语法:func.call(thisArg, arg1, arg2...)

apply

立即调用函数,显式指定this值,参数以数组形式传递。

语法:func.apply(thisArg, [argsArray])

核心区别

  • 执行时机bind返回绑定后的函数,不立即执行;call/apply立即执行。

  • 参数形式call接收参数列表,apply接收参数数组。

    javascript 复制代码
    Function.prototype.myBind = function(context, ...bindArgs) {
      const originalFunc = this;
      return function(...callArgs) {
        return originalFunc.apply(context, [...bindArgs, ...callArgs]);
      };
    };
    
    // 示例
    const obj = { value: 42 };
    function logValue(a, b) {
      console.log(this.value + a + b);
    }
    const boundFunc = logValue.myBind(obj, 1);
    boundFunc(2); // 输出: 45 (42 + 1 + 2)
     

11.common.js和es6中模块引入的区别?

1.common.js是nodejs默认采用的模块系统,主要用于服务器端开发,模块引入使用require和module.exports语法,模块同步加载,首次加载后会缓存结果,后续调用直接返回缓存。适用于文件系统环境

2.es6

ES6 模块是 ECMAScript 标准的一部分,支持静态分析,适用于浏览器和现代 Node.js 环境。使用 importexport 语法。

模块在编译时静态解析,支持异步加载(如动态 import()),适合浏览器环境。

12.说说 vue3 中的响应式设计原理?

答:是基于Proxy和ReflectAPI实现的,是通过ref、reactive的那个函数实现的数据劫持,依赖收集以及触发更新。

Proxy 代理对象 通过 Proxy 拦截对象的读取(get)和修改(set)操作,在访问属性时收集依赖,在修改属性时触发更新

javascript 复制代码
const proxy = new Proxy(target, {
  get(target, key, receiver) {
    track(target, key) // 依赖收集
    return Reflect.get(target, key, receiver)
  },
  set(target, key, value, receiver) {
    Reflect.set(target, key, value, receiver)
    trigger(target, key) // 触发更新
  }
})
 

reactive() 处理对象类型数据,返回 Proxy 代理对象

ref() 处理基本类型数据(如 numberstring),通过 .value 访问

effect() 用于创建响应式副作用,Vue 的组件渲染本质上是一个 effect

13.script标签放在header里和放在body底部里有什么区别?

答:

<script>标签放在<head>中会导致浏览器在解析HTML时立即下载并执行脚本,这会阻塞DOM的构建和页面渲染。若脚本较大或网络延迟较高,用户会看到较长时间的白屏。

放在<body>底部(闭合标签</body>之前)时,脚本会在DOM树构建完成后执行,用户能更快看到页面内容,适合非关键性脚本。

14.下面代码中,点击"+3"按钮后,age 的值是什么?

javascript 复制代码
import {usestate }from 'react'
export default function counter(){
const [age,setAge]= useState(42);
function increment(){
setAge(age + 1);
return
<h1>Your age:{age}</h1>
<button onclick={()=>{
increment();
increment();
increment();
}}>+3</button>
</>
);

点击后 age 的值

点击"+3"按钮后,age 的值会是 43 而非预期的 45。这与 React 的状态更新机制有关。

原因分析

React 的 setState 在事件处理函数中是批量处理的。当连续调用同一个状态的更新函数时,React 会将它们合并:

js 复制代码
function increment() {
  setAge(age + 1); // 所有调用都基于初始值 42
}
 

三次 increment() 调用相当于:

js 复制代码
setAge(42 + 1);
setAge(42 + 1);
setAge(42 + 1);
 

如需实现+3效果,应采用函数式更新:

jsx 复制代码
function increment() {
  setAge(a => a + 1); // 基于最新状态更新
}
 

15.Vue中,created和mounted两个钩子之间调用时间差值受什么影响?

答:

网络请求与异步操作

若在created中发起异步请求(如API调用),响应时间会直接影响两个钩子之间的时间差。异步操作未完成时,mounted可能已触发,导致差值增大。

DOM渲染复杂度

页面DOM结构复杂度影响渲染速度。组件模板越复杂,Vue生成虚拟DOM并挂载到真实DOM的时间越长,导致createdmounted间隔增加。

组件嵌套深度

嵌套层级深的组件需要更多时间完成子组件的初始化。父组件的mounted需等待所有子组件挂载完成,这会延长与created的时间差。

浏览器性能与资源加载

浏览器性能较差或存在未加载完成的资源(如图片、样式文件)时,DOM渲染会被阻塞,导致mounted延迟执行,差值扩大。

动态组件与懒加载

使用动态组件(如<component :is>)或路由懒加载时,组件资源的加载时间会被计入渲染流程,从而延长两个钩子之间的间隔。

16.vue中,推荐在哪个生命周期发起请求?

答:

  • 关键数据优先在 created 中加载以减少白屏时间。
  • 非关键或 DOM 依赖的操作可放在 mounted
  • 对于复杂逻辑,结合 watch 或路由守卫处理动态数据更新。

17.为什么Node在使Hes module时必须加上文件扩展名?

答:

模块解析机制差异 ES modules 是 ECMAScript 标准的一部分,设计上要求明确的文件路径。Node.js 实现时遵循了这一规范,避免隐式文件扩展名解析带来的歧义。CommonJS 允许省略扩展名,因为它是 Node.js 特有的非标准实现。

浏览器兼容性对齐 浏览器在加载 ES modules 时要求完整的 URL(包括扩展名)。Node.js 的 ES modules 设计有意与浏览器行为保持一致,减少开发者在不同环境下的认知差异。

性能优化考虑 显式扩展名减少了文件系统查找次数。CommonJS 会尝试匹配 .js.json.node 等扩展名,而 ES modules 直接通过完整路径定位文件,提升加载速度。

18.package.json 文件中的 devDependencies 和 dependencies 对象有什么区

别?

答:devDependencies 包含开发阶段的依赖项,不会随着项目发布到生产环境。安装时使用 --save-dev-D 标志:

dependencies项目运行时必须的依赖项,会随项目一同发布到生产环境。安装时默认使用 --save-S 标志(可省略):

19. React Portals 有什么用?

答:React Portals 提供了一种将子节点渲染到父组件 DOM 层次结构之外的 DOM 节点的解决方案

1.解决模态框和弹窗的层级问题

2.脱离当前 DOM 结构

20.react 和 react-dom 是什么关系?

答:React 是一个用于构建用户界面的 JavaScript 库,专注于组件化开发和状态管理。React-DOM 是 React 的官方渲染器,负责将 React 组件渲染到浏览器 DOM 中。

React 提供核心逻辑和组件化能力,包括虚拟 DOM、状态管理、生命周期等。React-DOM 提供与浏览器 DOM 交互的具体实现,将 React 的虚拟 DOM 转换为真实 DOM。

在 Web 开发中,React 和 React-DOM 通常一起使用。React 负责组件逻辑,React-DOM 负责渲染到网页。对于非浏览器环境(如 React Native),会使用其他渲染器替代 React-DOM。

注意:React 和 React-DOM 需要保持版本一致。不同版本的 API 可能有差异,版本不匹配可能导致兼容性问题。安装时应确保两者版本号相同

相关推荐
Thomas_YXQ2 小时前
Unity3D的委托和事件的用法详解
java·开发语言
政采云技术2 小时前
深入理解 Webpack5:从打包到热更新原理
前端·webpack
T___T2 小时前
从入门到实践:React Hooks 之 useState 与 useEffect 核心解析
前端·react.js·面试
山有木兮木有枝_2 小时前
当你的leader问你0.1+0.2=?
前端
编程小Y2 小时前
Bash 替换机制
开发语言·chrome·bash
我要学脑机2 小时前
一个图谱映射到功能网络yeo7或17的解决方案
开发语言·网络·php
前端程序猿之路2 小时前
模型应用开发的基础工具与原理之Web 框架
前端·python·语言模型·学习方法·web·ai编程·改行学it
名字被你们想完了2 小时前
Flutter 实现一个容器内部元素可平移、缩放和旋转等功能(八)
前端·flutter
听风说图2 小时前
Figma画布协议揭秘:组件系统的设计哲学
前端