你的前端技术是否能通过这些高频面试题?

news2024/11/15 7:30:13

在这里插入图片描述

文章目录

  • 1.储存了某个数据到 localStorage,立即进行 localStorage.getItem,能否取到值?
  • 2.实现异步的方式有几种
  • 3.异步不阻塞
  • 4.选择 div 的第二个子元素
  • 5.display: none 和 visibility: hidden 的区别
  • 6.如果想要让一个元素的宽高包含元素的 boder 和 padding
  • 7.const, let 和 var 有什么区别
  • 8.处理 any 类型,如何避免 any
  • 9.举几个常用的 Hook,并且解释一下作用
  • 10.List, Map, Set 有什么区别?

1.储存了某个数据到 localStorage,立即进行 localStorage.getItem,能否取到值?

如果您已经成功将数据存储到 localStorage 中,调用 localStorage.getItem 方法可以立即取出对应的值。举个例子,如果您使用以下代码将一个键值对存储到 localStorage 中:

localStorage.setItem('key', 'value');

那么您可以立即使用以下代码从 localStorage 中获取该键对应的值:

const value = localStorage.getItem('key');
console.log(value);  // 输出 "value"

当然,在某些情况下(例如浏览器隐私模式下或者被禁用了 localStorage 功能等),调用 localStorage.getItem 方法可能无法取到值,请确保您的代码在适当的环境下运行。

2.实现异步的方式有几种

在 JavaScript 中,实现异步的方式有以下几种:

1. 回调函数:在函数内部执行异步操作,然后将异步操作的结果作为参数传递到回调函数中。

function doAsyncTask(data, callback) {
  setTimeout(function() {
    const result = data.toUpperCase();
    callback(result);
  }, 1000);
}

doAsyncTask('hello', function(result) {
  console.log(result); // 'HELLO'
});

回调函数的方式非常常见,但也很容易导致回调地狱和可读性问题。

2. Promise:Promise 为一种更加优雅的异步模式,可以更好地解决回调地狱和可读性问题。

function doAsyncTask(data) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      if (data) {
        const result = data.toUpperCase();
        resolve(result);
      } else {
        reject(new Error('Data is null'));
      }
    }, 1000);
  });
}

doAsyncTask('hello')
  .then(function(result) {
    console.log(result); // 'HELLO'
  })
  .catch(function(error) {
    console.error(error);
  });

3. Async/Await:Async/Await 是 ES2017 的新增语法,它是基于 Promise 的封装,可以更加方便地编写异步代码,解决了 Promise 的then方法链式调用的可读性问题。

async function main() {
  try {
    const result = await doAsyncTask('hello');
    console.log(result); // 'HELLO'
  } catch (error) {
    console.error(error);
  }
}

main();

上述三种方式都可以实现异步,具有不同的特点。回调函数是传统方式, Promise 可以更好的处理 Promise 的嵌套和 then 方法的链式调用问题,Async/Await 则提供了更加优雅的方式,在可读性和维护性方面更加友好。

3.异步不阻塞

异步不阻塞是指当一个异步操作被触发时,它会在后台执行(非主线程中执行),在等待操作完成的同时,主线程可以继续执行其他代码,不会被该异步操作所阻塞。

在 JavaScript 中,异步操作通常使用回调函数、Promise 对象或 async/await 语法来实现。例如,以下代码使用 Promise 对象实现了一个异步操作:

function asyncOperation() {
  return new Promise((resolve, reject) => {
    // 模拟一个异步操作
    setTimeout(() => {
      resolve('异步操作完成');
    }, 1000);
  });
}

console.log('异步操作执行前');

asyncOperation().then((result) => {
  console.log(result);
});

console.log('异步操作执行后');

在上面的示例中,当程序执行到 console.log('异步操作执行前') 时会首先输出该语句,然后立即执行下一行代码 asyncOperation(),该函数返回一个 Promise 对象,这个 Promise 对象被 resolve 后继续执行后面的 then 方法中的回调函数,并输出 '异步操作完成',最后输出 '异步操作执行后'

因此,异步操作的执行不会阻塞主线程的代码,而是后台执行,等待异步操作完成后再去执行相应的回调函数或 Promise 对象的 then 方法中的回调函数。

4.选择 div 的第二个子元素

您可以使用以下 CSS 选择器来选择 div 的第二个子元素:

div:nth-child(2)

在这个选择器中,div 表示选择所有的 div 元素,nth-child(2) 表示选择 div 的第二个子元素。注意,这里的计数不是从 0 开始的,而是从 1 开始的。

以下是一个示例,展示如何使用此选择器选择 div 的第二个子元素,并设置其背景颜色为红色:

<div>
  <p>第一个子元素</p>
  <p>第二个子元素</p>
  <p>第三个子元素</p>
</div>
div:nth-child(2) {
  background-color: red;
}

在上面的示例中,第二个 <p> 元素的背景颜色将变为红色。

5.display: none 和 visibility: hidden 的区别

display: nonevisibility: hidden 二者都可以用来隐藏元素,但它们的实现方式和效果略有不同:

  1. display: none:该样式会将元素完全隐藏,不占据页面布局,也不会响应用户事件(例如点击、鼠标移入等)。设置元素的 display 属性为 none 会将该元素从渲染树中移除,因此该元素及其所有后代元素在页面上不会被显示,且不占用绘制资源和空间。
  2. visibility: hidden:该样式会使元素隐藏,但在页面布局中仍占据空间,并继续响应用户事件。而这种方式只是让元素不可见,但是元素仍会被渲染出来,只不过不可见罢了。以至于它仍然对渲染树和布局模型可能产生影响。

下面是一个示例,展示 display: nonevisibility: hidden 的效果差异:

<div>
  <p>文本内容</p>
  <button>按钮</button>
</div>
div {
  width: 200px;
  height: 200px;
  background-color: #ccc;
  display: flex;
  justify-content: center;
}

p {
  font-size: 24px;
  display: none;
}

button {
  font-size: 18px;
  visibility: hidden;
}

在上面的示例中,pbutton 元素分别被设置为 display: nonevisibility: hidden。当浏览器渲染页面时,p 元素被完全移除了,因此页面上不会看到任何文本内容,而 button 元素虽然占据了页面的空间,但是在页面上不可见,以至于它不会响应用户事件,即使用户点击了该区域。

因此,一般情况下,如果需要完全删除某个元素,不想再让它占据空间或影响其他元素,应该使用 display: none,如果只需要将元素隐藏起来,但仍占据空间并继续响应事件,可以使用 visibility: hidden

6.如果想要让一个元素的宽高包含元素的 boder 和 padding

| < - a - > | b: 50px | < - c - > |,a 和 c 等比填充,用 flex 怎么实现;如果我想让它变成垂直方向,怎么做?

可以使用 box-sizing 属性来解决这个问题。将 box-sizing 属性设置为 border-box 可以使元素的宽度和高度包括了 padding 和 border,而不用再考虑它们的影响。

对于您的要求,假设父元素宽度已经确定,如果要让其中的子元素宽度和高度等比例填充,可以将父元素的 display 属性设置为 flex,并在子元素上使用一个占比为 1 的 Flexbox 布局框架。然后将子元素的 box-sizing 属性设置为 border-box 即可。示例代码如下:

<div class="parent">
  <div class="child"></div>
</div>
.parent {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 200px;
  height: 200px;
  border: 10px solid #ccc;
  padding: 20px;
}

.child {
  flex: 1;
  box-sizing: border-box;
  background: #f00;
}

在上面的示例中,父元素 .parent 的宽度为 200px,高度为 200px,同时设置了边框和内边距。子元素 .child 使用了 Flexbox 布局的占比为 1 的框架,在 box-sizing 属性设置为 border-box 之后,它的实际宽度和高度就会考虑到父元素的边框和内边距。

如果希望这个布局框架垂直方向上往下延伸,只需将 .parent.child 元素都添加上 flex-direction: column 属性,示例代码如下:

.parent {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 200px;
  height: 200px;
  border: 10px solid #ccc;
  padding: 20px;
  flex-direction: column;
}

.child {
  flex: 1;
  box-sizing: border-box;
  background: #f00;
}

7.const, let 和 var 有什么区别

constletvar 是用于声明变量的关键字,它们有以下区别:

  1. const:用于声明一个只读的常量,一旦被声明,它的值不能被修改。但是,如果是引用类型(例如对象、数组)时,引用本身是不能被修改的,但对象或数组中的属性或元素是可以修改的。
  2. let:用于声明一个块级作用域的变量,它的作用域仅限于当前的代码块,不会被提升到函数作用域或全局作用域。
  3. var:用于声明一个函数作用域或全局作用域的变量,它的作用域不受代码块的限制,而是在整个函数或全局范围内都可以访问。

下面是一个示例,展示 constletvar 的差异:

function test() {
  var a = 10;
  let b = 20;
  const c = 30;
  if (true) {
    var a = 50;
    let b = 60;
    const c = 70;
    console.log(a, b, c);
  }
  console.log(a, b, c);
}

test(); // 输出:50 60 70,10 20 30

在上面的示例中,使用 var 声明的变量 a 在代码块内部被重新赋值,同时在代码块外部也被重新赋值。这是因为 var 声明的变量的作用域不仅局限于代码块内部,而是在整个函数作用域范围内有效。而使用 letconst 声明的变量 bc 只在代码块内部有效,并且代码块内的重新赋值不会影响到代码块外部的变量。

因此,对于变量的声明,应该优先使用 constlet,避免使用 varconst 用于声明不会被重新赋值的常量(例如数学常数、常量字符串等),使用 let 声明变量并且在需要重新赋值的情况下使用它。如果您需要使用一个变量,但不希望它在函数或全局范围内被访问,请使用 let

8.处理 any 类型,如何避免 any

any 是 TypeScript 中的一种通用类型,用于表示任何类型的值。由于它是一种非常宽泛的类型,无法提供静态类型检查的保障,使用 any 类型会增加代码出错的风险,并且对于代码可读性和可维护性也不利。

为了更好地利用 TypeScript 的静态类型检查,应该尽可能避免使用 any 类型。下面是一些方法可以帮助您减少在代码中使用 any

  1. 尽可能地使用具体的类型:在代码中使用具体的类型可以帮助您充分利用 TypeScript 的类型检查功能,这有助于在开发过程中尽早发现潜在的类型转换错误等问题。例如,尽量使用字符串、数字、布尔等具体类型,而不是将它们视为 any 类型。
  2. 使用泛型:在需要处理多种类型的函数或类时,可以使用泛型来代替 any。泛型可以帮助您在编译时捕获类型错误,并提高代码的可读性和可维护性。
  3. 定义接口或类型别名:在需要包含多个属性或方法的复杂结构中,可以使用接口或类型别名来定义类型,而不是使用 any。使用接口或类型别名可以帮助您充分利用 TypeScript 的类型检查功能,并避免类型转换错误。
  4. 使用非空断言操作符:在某些情况下,可以使用非空断言操作符 ! 来告诉 TypeScript 某个变量不为空,从而避免将其视为 any 类型。但是,使用非空断言操作符需要慎重,可能会掩盖真正的类型错误。

总之,尽可能避免使用 any 类型可以帮助您充分利用 TypeScript 的静态类型检查功能,提高代码的可读性和可维护性。在编写代码时,应该尽可能使用具体的类型、泛型、接口等替代方案来代替 any 类型。

9.举几个常用的 Hook,并且解释一下作用

React Hooks 是 React 16.8 版本引入的新功能,当我们需要在函数式组件中使用状态和生命周期方法时,可以使用 Hooks,以下是几个常用的 Hooks。

  1. useState()

useState Hook 允许函数组件使用状态,这是一个能够重复使用的类似 this.state 和 this.setState 方法的 Hook。useState 为函数组件提供了在不转换为类的情况下存储和更新组件状态和其它变量的能力。

import React, { useState } from 'react';

function Example() {
  // 声明一个新的状态变量,名为 "count"
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

在上述示例中,useState 的初始值为 0,然后修改 count 的值需要使用 setCount 方法。每次修改了 count 的值,整个组件都会重新渲染。

  1. useEffect()

useEffect 可以用来在函数组件中执行副作用操作,例如获取远程数据、添加或删除 DOM 元素等。useEffect 在每次渲染后执行,但是可以根据需要进行激活和清除。

import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  // 相当于 componentDidMount 和 componentDidUpdate:
  useEffect(() => {
    // 更新文档标题
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

上述示例中,每次 count 改变,useEffect 执行后会修改文本标题。如果需要进行清除操作,则需要返回一个清除函数:

useEffect(() => {
  // 执行副作用操作
  return () => {
    // 清除操作
  };
});
  1. useContext()

useContext 用于在组件之间共享数据,可以避免使用 props 进行层层传递。通过使用 useContext,您可以将公共数据从父组件提取并将其传递到子组件中。

import React, { useContext } from 'react';

// 创建一个上下文对象
const MyContext = React.createContext(defaultValue);

function ChildComponent() {
  // 读取 MyContext 的值
  const contextValue = useContext(MyContext);

  return (
    <div>
      {contextValue}
    </div>
  );
}

function ParentComponent() {
  // 将值传递给 MyContext
  return (
    <MyContext.Provider value="Hello World!">
      <ChildComponent />
    </MyContext.Provider>
  );
}

在上述示例中,将值“Hello World!”传递给 MyContext,并在 ChildComponent 中使用 const contextValue = useContext(MyContext) 访问该上下文的值。

React Hooks 还有很多其它 Hook,比如 useReduceruseRefuseCallbackuseMemo 等,不同的 Hook 对应不同的用途。在实践中,您可以根据具体需要选择适当的 Hook,避免重复代码和 class 声明。

10.List, Map, Set 有什么区别?

ListMapSet 都是 JavaScript 中常用的数据结构,它们有以下区别:

  1. List:一组有序的值的集合,类似于数组。你可以通过索引或值来访问列表中的一项。List 具有可变性,可以添加、删除或修改其元素。在 JavaScript 中,可以使用数组(Array)实现类似 List 的数据结构。
// 使用数组实现类似于 List 的数据结构
const list = ['a', 'b', 'c'];
list.push('d');
console.log(list); // ['a', 'b', 'c', 'd']
  1. Map:一组键值对的集合,可以像字典一样使用。每个键都必须是唯一的,而且可以通过键快速查找值。Map 具有可变性,可以添加、删除或修改其键值对。在 JavaScript 中,可以使用对象(Object)实现类似 Map 的数据结构。
// 使用对象实现类似于 Map 的数据结构
const map = { a: 1, b: 2, c: 3 };
map.d = 4;
console.log(map); // { a: 1, b: 2, c: 3, d: 4 }
  1. Set:一组唯一值的集合,不考虑元素的顺序。Set 具有可变性,可以添加或删除其元素。在 JavaScript 中,可以使用数组(Array)和indexOf()或者includes()方法或者对象字面量({})实现类似 Set 的数据结构。
// 使用数组和 indexOf() 方法实现类似于 Set 的数据结构
const set1 = ['a', 'b', 'c'];
if (!set1.includes('d')) {
  set1.push('d');
}
console.log(set1); // ['a', 'b', 'c', 'd']

// 使用对象字面量实现类似于 Set 的数据结构
const set2 = { a: true, b: true, c: true };
set2.d = true;
console.log(Object.keys(set2)); // ['a', 'b', 'c', 'd']

综上所述,ListMapSet 的主要区别在于其元素的组织方式和基本操作。List 以有序方式组织元素,随着元素个数增加,查找速度变慢;Map 以键值对的形式组织元素,查找速度较快,但是需要占用更多内存;Set 则是以无序方式组织元素,并保证元素唯一。在实际开发中,应根据要求和场景的不同,选择适合的数据结构。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/673595.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【初识C语言】选择语句+循环语句+函数+数组

文章目录 前言1. 选择语句2. 循环语句3. 函数4. 数组 前言 C语言是一门结构化的程序设计语言 顺序结构&#xff1b; 选择结构&#xff1b; 循环结构。 1. 选择语句 生活中处处面临着选择&#xff0c;如果你好好学习&#xff0c;校招时拿一个好offer&#xff0c;走上人生巅峰。…

关于程序员的工作总结

程序员工作总结篇1 从我x月x日进入公司到现在已经过去一年了&#xff0c;从一名刚刚结束实习的学生到一名独立的开发人员&#xff0c;角色改变了&#xff0c;职责也改变了。虽然已经预计了工作之中会有很多困难&#xff0c;可是在实际的项目开发中&#xff0c;自己所遇到远远不…

(超级详细)如何在Mac OS上的VScode中配置OpenGL环境并编译

文章目录 安装环境下载GLAD与GLFW一、下载GLAD二、下载GLFW 项目结构配置测试程序与项目的编译测试可执行文件HelloGL 安装环境 机器&#xff1a;macbook air 芯片&#xff1a; M1芯片&#xff08;arm64&#xff09; macOS&#xff1a;macOS Ventura 13.4 VScode version&#…

Pytorch数据类型Tensor张量操作(操作比较全)

文章目录 Pytorch数据类型Tensor张量操作一.创建张量的方式1.创建无初始化张量2.创建随机张量3.创建初值为指定数值的张量4.从数据创建张量5.生成等差数列张量 二.改变张量形状三.索引四.维度变换1.维度增加unsqueeze2.维度扩展expand3.维度减少squeeze4.维度扩展repeat 五.维度…

SpringCloud Alibaba入门5之使用OpenFegin调用服务

我们继续在上一章的基础上进行开发 SpringCloud Alibaba入门4之nacos注册中心管理_qinxun2008081的博客-CSDN博客 Feign是一种声明式、模板化的HTTP客户端。使用Feign&#xff0c;可以做到声明式调用。Feign是在RestTemplate和Ribbon的基础上进一步封装&#xff0c;使用RestT…

SAP从入门到放弃系列之BOM行项目-虚拟装配-Part4

文章目录 虚拟组件&#xff08;Phantom assemblies&#xff09;&#xff1a;作用&#xff1a;BOM中虚拟件维护的方式&#xff1a; 物料主数据维度BOM组件维度&#xff08;数据优先级最高&#xff09; BOM组件的展开类型&#xff1a;BOM组件的特殊采购类数据测试示例&#xff1…

基于open62541库的OPC UA协议节点信息查询及多节点数值读写案例实践

目录 一、OPC UA协议简介 二、open62541库简介 三、 opcua协议的多点查询、多点读写案例服务端opcua_server 3.1 opcua_server工程目录 3.2 程序源码 3.3 工程组织文件 3.4 编译及启动 四、opcua协议的多点查询、多点读写案例客户端opcua_client 4.1 opcua_client工程目录 4…

医院管理系统源码PACS超声科室源码DICOM影像工作站

一、医学影像系统&#xff08;PACS&#xff09;是一种应用于医院影像科室的系统&#xff0c;主要任务是将日常产生的各种医学影像&#xff08;如核磁、CT、超声、X光机、红外仪、显微仪等设备产生的图像&#xff09;通过各种接口&#xff08;模拟、DICOM、网络&#xff09;以数…

社区活动 | OpenVINO™ DevCon 中国系列工作坊第二期 | 使用 OpenVINO™ 加速生成式 AI...

生成式 AI 领域一直在快速发展&#xff0c;许多潜在应用随之而来&#xff0c;这些应用可以从根本上改变人机交互与协作的未来。这一最新进展的一个例子是 GPT 模型的发布&#xff0c;它具有解决复杂问题的能力&#xff0c;比如通过医学和法律考试这种类似于人类的能力。然而&am…

Android Studio实现推箱子小游戏

项目目录 一、项目概述二、开发环境三、详细设计四、运行演示五、项目总结 一、项目概述 推箱子是一款非常受欢迎的益智游戏&#xff0c;游戏的玩法简单&#xff0c;但是需要玩家具备一定的逻辑思维能力和空间感知能力&#xff0c;因此深受广大玩家的喜爱。在游戏中&#xff0…

正点原子F4HAL库串口中断再解读

七步走&#xff0c;参考usart.c文件 void HAL_UART_MspInit(UART_HandleTypeDef *huart) 这个函数进行了&#xff08;1&#xff09;、&#xff08;2&#xff09;、&#xff08;3&#xff09;、&#xff08;5&#xff09;中的使能中断 void uart_init(u32 bound)函数进行了&…

『手撕 Mybatis 源码』07 - Proxy 对象创建

Proxy 对象创建 问题 sqlSession.getMapper(UserMapper.class) 是如何生成的代理对象&#xff1f; Mapper 代理方式初始化完成后&#xff0c;下一步进行获取代理对象来执行 public class MybatisTest {/*** 问题2&#xff1a;sqlSession.getMapper(UserMapper.class); 是如…

EMC学习笔记(五)传输线模型及反射、串扰

1.概述 在高速数字电路PCB设计中&#xff0c;当布线长度大于20分之一波长或信号延时超过6分之一信号上升沿时&#xff0c;PCB布线可被视为传输线。传输线有两种类型:微带线和带状线。与EMC设计有关的传输线特性包括:特征阻抗、传输延迟、固有电容和固有电感。反射与串扰会影响…

2023年第1季社区Task挑战赛贡献者榜单

基于数字身份凭证的业务逻辑设计&#xff0c;贡献了发放数字身份凭证的参考实现&#xff1b;提供企业碳排放、慈善公益等智能合约库业务场景案例&#xff1b;体验最新发布的WeCross-BCOS3-Stub&#xff0c;跟社区核心开发者碰撞想法并给出自己的见解……这些精彩贡献展现出社区…

<C++项目>高并发内存池

项目介绍&#xff1a; 原型是goole的开源项目tcmalloc(全称:Thread-Caching Malloc),用于替代系统的内存分配相关的函数(malloc, free).知名度非常高。 项目要求知识储备和难度&#xff1a; 会用到C/C、数据结构(链表、哈希桶)、操作系统内存管理、单例模式、多线程、互斥锁等等…

设计模式—“行为变化”

在组件构建过程中,组件行为的变化经常导致组件本身剧烈的变化。“行为变化”模式将组件的行为和组件本身进行解耦,从而支持组件行为的变化,实现两者之间的松耦合。 典型模式有:Command、Visitor 一、Command 动机 在软件构建过程中,"行为请求者"与“行为实现…

看完这篇,立马看懂理想首款纯电MEGA

作者 | 马波编辑 | 德新 6月17日&#xff0c;理想召开了首届家庭科技日活动。 这场打着家庭幌子的科技发布会&#xff0c;信息密度高到有些超出预期。但是看完这场发布会&#xff0c;理想超级旗舰车型 W01&#xff0c;也就是同时在本场发布会公布名称的理想MEGA&#xff0c;它…

硅谷之火重燃武大

关注、星标公众号&#xff0c;直达精彩内容 来源&#xff1a;技术让梦想更伟大 作者&#xff1a;李肖遥 昨天看到雷军雷总在武汉大学的毕业典礼上&#xff0c;朴实的演讲&#xff0c;看似吹牛&#xff0c;实则也是一种勉励。 雷军大学一年级时&#xff0c;在武大图书馆看到一本…

基于java,springboot的音乐分享平台

背景 音乐网站与分享平台的主要使用者分为管理员和用户&#xff0c;实现功能包括管理员&#xff1a;首页、个人中心、用户管理、音乐资讯管理、音乐翻唱管理、在线听歌管理、留言板管理、系统管理&#xff0c;用户&#xff1a;首页、个人中心、音乐翻唱管理、我的收藏管理&…

MySQL - 单表数据量大表优化方案

一. 前言 当MySQL单表记录数过大时&#xff0c;增删改查性能都会急剧下降&#xff0c;可以参考以下步骤来优化。 二. 单表优化 除非单表数据未来会一直不断上涨&#xff0c;否则不要一开始就考虑拆分&#xff0c;拆分会带来逻辑、部署、运维的各种复杂度&#xff0c;一般以整…