前端工程师面试题整理

前言

本文整理了一系列前端工程师面试中常见的 HTML、CSS 和 JavaScript 问题及其答案,涵盖基础知识、常见问题及面试技巧。适用于准备前端开发职位面试的候选人参考。

目录

    • 前言
    • [HTML & CSS](#HTML & CSS)
      • [1. 对 WEB 标准以及 W3C 的理解与认识](#1. 对 WEB 标准以及 W3C 的理解与认识)
      • [2. XHTML 和 HTML 有什么区别](#2. XHTML 和 HTML 有什么区别)
      • [3. Doctype? 严格模式与混杂模式](#3. Doctype? 严格模式与混杂模式)
      • [4. 行内元素有哪些? 块级元素有哪些? CSS 的盒模型?](#4. 行内元素有哪些? 块级元素有哪些? CSS 的盒模型?)
      • [5. CSS 引入的方式有哪些? `link` 和 `@import` 的区别是?](#5. CSS 引入的方式有哪些? link@import 的区别是?)
      • [6. CSS 选择符有哪些? 哪些属性可以继承? 优先级算法如何计算? 内联和 `!important` 哪个优先级高?](#6. CSS 选择符有哪些? 哪些属性可以继承? 优先级算法如何计算? 内联和 !important 哪个优先级高?)
      • [7. 前端页面有哪三层构成,分别是什么? 作用是什么?](#7. 前端页面有哪三层构成,分别是什么? 作用是什么?)
      • [8. CSS 的基本语句构成是?](#8. CSS 的基本语句构成是?)
      • [9. 你做的页面在哪些浏览器测试过? 这些浏览器的内核分别是什么? 经常遇到的浏览器的兼容性有哪些? 怎么会出现? 解决方法是什么?](#9. 你做的页面在哪些浏览器测试过? 这些浏览器的内核分别是什么? 经常遇到的浏览器的兼容性有哪些? 怎么会出现? 解决方法是什么?)
      • [10. 写出几种 IE6 BUG 的解决方法](#10. 写出几种 IE6 BUG 的解决方法)
      • [11. 标签上 `title` 与 `alt` 属性的区别是什么?](#11. 标签上 titlealt 属性的区别是什么?)
      • [12. 描述 CSS Reset 的作用和用途](#12. 描述 CSS Reset 的作用和用途)
      • [13. 解释 CSS Sprites,如何使用](#13. 解释 CSS Sprites,如何使用)
      • [14. 浏览器标准模式和怪异模式之间的区别是什么?](#14. 浏览器标准模式和怪异模式之间的区别是什么?)
      • [15. 你如何对网站的文件和资源进行优化?](#15. 你如何对网站的文件和资源进行优化?)
      • [16. 什么是语义化的 HTML?](#16. 什么是语义化的 HTML?)
      • [17. 清除浮动的几种方式,各自的优缺点](#17. 清除浮动的几种方式,各自的优缺点)
    • JavaScript
      • [1. JavaScript 的 `typeof` 返回哪些数据类型](#1. JavaScript 的 typeof 返回哪些数据类型)
      • [2. 例举 3 种强制类型转换和 2 种隐式类型转换](#2. 例举 3 种强制类型转换和 2 种隐式类型转换)
      • [3. `split()` 和 `join()` 的区别](#3. split()join() 的区别)
      • [4. 数组方法 `pop()`、`push()`、`unshift()`、`shift()`](#4. 数组方法 pop()push()unshift()shift())
      • [5. 事件绑定和普通事件有什么区别](#5. 事件绑定和普通事件有什么区别)
      • [6. IE 和 DOM 事件流的区别](#6. IE 和 DOM 事件流的区别)
      • [7. IE 和标准下有哪些兼容性的写法](#7. IE 和标准下有哪些兼容性的写法)
      • [8. AJAX 请求的时候 GET 和 POST 方式的区别](#8. AJAX 请求的时候 GET 和 POST 方式的区别)
      • [9. `call` 和 `apply` 的区别](#9. callapply 的区别)
      • [10. AJAX 请求时,如何解析 JSON 数据](#10. AJAX 请求时,如何解析 JSON 数据)
      • [11. B 继承 A 的方法](#11. B 继承 A 的方法)
      • [12. 写一个获取非行间样式的函数](#12. 写一个获取非行间样式的函数)
      • [13. 事件委托是什么](#13. 事件委托是什么)
      • [14. 闭包是什么,有什么特性,对页面有什么影响](#14. 闭包是什么,有什么特性,对页面有什么影响)
      • [15. 如何阻止事件冒泡和默认事件](#15. 如何阻止事件冒泡和默认事件)
      • [16. 添加、删除、替换、插入到某个节点的方法](#16. 添加、删除、替换、插入到某个节点的方法)
      • [17. 解释 JSONP 的原理,以及为什么不是真正的 AJAX](#17. 解释 JSONP 的原理,以及为什么不是真正的 AJAX)
      • [18. JavaScript 的本地对象,内置对象和宿主对象](#18. JavaScript 的本地对象,内置对象和宿主对象)
      • [19. `document load` 和 `document ready` 的区别](#19. document loaddocument ready 的区别)
      • [20. `==` 和 `===` 的不同](#20. ===== 的不同)
      • [21. JavaScript 的同源策略](#21. JavaScript 的同源策略)
      • [22. 编写一个数组去重的方法](#22. 编写一个数组去重的方法)
      • [23. `String` 对象的方法不包括哪一个](#23. String 对象的方法不包括哪一个)
      • [24. 关于 `setTimeout("check", 10)` 中说法正确的是](#24. 关于 setTimeout("check", 10) 中说法正确的是)
      • [25. 以下哪个单词不属于 JavaScript 关键字](#25. 以下哪个单词不属于 JavaScript 关键字)
    • 前端工程师面试心得
    • 其他面试题
    • 前端开发工程师面试知识点大纲
    • 其他面试题
  • 参考资料

HTML & CSS

1. 对 WEB 标准以及 W3C 的理解与认识

WEB 标准 是指一套用于规范网页设计和开发的技术标准,旨在确保网页在不同浏览器和设备上具有一致的表现和功能。W3C(万维网联盟)是制定和维护这些标准的国际组织。

遵循 WEB 标准的好处包括:

  • 标签闭合:确保 HTML 标签正确闭合,避免结构混乱。
  • 标签小写:统一标签名称为小写,提高代码一致性。
  • 不乱嵌套:正确嵌套 HTML 元素,确保文档结构合理。
  • 提高搜索机器人搜索几率:标准化代码有助于搜索引擎更好地抓取和索引内容。
  • 使用外链 CSS 和 JS 脚本:实现结构、行为和表现的分离,提升可维护性。
  • 文件下载与页面速度更快:外链资源可以被缓存,减少重复下载,提高加载速度。
  • 内容能被更多的用户所访问:标准化代码兼容更多设备和浏览器。
  • 更少的代码和组件,容易维护:简洁的代码更易于维护和更新。
  • 改版方便,不需要变动页面内容:样式与结构分离,便于进行视觉改版。
  • 提供打印版本而不需要复制内容:通过 CSS 打印样式,实现页面的打印优化。
  • 提高网站易用性:一致的标准提升用户体验。

2. XHTML 和 HTML 有什么区别

HTML 是一种用于创建网页的标记语言,而 XHTML 是基于 XML 的标记语言,两者的主要区别如下:

  • 严格嵌套:XHTML 元素必须被正确地嵌套,避免标签交叉。
  • 元素必须被关闭:所有的 XHTML 元素必须有对应的结束标签,或使用自闭合标签。
  • 标签名必须小写:XHTML 标签名必须全部使用小写字母。
  • 文档必须拥有根元素 :XHTML 文档必须有一个唯一的根元素,如 <html>

3. Doctype? 严格模式与混杂模式

Doctype 用于声明文档类型,告诉浏览器按照哪种标准解析网页。它可以触发浏览器的严格模式或混杂模式。

  • 严格模式(Standards Mode) :浏览器按照 W3C 标准严格解析和渲染网页。触发方式:使用正确的 Doctype 声明,例如 <!DOCTYPE html>
  • 混杂模式(Quirks Mode):浏览器以向后兼容的方式解析网页,允许使用一些旧版浏览器的特性和漏洞。触发方式:缺少 Doctype 或使用不正确的 Doctype 声明。

区别与意义:

  • 渲染方式不同:严格模式下,浏览器遵循标准,混杂模式下,浏览器兼容旧版行为。
  • 盒模型差异:在严格模式下,盒模型按照标准计算;在混杂模式下,IE6 等浏览器使用不同的盒模型。
  • 布局与样式表现:严格模式提供更一致和可预测的布局表现,有助于开发者编写符合标准的代码。

4. 行内元素有哪些? 块级元素有哪些? CSS 的盒模型?

块级元素(Block-Level Elements):

  • 常见标签:<div><p><h1>-<h6><form><ul><ol><dl><li><table><tr><td>

行内元素(Inline Elements):

  • 常见标签:<a><b><br><i><span><input><select><textarea><strong><em>

CSS 盒模型(Box Model):

每个 HTML 元素在浏览器中被视为一个盒子,包含以下部分:

  1. 内容区(Content):实际内容显示区域。

  2. 内边距(Padding):内容周围的空白区域,透明。

  3. 边框(Border):包围内边距和内容的边框。

  4. 外边距(Margin):盒子外部的空白区域,透明。

    +---------------------------+
    | Margin |
    | +---------------------+ |
    | | Border | |
    | | +---------------+ | |
    | | | Padding | | |
    | | | +-----------+ | | |
    | | | | Content | | | |
    | | | +-----------+ | | |
    | | | | | |
    | | +---------------+ | |
    | | | |
    | +---------------------+ |
    | |
    +---------------------------+

CSS 引入方式:

  1. 内联样式(Inline Styles)

    • 直接在 HTML 元素的 style 属性中定义样式。

    • 示例:

      html 复制代码
      <div style="color: red;">文本</div>
  2. 内嵌样式(Internal Styles)

    • 在 HTML 文档的 <head> 部分使用 <style> 标签定义样式。

    • 示例:

      html 复制代码
      <head>
        <style>
          .text { color: red; }
        </style>
      </head>
  3. 外链样式(External Styles)

    • 使用 <link> 标签在 HTML 文档中引入外部 CSS 文件。

    • 示例:

      html 复制代码
      <head>
        <link rel="stylesheet" href="styles.css">
      </head>
  4. @import 引入

    • 在 CSS 文件中使用 @import 语句引入其他 CSS 文件。

    • 示例:

      css 复制代码
      @import url("styles.css");

link@import 的区别:

特性 <link> 标签 @import 语句
加载方式 同时加载,减少延迟 顺序加载,可能增加延迟
兼容性 所有浏览器均支持 CSS2.1 以下浏览器不支持
动态修改 支持使用 JavaScript 动态改变样式 不支持使用 JavaScript 动态改变样式
优先级 较高 较低
性能 更优,减少 HTTP 请求时间 较差,可能阻塞后续样式的加载

总结:

  • 外链样式 (<link>):推荐使用,因为它性能更好,兼容性更强,且支持动态修改。
  • @import:适用于需要在 CSS 文件中组织和引入样式,但可能会影响性能,尽量减少使用。

6. CSS 选择符有哪些? 哪些属性可以继承? 优先级算法如何计算? 内联和 !important 哪个优先级高?

CSS 选择符(Selectors):

  1. 标签选择器(Type Selector)

    • 例如:divph1
  2. 类选择器(Class Selector)

    • 例如:.container.active
  3. ID 选择器(ID Selector)

    • 例如:#header#footer
  4. 后代选择器(Descendant Selector)

    • 例如:div pul li
  5. 群组选择器(Group Selector)

    • 例如:h1, h2, h3.btn, .link
  6. 伪类选择器(Pseudo-class Selector)

    • 例如::hover:active:nth-child(2)
  7. 属性选择器(Attribute Selector)

    • 例如:input[type="text"]a[href^="https"]

可继承的属性(Inherited Properties):

  • 字体相关font-familyfont-sizefont-weightcolorline-height
  • 文本相关text-aligntext-indenttext-transform
  • 其他visibilitycursor

不可继承的属性:

  • 布局相关marginpaddingborderwidthheightdisplayposition

优先级算法(Specificity)计算:

优先级由四个部分组成,按照从高到低依次为:

  1. 内联样式(Inline styles):最高优先级。
  2. ID 选择器(ID selectors)
  3. 类、属性、伪类选择器(Classes, attributes, pseudo-classes)
  4. 标签、伪元素选择器(Type selectors, pseudo-elements)

具体计算方式:

  • 每一类选择器对应一个数字位数,例如:
    • 内联样式:1,0,0,0
    • ID 选择器:0,1,0,0
    • 类选择器:0,0,1,0
    • 标签选择器:0,0,0,1

!important 和内联样式的优先级比较:

  • !important :无论选择器的优先级如何,带有 !important 的声明优先级最高。
  • 内联样式 :在没有 !important 的情况下,内联样式的优先级高于外部样式。

总结:

  • !important > 内联样式 > ID 选择器 > 类选择器 > 标签选择器
  • 建议尽量避免使用 !important,以保持 CSS 的可维护性和层次性。

7. 前端页面有哪三层构成,分别是什么? 作用是什么?

前端页面的三层构成:

  1. 结构层(Structure Layer)

    • 技术:HTML、XHTML
    • 作用:定义网页的基本结构和内容,如标题、段落、列表等。
  2. 表现层(Presentation Layer)

    • 技术:CSS
    • 作用:控制网页的视觉表现,如布局、颜色、字体、边距等。
  3. 行为层(Behavior Layer)

    • 技术:JavaScript
    • 作用:实现网页的动态交互和行为,如按钮点击、表单验证、动画效果等。

总结:

  • 结构层:负责内容的组织和呈现。
  • 表现层:负责内容的视觉样式和布局。
  • 行为层:负责内容的交互和动态行为。

8. CSS 的基本语句构成是?

CSS 基本语句构成:

css 复制代码
选择器 {
  属性1: 值1;
  属性2: 值2;
  /* 更多属性 */
}

示例:

css 复制代码
.container {
  width: 100%;
  padding: 20px;
  background-color: #f0f0f0;
}

9. 你做的页面在哪些浏览器测试过? 这些浏览器的内核分别是什么? 经常遇到的浏览器的兼容性有哪些? 怎么会出现? 解决方法是什么?

测试过的浏览器及其内核:

  • IE(Trident 内核)
  • 火狐(Firefox)(Gecko 内核)
  • 谷歌(Chrome)(Blink 内核,基于 WebKit)
  • Opera(Presto 内核,最新版本基于 Blink)
  • Safari(WebKit 内核)
  • Maxthon(Trident/WebKit 双内核)

常见的浏览器兼容性问题及解决方法:

  1. 默认字体大小差异

    • 问题:不同浏览器的默认字体大小不同,导致字体显示不一致。
    • 解决方法 :在 CSS 中统一设置字体大小,例如 body { font-size: 14px; }
  2. 嵌套 <a> 标签

    • 问题 :某些浏览器不允许 <a> 标签嵌套 <a> 标签,会导致结构错误。
    • 解决方法 :避免在 <a> 标签内嵌套其他 <a> 标签,使用其他元素包裹。
  3. 链接内容样式差异

    • 问题 :不同浏览器对 <a> 标签内部内容的样式处理不同。
    • 解决方法 :在 CSS 中明确设置 <a> 标签的 display 属性,例如 display: block;,并统一样式。
  4. 列表样式和内边距

    • 问题 :不同浏览器对 <ul>ol><dl> 等列表标签的默认样式和内边距处理不同。

    • 解决方法 :在 CSS 中重置列表样式和内边距,例如:

      css 复制代码
      ul, ol, dl {
        margin: 0;
        padding: 0;
        list-style: none;
      }
  5. Wrapper <div> 高度问题

    • 问题 :外部包裹的 <div> 高度在不同浏览器中表现不一致。
    • 解决方法 :设置 overflow: hidden; 使高度自适应,避免固定高度。
  6. 手形光标兼容性

    • 问题 :不同浏览器对 cursor: hand;cursor: pointer; 的支持不同。
    • 解决方法 :统一使用 cursor: pointer;,兼容性更好。
  7. 居中问题

    • 问题:不同浏览器对居中方式的支持不同,特别是浮动元素的居中。
    • 解决方法
      • 对父元素使用 text-align: center;,对子元素使用 margin: 0 auto;
      • 使用 Flexbox 布局实现居中。
  8. 浮动引起的双倍边距

    • 问题:在 IE 中,浮动元素可能会导致双倍边距。
    • 解决方法 :设置 display: inline; 使浮动忽略元素间的空隙,或使用其他清除浮动的方法。
  9. 居中浮动元素

    • 问题:浮动元素无法通过常规方式居中。
    • 解决方法 :使用 margin: 0 auto; 配合 display: block;,或使用 Flexbox 实现居中。

10. 写出几种 IE6 BUG 的解决方法

  1. 双边距 BUG(Double Margin Float Bug)

    • 问题:在 IE6 中,浮动元素的左右外边距会被倍增。

    • 解决方法 :设置 display: inline;,使 IE6 忽略外边距的倍增。

      css 复制代码
      .float-element {
        float: left;
        margin-left: 10px;
        display: inline;
      }
  2. 3 像素问题

    • 问题:IE6 中,浮动元素的高度可能出现 3 像素的误差。

    • 解决方法 :调整 line-height 或使用 zoom: 1; 触发 hasLayout。

      css 复制代码
      .float-element {
        float: left;
        line-height: 1px;
        zoom: 1;
      }
  3. 超链接 hover 点击后失效

    • 问题 :在 IE6 中,超链接在 :hover 状态下点击后失效。

    • 解决方法 :确保 CSS 中的链接伪类顺序为 :link:visited:hover:active

      css 复制代码
      a:link { /* 样式 */ }
      a:visited { /* 样式 */ }
      a:hover { /* 样式 */ }
      a:active { /* 样式 */ }
  4. IE z-index 问题

    • 问题 :在 IE6 中,子元素的 z-index 无法超越父元素。

    • 解决方法 :给父元素添加 position: relative;

      css 复制代码
      .parent {
        position: relative;
        z-index: 1;
      }
      .child {
        position: absolute;
        z-index: 2;
      }
  5. PNG 透明问题

    • 问题:IE6 不支持 PNG 图片的透明背景。

    • 解决方法 :使用 JavaScript 或滤镜(filter)修复透明效果。

      css 复制代码
      .png-fix {
        filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='image.png', sizingMethod='scale');
      }
  6. min-height 最小高度问题

    • 问题 :IE6 不支持 min-height 属性。

    • 解决方法 :使用 height 代替,并触发 hasLayout。

      css 复制代码
      .container {
        height: 300px; /* 代替 min-height */
        zoom: 1; /* 触发 hasLayout */
      }
  7. select 元素遮盖问题

    • 问题 :在 IE6 中,select 元素会遮盖浮动元素。

    • 解决方法 :使用 iframe 嵌套层级,或者使用其他替代方案。

      html 复制代码
      <!-- 使用 iframe 作为遮罩层 -->
      <iframe src="about:blank" style="position:absolute; top:0; left:0; width:100%; height:100%;"></iframe>
  8. 无法定义 1px 宽度的容器

    • 问题:IE6 默认行高导致无法准确设置 1px 宽度。

    • 解决方法 :使用 overflow: hidden;zoom: 1; 或调整 line-height

      css 复制代码
      .one-pixel {
        width: 1px;
        overflow: hidden;
        zoom: 1;
        line-height: 1px;
      }

11. 标签上 titlealt 属性的区别是什么?

  • alt 属性

    • 用途:为图片提供替代文本,当图片无法显示时显示该文字。

    • 示例

      html 复制代码
      <img src="image.jpg" alt="描述性文本">
  • title 属性

    • 用途:为元素提供额外的信息,通常在鼠标悬停时显示为工具提示。

    • 示例

      html 复制代码
      <a href="#" title="更多信息">链接</a>

总结:

  • alt 用于替代内容,增强可访问性。
  • title 用于提供额外信息,提升用户体验。

12. 描述 CSS Reset 的作用和用途

CSS Reset 的作用是重置不同浏览器的默认样式,使各浏览器在渲染网页时有一致的基础,从而减少跨浏览器的兼容性问题。

用途:

  • 统一样式:消除不同浏览器默认的内边距、外边距、字体等差异。
  • 简化样式管理:提供一个统一的起点,便于后续的样式设计和开发。
  • 提升可维护性:减少因浏览器差异导致的样式调整和修复工作。

常见的 CSS Reset 工具:

  • Eric Meyer's Reset CSS
  • Normalize.css

示例:

css 复制代码
/* 简单的 CSS Reset */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

13. 解释 CSS Sprites,如何使用

CSS Sprites 是一种将多个小图标或图片合并为一张大图的技术,通过 CSS 的 background-imagebackground-position 属性来显示不同部分的图片。

优点:

  • 减少 HTTP 请求:合并图片减少页面加载时的 HTTP 请求数量,提升加载速度。
  • 提高性能:减少服务器资源的消耗,提升用户体验。

使用方法:

  1. 创建 Sprites 图

    • 将多个小图标拼接成一张大图,记录每个小图标在大图中的位置(坐标)。
  2. CSS 设置

    • 使用 background-image 指定大图。
    • 使用 background-position 设置显示大图的特定部分。
    • 设置元素的宽度和高度为小图标的尺寸。

示例:

css 复制代码
.icon {
  background-image: url('sprites.png');
  width: 32px;
  height: 32px;
  display: inline-block;
}

.icon-home {
  background-position: 0 0;
}

.icon-search {
  background-position: -32px 0;
}

.icon-settings {
  background-position: -64px 0;
}
html 复制代码
<span class="icon icon-home"></span>
<span class="icon icon-search"></span>
<span class="icon icon-settings"></span>

14. 浏览器标准模式和怪异模式之间的区别是什么?

浏览器标准模式(Standards Mode)怪异模式(Quirks Mode) 是浏览器解析和渲染网页时的两种模式,主要区别体现在以下方面:

  1. 盒模型

    • 标准模式:采用标准的盒模型,元素的宽高只包含内容区,不包括内边距和边框。
    • 怪异模式:采用 IE6 盒模型,元素的宽高包括内容、内边距和边框。
  2. 渲染行为

    • 标准模式:严格遵循 W3C 标准,提供一致和可预测的渲染结果。
    • 怪异模式:兼容旧版浏览器的渲染方式,可能导致不一致和不可预测的布局问题。
  3. 触发方式

    • 标准模式 :通过正确的 Doctype 声明,如 <!DOCTYPE html>
    • 怪异模式:缺少 Doctype 或使用不正确的 Doctype 声明。

检测渲染模式

javascript 复制代码
if (document.compatMode === "CSS1Compat") {
  console.log("标准模式");
} else {
  console.log("怪异模式");
}

意义:

  • 一致性:标准模式提供更一致的跨浏览器表现,便于开发和维护。
  • 兼容性:怪异模式用于兼容旧版浏览器的网页,确保旧网站正常显示。

15. 你如何对网站的文件和资源进行优化?

文件和资源优化方法:

  1. 文件合并

    • 将多个 CSS 或 JavaScript 文件合并为一个文件,减少 HTTP 请求次数。
  2. 文件最小化/压缩

    • 使用工具(如 UglifyJS、CSSNano)压缩 JavaScript 和 CSS 文件,减少文件大小。
  3. 使用 CDN 托管

    • 将静态资源(如图片、库文件)托管在 CDN 上,提升加载速度和分发效率。
  4. 缓存的使用

    • 利用浏览器缓存,通过设置合适的 HTTP 缓存头(如 Cache-ControlExpires)提高资源加载效率。
  5. 图片优化

    • 压缩图片文件,选择合适的格式(如 JPEG、PNG、WebP),使用 CSS Sprites 减少图片请求。
  6. 延迟加载(Lazy Loading)

    • 对不在视口内的资源进行延迟加载,提升页面初始加载速度。
  7. 代码分割(Code Splitting)

    • 将代码拆分成按需加载的模块,减少初始加载的 JavaScript 量。
  8. 使用 GZIP 压缩

    • 启用 GZIP 压缩,减少传输数据量,提升加载速度。

总结:

通过以上优化方法,可以显著提升网站的加载速度、响应效率和用户体验。

16. 什么是语义化的 HTML?

语义化 HTML 指的是使用具有明确意义的 HTML 标签来描述内容,使代码更具可读性和可维护性,同时提升搜索引擎优化(SEO)效果和可访问性。

优势:

  • 提高可读性:开发者和其他人更容易理解代码结构和内容。
  • 增强 SEO:搜索引擎更容易抓取和理解网页内容,提高网站排名。
  • 改善可访问性:辅助技术(如屏幕阅读器)更好地理解和呈现内容,提升无障碍体验。

示例:

  • 使用 <header><nav><main><footer> 来定义页面的不同部分。
  • 使用 <article><section><aside> 来组织内容。
  • 使用 <figure><figcaption> 来描述图像和其说明。
html 复制代码
<article>
  <header>
    <h1>文章标题</h1>
    <p>作者信息</p>
  </header>
  <section>
    <h2>章节标题</h2>
    <p>内容...</p>
  </section>
  <footer>
    <p>版权信息</p>
  </footer>
</article>

17. 清除浮动的几种方式,各自的优缺点

1. 使用空标签清除浮动(Clearfix Hack)

html 复制代码
<div class="container">
  <div class="float-element">浮动元素</div>
  <div class="float-element">浮动元素</div>
  <div class="clearfix"></div>
</div>
css 复制代码
.clearfix {
  clear: both;
}

优点:

  • 简单直接,易于理解和实现。

缺点:

  • 增加了无意义的 HTML 标签,影响语义化。

2. 使用 overflow: autooverflow: hidden

css 复制代码
.container {
  overflow: hidden;
}

优点:

  • 不需要额外的 HTML 元素,保持结构简洁。
  • 触发块级格式化上下文,自动清除浮动。

缺点:

  • 可能会截断溢出的内容,不适用于需要显示溢出部分的场景。

3. 使用 ::after 伪元素

css 复制代码
.container::after {
  content: "";
  display: table;
  clear: both;
}
html 复制代码
<div class="container">
  <div class="float-element">浮动元素</div>
  <div class="float-element">浮动元素</div>
</div>

优点:

  • 不需要添加额外的 HTML 元素,保持结构干净。
  • 支持 CSS3,适用于现代浏览器。

缺点:

  • 不支持 IE8 及以下版本。

总结:

  • 使用空标签:简单但增加 HTML 负担。
  • 使用 overflow:简洁但可能影响内容显示。
  • 使用伪元素:高效且不污染 HTML,但需现代浏览器支持。

JavaScript

1. JavaScript 的 typeof 返回哪些数据类型

typeof 运算符用于检测变量的数据类型,返回以下几种类型:

  • "undefined"
  • "object"(对于 null 也是 "object"
  • "boolean"
  • "number"
  • "string"
  • "function"
  • "symbol"(ES6 引入)
  • "bigint"(ES2020 引入)

示例:

javascript 复制代码
console.log(typeof undefined); // "undefined"
console.log(typeof null);      // "object"
console.log(typeof true);      // "boolean"
console.log(typeof 42);        // "number"
console.log(typeof "Hello");   // "string"
console.log(typeof function(){}); // "function"
console.log(typeof Symbol());  // "symbol"
console.log(typeof 10n);       // "bigint"

2. 例举 3 种强制类型转换和 2 种隐式类型转换

强制类型转换(Explicit Type Conversion):

  1. parseInt

    • 将字符串转换为整数。

    • 示例:

      javascript 复制代码
      parseInt("123"); // 123
  2. parseFloat

    • 将字符串转换为浮点数。

    • 示例:

      javascript 复制代码
      parseFloat("123.45"); // 123.45
  3. Number

    • 将值转换为数字类型。

    • 示例:

      javascript 复制代码
      Number("123"); // 123

隐式类型转换(Implicit Type Conversion):

  1. 使用 == 进行比较

    • 自动转换不同类型的值后进行比较。

    • 示例:

      javascript 复制代码
      5 == "5"; // true
  2. 使用算术运算符

    • 在运算过程中自动转换类型。

    • 示例:

      javascript 复制代码
      "5" * "2"; // 10

3. split()join() 的区别

  • split() 方法

    • 用途:将字符串按指定分隔符拆分为数组。

    • 示例

      javascript 复制代码
      const str = "apple,banana,cherry";
      const arr = str.split(","); // ["apple", "banana", "cherry"]
  • join() 方法

    • 用途:将数组元素按指定分隔符连接为字符串。

    • 示例

      javascript 复制代码
      const arr = ["apple", "banana", "cherry"];
      const str = arr.join(","); // "apple,banana,cherry"

总结:

  • split():字符串 → 数组
  • join():数组 → 字符串

4. 数组方法 pop()push()unshift()shift()

  • push()

    • 用途:在数组末尾添加一个或多个元素。

    • 示例

      javascript 复制代码
      const arr = [1, 2, 3];
      arr.push(4); // [1, 2, 3, 4]
  • pop()

    • 用途:移除数组末尾的元素并返回该元素。

    • 示例

      javascript 复制代码
      const arr = [1, 2, 3, 4];
      const last = arr.pop(); // last = 4, arr = [1, 2, 3]
  • unshift()

    • 用途:在数组开头添加一个或多个元素。

    • 示例

      javascript 复制代码
      const arr = [2, 3];
      arr.unshift(1); // [1, 2, 3]
  • shift()

    • 用途:移除数组开头的元素并返回该元素。

    • 示例

      javascript 复制代码
      const arr = [1, 2, 3];
      const first = arr.shift(); // first = 1, arr = [2, 3]

5. 事件绑定和普通事件有什么区别

事件绑定(Event Binding):

  • 定义:通过 JavaScript 动态地将事件处理函数绑定到元素上。
  • 方法
    • 使用 addEventListener (现代浏览器)

      javascript 复制代码
      element.addEventListener('click', function() {
        // 处理代码
      });
    • 使用 attachEvent (IE8 及以下)

      javascript 复制代码
      element.attachEvent('onclick', function() {
        // 处理代码
      });

普通事件(Inline Event Handlers):

  • 定义:在 HTML 标签中直接使用事件属性绑定事件处理函数。

  • 示例

    html 复制代码
    <button onclick="handleClick()">点击我</button>

区别:

  1. 可维护性

    • 事件绑定:代码与 HTML 分离,易于维护和管理。
    • 普通事件:代码混杂在 HTML 中,难以维护。
  2. 多重绑定

    • 事件绑定:允许为同一事件绑定多个处理函数。
    • 普通事件:只能绑定一个处理函数,后绑定的会覆盖前面的。
  3. 兼容性

    • 事件绑定 :现代方法 addEventListener 在所有现代浏览器中支持,attachEvent 支持 IE8 及以下。
    • 普通事件:所有浏览器都支持,但功能有限。

总结:

  • 推荐使用事件绑定方法(如 addEventListener),以提高代码的可维护性和灵活性。

6. IE 和 DOM 事件流的区别

IE 事件模型(IE Event Model):

  • 事件处理方式 :基于 attachEventdetachEvent 方法。
  • 事件对象 :通过全局变量 window.event 获取。
  • 事件冒泡:事件总是从目标元素向上冒泡。
  • 取消默认行为 :使用 return false; 或设置 event.cancelBubble = true;

DOM 事件模型(W3C DOM Event Model):

  • 事件处理方式 :基于 addEventListenerremoveEventListener 方法。
  • 事件对象:作为事件处理函数的参数传递。
  • 事件流:包括捕获阶段、目标阶段和冒泡阶段。
  • 取消默认行为 :使用 event.preventDefault();event.stopPropagation();

主要区别:

  1. 事件绑定方法

    • IEattachEvent / detachEvent
    • DOMaddEventListener / removeEventListener
  2. 事件对象获取

    • IE :通过 window.event
    • DOM:通过事件处理函数的参数
  3. 事件流控制

    • IE:仅支持冒泡
    • DOM:支持捕获和冒泡
  4. 取消冒泡和默认行为的方法

    • IEevent.cancelBubble = true;return false;
    • DOMevent.stopPropagation();event.preventDefault();

总结:

  • 现代浏览器支持 W3C DOM 事件模型,建议使用 addEventListener 等标准方法进行事件处理。
  • 对于需要兼容 IE8 及以下版本的项目,需结合 attachEvent 方法进行兼容处理。

7. IE 和标准下有哪些兼容性的写法

常见的 IE 和标准兼容写法:

  1. 获取事件对象

    javascript 复制代码
    function handleEvent(event) {
      var e = event || window.event; // 兼容 IE
      // 处理事件
    }
  2. 获取元素的宽度

    javascript 复制代码
    var width = document.documentElement.clientWidth || document.body.clientWidth; // 兼容 IE
  3. 获取事件目标元素

    javascript 复制代码
    var target = event.srcElement || event.target; // 兼容 IE
  4. 阻止事件冒泡

    javascript 复制代码
    if (event.stopPropagation) {
      event.stopPropagation(); // 标准
    } else {
      event.cancelBubble = true; // IE
    }
  5. 阻止默认行为

    javascript 复制代码
    if (event.preventDefault) {
      event.preventDefault(); // 标准
    } else {
      event.returnValue = false; // IE
    }
  6. 添加事件处理函数

    javascript 复制代码
    if (element.addEventListener) {
      element.addEventListener('click', handler, false); // 标准
    } else if (element.attachEvent) {
      element.attachEvent('onclick', handler); // IE
    }
  7. 移除事件处理函数

    javascript 复制代码
    if (element.removeEventListener) {
      element.removeEventListener('click', handler, false); // 标准
    } else if (element.detachEvent) {
      element.detachEvent('onclick', handler); // IE
    }

总结:

  • 使用逻辑判断 (if-else) 来确定使用哪种方法,以兼容不同浏览器的事件模型。
  • 关注现代浏览器的支持,逐步淘汰对旧版 IE 的兼容性处理。

8. AJAX 请求的时候 GET 和 POST 方式的区别

GET 和 POST 的区别:

特性 GET POST
数据位置 URL 后面作为查询字符串 请求体中发送数据
数据大小限制 有限制(通常为 2048 字符) 无明显限制
安全性 不安全,数据暴露在 URL 中 相对安全,数据隐藏在请求体中
幂等性 是,重复请求不会改变服务器状态 否,重复请求可能导致数据重复提交
缓存 可以被浏览器缓存 通常不被缓存
使用场景 数据检索、搜索请求 数据提交、表单提交、文件上传

应用场景:

  • GET:适用于获取数据、不改变服务器状态的请求,如搜索、数据查询。
  • POST:适用于提交数据、改变服务器状态的请求,如表单提交、数据创建。

9. callapply 的区别

callapply 方法用于改变函数的上下文(this)并调用函数。

  • call 方法

    • 语法function.call(thisArg, arg1, arg2, ...)

    • 用法:传递参数列表。

    • 示例

      javascript 复制代码
      function greet(greeting, punctuation) {
        console.log(greeting + ', ' + this.name + punctuation);
      }
      
      const person = { name: 'Alice' };
      greet.call(person, 'Hello', '!'); // 输出: "Hello, Alice!"
  • apply 方法

    • 语法function.apply(thisArg, [argsArray])

    • 用法:传递参数数组。

    • 示例

      javascript 复制代码
      function greet(greeting, punctuation) {
        console.log(greeting + ', ' + this.name + punctuation);
      }
      
      const person = { name: 'Bob' };
      greet.apply(person, ['Hi', '?']); // 输出: "Hi, Bob?"

主要区别:

  • 参数传递方式
    • call:逐个传递参数。
    • apply:以数组形式传递参数。

总结:

  • 使用 call 时,参数以逗号分隔。
  • 使用 apply 时,参数作为数组传递。

10. AJAX 请求时,如何解析 JSON 数据

解析 JSON 数据的方法:

  1. 使用 JSON.parse()

    • 用途:将 JSON 字符串转换为 JavaScript 对象。

    • 示例

      javascript 复制代码
      const jsonString = '{"name": "Alice", "age": 25}';
      const obj = JSON.parse(jsonString);
      console.log(obj.name); // "Alice"
  2. 使用 eval()

    • 用途:将字符串当作 JavaScript 代码执行。

    • 注意:存在安全风险,容易受到 XSS 攻击,不推荐使用。

    • 示例

      javascript 复制代码
      const jsonString = '{"name": "Bob", "age": 30}';
      const obj = eval('(' + jsonString + ')');
      console.log(obj.name); // "Bob"

推荐方法:

  • 使用 JSON.parse(),因为它安全、标准且高效。
  • 避免使用 eval(),因其潜在的安全风险和性能问题。

11. B 继承 A 的方法

实现继承的方法有多种,以下为常见的两种:

  1. 原型链继承
javascript 复制代码
function A() {
  this.name = 'A';
}

A.prototype.sayHello = function() {
  console.log('Hello from A');
};

function B() {
  A.call(this); // 继承属性
  this.name = 'B';
}

B.prototype = Object.create(A.prototype); // 继承方法
B.prototype.constructor = B;

const b = new B();
b.sayHello(); // 输出: "Hello from A"
console.log(b.name); // "B"
  1. 寄生组合继承
javascript 复制代码
function A() {
  this.name = 'A';
}

A.prototype.sayHello = function() {
  console.log('Hello from A');
};

function B() {
  A.call(this);
  this.name = 'B';
}

(function() {
  const Super = function() {};
  Super.prototype = A.prototype;
  B.prototype = new Super();
  B.prototype.constructor = B;
})();

const b = new B();
b.sayHello(); // 输出: "Hello from A"
console.log(b.name); // "B"

总结:

  • 原型链继承:简单易懂,但存在引用类型属性共享的问题。
  • 寄生组合继承:结合构造函数继承和原型链继承,避免了原型链继承的问题,推荐使用。

12. 写一个获取非行间样式的函数

获取元素非行内样式的函数示例:

javascript 复制代码
function getStyle(obj, attr) {
  if (window.getComputedStyle) {
    // 标准浏览器
    return window.getComputedStyle(obj, null).getPropertyValue(attr);
  } else if (obj.currentStyle) {
    // IE
    return obj.currentStyle[attr];
  }
  return null;
}

// 设置样式
function setStyle(obj, attr, value) {
  obj.style[attr] = value;
}

// 使用示例
const element = document.getElementById('myElement');
const fontSize = getStyle(element, 'font-size');
console.log(fontSize); // e.g., "16px"

setStyle(element, 'color', 'blue');

说明:

  • 获取样式

    • 标准浏览器 :使用 window.getComputedStyle
    • IE6-8 :使用 element.currentStyle
  • 设置样式

    • 直接通过 element.style 属性设置。

13. 事件委托是什么

事件委托(Event Delegation) 是一种利用事件冒泡机制,将事件处理器绑定到父元素上,而不是每个子元素上,从而提高性能和简化代码的方法。

原理:

  • 事件冒泡:事件从目标元素向上冒泡到父元素。
  • 委托处理 :父元素通过判断事件目标 (event.target) 来处理子元素的事件。

优点:

  • 减少事件处理器:避免为每个子元素绑定事件处理器,节省内存和提高性能。
  • 动态元素支持:自动支持动态添加的子元素,无需重新绑定事件。

示例:

html 复制代码
<ul id="parentList">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>
javascript 复制代码
document.getElementById('parentList').addEventListener('click', function(event) {
  const target = event.target;
  if (target && target.nodeName === 'LI') {
    alert('Clicked on ' + target.textContent);
  }
});

总结:

  • 事件委托 通过绑定单一的事件处理器到父元素,管理所有子元素的事件,提升代码效率和可维护性。

14. 闭包是什么,有什么特性,对页面有什么影响

闭包(Closure) 是指在函数内部创建的函数,可以访问其外部函数的作用域,即使外部函数已经执行完毕。

特性:

  1. 访问外部函数的变量:闭包可以访问并操作外部函数的变量和参数。
  2. 保持变量状态:即使外部函数执行完毕,闭包仍然保持对变量的引用。
  3. 私有变量:通过闭包,可以创建私有变量和方法,增强封装性。

影响:

  • 数据隐私:通过闭包可以保护变量不被外部直接访问和修改。
  • 内存管理:过多的闭包可能导致内存泄漏,因为它们保持对外部变量的引用。
  • 功能扩展:闭包在模块化开发、函数式编程等方面具有重要应用。

示例:

javascript 复制代码
function outerFunction() {
  var count = 0;
  function innerFunction() {
    count++;
    console.log(count);
  }
  return innerFunction;
}

const counter = outerFunction();
counter(); // 输出: 1
counter(); // 输出: 2

总结:

  • 闭包 是理解 JavaScript 作用域和函数特性的关键,合理使用闭包可以提升代码的灵活性和封装性,但需注意内存管理。

15. 如何阻止事件冒泡和默认事件

阻止事件冒泡(Event Bubbling):

  1. 标准方法

    javascript 复制代码
    event.stopPropagation();
  2. IE 兼容方法

    javascript 复制代码
    event.cancelBubble = true;

阻止默认事件(Prevent Default Behavior):

  1. 标准方法

    javascript 复制代码
    event.preventDefault();
  2. IE 兼容方法

    javascript 复制代码
    event.returnValue = false;

示例:

javascript 复制代码
element.addEventListener('click', function(event) {
  // 阻止冒泡
  if (event.stopPropagation) {
    event.stopPropagation();
  } else {
    event.cancelBubble = true; // IE
  }

  // 阻止默认行为
  if (event.preventDefault) {
    event.preventDefault();
  } else {
    event.returnValue = false; // IE
  }
});

总结:

  • 使用 stopPropagation()preventDefault() 来阻止事件冒泡和默认行为,兼容不同浏览器的写法确保功能一致。

16. 添加、删除、替换、插入到某个节点的方法

常用的 DOM 操作方法:

  1. 创建新节点

    • createDocumentFragment():创建一个空的文档片段,用于批量添加节点。

      javascript 复制代码
      const fragment = document.createDocumentFragment();
    • createElement():创建一个新的元素节点。

      javascript 复制代码
      const newDiv = document.createElement('div');
    • createTextNode():创建一个新的文本节点。

      javascript 复制代码
      const text = document.createTextNode('Hello World');
  2. 添加、删除、替换、插入

    • appendChild():在父节点末尾添加一个子节点。

      javascript 复制代码
      parent.appendChild(child);
    • removeChild():从父节点中移除一个子节点。

      javascript 复制代码
      parent.removeChild(child);
    • replaceChild():用一个新节点替换父节点中的一个子节点。

      javascript 复制代码
      parent.replaceChild(newChild, oldChild);
    • insertBefore():在指定子节点之前插入一个新节点。

      javascript 复制代码
      parent.insertBefore(newChild, referenceChild);
  3. 查找节点

    • getElementsByTagName():通过标签名称查找元素。

      javascript 复制代码
      const divs = document.getElementsByTagName('div');
    • getElementsByName() :通过元素的 name 属性查找元素。

      javascript 复制代码
      const inputs = document.getElementsByName('username');
    • getElementById() :通过元素的 id 查找元素。

      javascript 复制代码
      const header = document.getElementById('header');

总结:

  • 使用 DOM 方法进行节点操作可以动态改变网页内容和结构,提升用户体验和交互性。

17. 解释 JSONP 的原理,以及为什么不是真正的 AJAX

JSONP(JSON with Padding) 是一种跨域请求数据的技术,通过动态创建 <script> 标签并使用回调函数来实现数据的跨域获取。

原理:

  1. 创建 <script> 标签 :在页面中动态添加一个 <script> 标签,设置其 src 属性指向跨域的数据源,并包含回调函数名称。

    javascript 复制代码
    const script = document.createElement('script');
    script.src = 'https://api.example.com/data?callback=handleData';
    document.body.appendChild(script);
  2. 服务器返回 JSONP 格式的数据:服务器响应时,将数据包裹在回调函数中。

    javascript 复制代码
    handleData({"name": "Alice", "age": 25});
  3. 回调函数执行:页面中的回调函数接收数据并处理。

    javascript 复制代码
    function handleData(data) {
      console.log(data.name); // "Alice"
    }

为什么不是真正的 AJAX:

  • 基于 <script> 标签 :JSONP 使用 <script> 标签加载数据,而 AJAX 使用 XMLHttpRequest 对象。
  • 仅支持 GET 请求:JSONP 只能进行 GET 请求,无法执行其他类型的 HTTP 请求(如 POST)。
  • 安全性问题:JSONP 允许执行任意 JavaScript 代码,存在 XSS 攻击风险。

总结:

  • JSONP 是一种跨域数据获取的替代方案,但因其安全性和功能限制,不属于标准的 AJAX 技术。
  • 现代跨域方案 :推荐使用 CORS(跨域资源共享),提供更安全和灵活的跨域请求支持。

18. JavaScript 的本地对象,内置对象和宿主对象

JavaScript 对象分类:

  1. 本地对象(Native Objects)

    • 定义 :JavaScript 语言本身提供的对象,可以通过 new 关键字实例化。
    • 示例
      • 构造函数ArrayObjectFunctionDateRegExp

      • 实例

        javascript 复制代码
        const arr = new Array();
        const obj = new Object();
        const func = new Function();
        const date = new Date();
        const regex = new RegExp('pattern');
  2. 内置对象(Built-in Objects)

    • 定义 :JavaScript 环境预定义的对象,不能通过 new 关键字实例化。
    • 示例
      • 全局对象MathJSONPromise

      • 对象实例

        javascript 复制代码
        const pi = Math.PI;
        const json = JSON.stringify({ name: 'Alice' });
        const promise = new Promise((resolve, reject) => {});
  3. 宿主对象(Host Objects)

    • 定义:由宿主环境(如浏览器、Node.js)提供的对象,用于与环境交互。
    • 示例
      • 浏览器宿主对象windowdocumentnavigatorlocation
      • Node.js 宿主对象processBufferfs

总结:

  • 本地对象:JavaScript 内置的可实例化对象。
  • 内置对象:JavaScript 环境提供的预定义对象,无法实例化。
  • 宿主对象:宿主环境提供的对象,用于与环境交互。

19. document loaddocument ready 的区别

document.onloaddocument.ready 的区别:

  1. document.onloadwindow.onload

    • 触发时机:在整个页面(包括所有依赖资源如图片、样式表、脚本等)加载完成后触发。

    • 使用方法

      javascript 复制代码
      window.onload = function() {
        // 页面完全加载后执行
      };
  2. document.ready(jQuery 的 $(document).ready()

    • 触发时机:在 DOM 树构建完成后触发,不等待图片、样式表等资源加载。

    • 使用方法

      javascript 复制代码
      $(document).ready(function() {
        // DOM 树构建完成后执行
      });
    • 原生实现

      javascript 复制代码
      document.addEventListener('DOMContentLoaded', function() {
        // DOM 树构建完成后执行
      });

区别与意义:

  • 执行时机

    • window.onload 适用于需要确保所有资源加载完成后执行的操作。
    • document.ready 适用于需要在 DOM 准备好后立即执行的操作,如绑定事件、操作 DOM 元素。
  • 性能与用户体验

    • document.ready 提升页面响应速度,用户可以更早地与页面交互。
    • window.onload 可能会延迟执行,影响用户体验。

总结:

  • document.ready:适用于大多数 DOM 操作,提升页面交互性。
  • window.onload:适用于需要所有资源加载完成后执行的任务。

20. ===== 的不同

==(双等号)与 ===(三等号)的区别:

  • ==(相等运算符)

    • 特性:进行类型转换后再比较,可能导致不同类型的值相等。

    • 示例

      javascript 复制代码
      5 == '5'; // true
      null == undefined; // true
      0 == false; // true
  • ===(严格相等运算符)

    • 特性 :不进行类型转换,只有在类型和值都相等时返回 true

    • 示例

      javascript 复制代码
      5 === '5'; // false
      null === undefined; // false
      0 === false; // false

优先级:

  • === 的优先级高于 ==
  • === 优先级高于 !important

总结:

  • 使用 ===:推荐使用严格相等运算符,避免类型转换带来的潜在问题,提升代码可靠性。
  • 使用 ==:仅在确实需要类型转换时使用,需谨慎处理。

21. JavaScript 的同源策略

同源策略(Same-Origin Policy) 是浏览器的安全机制,限制从一个源加载的文档或脚本如何与来自不同源的资源进行交互。

定义:

  • 同源 :协议(如 httphttps)、主机(如 www.example.com)、端口(如 :80:443)都相同。
  • 不同源:只要协议、主机或端口有一个不同,即为不同源。

作用:

  • 防止恶意脚本在未经授权的情况下访问或篡改其他网站的敏感数据。
  • 限制跨域的 AJAX 请求,确保数据的安全性和隐私。

示例:

  • 同源

    • http://www.example.com/page1.html
    • http://www.example.com/page2.html
  • 不同源

    • http://www.example.comhttps://www.example.com
    • http://www.example.comhttp://api.example.com
    • http://www.example.comhttp://www.example.com:8080

绕过同源策略的方法:

  1. CORS(跨域资源共享) :通过服务器设置响应头 Access-Control-Allow-Origin 允许跨域请求。
  2. JSONP :利用 <script> 标签的跨域能力,传递回调函数处理数据。
  3. 代理服务器:通过同源的服务器代理跨域请求。

总结:

  • 同源策略是浏览器安全的重要组成部分,理解其机制有助于开发安全和高效的前端应用。

22. 编写一个数组去重的方法

示例:使用对象存储法

javascript 复制代码
function removeDuplicates(arr) {
  const seen = {};
  const result = [];
  for (let i = 0; i < arr.length; i++) {
    const item = arr[i];
    if (!seen[item]) {
      seen[item] = true;
      result.push(item);
    }
  }
  return result;
}

// 使用示例
const array = [1, 2, 2, 3, 4, 4, 5];
const uniqueArray = removeDuplicates(array);
console.log(uniqueArray); // [1, 2, 3, 4, 5]

说明:

  • 使用一个对象 seen 来记录已经出现过的元素。
  • 遍历数组,只有当元素未在 seen 中出现时,才添加到结果数组中。

其他方法:

  1. 使用 Set(ES6)

    javascript 复制代码
    function removeDuplicates(arr) {
      return [...new Set(arr)];
    }
    
    const array = [1, 2, 2, 3, 4, 4, 5];
    const uniqueArray = removeDuplicates(array);
    console.log(uniqueArray); // [1, 2, 3, 4, 5]
  2. 使用 filterindexOf

    javascript 复制代码
    function removeDuplicates(arr) {
      return arr.filter((item, index) => arr.indexOf(item) === index);
    }
    
    const array = [1, 2, 2, 3, 4, 4, 5];
    const uniqueArray = removeDuplicates(array);
    console.log(uniqueArray); // [1, 2, 3, 4, 5]

总结:

  • 多种方法可以实现数组去重,选择适合项目需求和浏览器兼容性的方式。

23. String 对象的方法不包括哪一个

选项:

a) charAt()

b) substring()

c) length

d) toUpperCase()

答案: c) length

解释:

  • lengthString 对象的属性,不是方法。
  • 其他选项都是 String 对象的方法。

24. 关于 setTimeout("check", 10) 中说法正确的是

选项:

a) 程序循环执行 10 次

b) check 函数每 10 秒执行一次

c) 10 作为参数传给函数 check

d) check 函数每 10 毫秒执行一次

答案: d) check 函数每 10 毫秒执行一次

解释:

  • setTimeout("check", 10) 会在 10 毫秒后执行 check 函数一次。
  • 若要循环执行,需要使用 setInterval 或在回调中再次调用 setTimeout

25. 以下哪个单词不属于 JavaScript 关键字

选项:

a) with

b) parent

c) class

d) void

答案: c) class

解释:

  • class 是 ES6 引入的关键字,用于定义类,但在早期的 JavaScript 中不属于关键字。
  • parent 在 JavaScript 中不是关键字,是一个全局变量属性。

注意:不同的 JavaScript 版本中,关键字的定义可能有所变化。


前端工程师面试心得

基本知识

作为一名前端工程师,以下知识点是必须掌握的:

  1. DOM 结构

    • 理解节点之间的关系:父子关系、兄弟关系等。
    • 如何在节点之间任意移动 :使用 DOM 方法如 appendChildinsertBefore 等。
  2. DOM 操作

    • 添加、移除、移动、复制、创建和查找节点
    • 常用方法createElementcreateTextNodeappendChildremoveChildreplaceChildinsertBeforegetElementByIdgetElementsByTagNamegetElementsByName
  3. 事件

    • 如何使用事件:绑定事件处理函数、事件对象的使用。
    • IE 和 DOM 事件模型的主要差别:事件绑定方法、事件对象获取方式、事件流控制方法等。
  4. XMLHttpRequest

    • 定义:用于在后台与服务器交换数据。
    • 完整的 GET 请求流程 :创建 XMLHttpRequest 对象、配置请求、发送请求、处理响应、检测错误。
  5. 严格模式与混杂模式

    • 触发方式:通过正确或错误的 Doctype 声明。
    • 区别:盒模型、渲染行为等。
  6. 盒模型

    • 外边距(Margin)、内边距(Padding)、边框(Border) 的关系。
    • IE8 以下的浏览器盒模型差异:内容宽高是否包含内边距和边框。
  7. 块级元素与行内元素

    • CSS 控制display 属性的使用,如 blockinlineinline-block
    • 合理使用:根据内容语义和布局需求选择合适的元素类型。
  8. 浮动元素

    • 使用方法float 属性的应用。
    • 问题:浮动导致父容器高度塌陷、元素重叠等。
    • 解决方法:清除浮动、使用 Flexbox 等现代布局方法。
  9. HTML 与 XHTML

    • 区别:严格的语法规则、标签闭合、标签小写等。
    • 选择建议:推荐使用 HTML5,因其更灵活且广泛支持。
  10. JSON

    • 定义:轻量级的数据交换格式。
    • 作用:在客户端和服务器之间传递数据。
    • 用途:配置文件、API 数据响应等。
    • 设计结构:键值对形式,支持嵌套和数组。

少量提问

面试时,应尽量减少提问数量,但每个问题深入考察多个知识点。

示例问题:

  • 问题:现在有一个正显示着 Yahoo! 股票价格的页面。页面上有一个按钮,你可以单击它来刷新价格,但不会重新加载页面。请你描述一下实现这个功能的过程,假设服务器会负责准备好正确的股票价格数据。

考察知识点:

  • DOM 结构:如何获取和操作 DOM 元素。
  • 事件处理:绑定按钮点击事件。
  • XMLHttpRequest:发送 AJAX 请求获取数据。
  • JSON:处理服务器返回的数据格式。
  • 动态更新:将新数据更新到页面中。

深入提问:

  • 替代方法:如果不使用 AJAX,你还能如何实现数据刷新?
  • 安全问题:如何确保数据传输的安全性?
  • 性能优化:如何优化数据请求和页面更新的性能?

解决问题

关键能力:找出问题的多种解决方案,理解底层机制。

重要性:

  • 应对复杂问题:如 IE6 的兼容性问题,能灵活应对不同浏览器的差异。
  • 创新思维:能够在既有方法受限时,创造新的解决方案。
  • 技术掌握:深入理解浏览器技术,能高效解决实际开发中的问题。

示例:

  • 问题:IE6 中浮动元素的双倍边距问题。
  • 解决方案 1 :设置 display: inline; 使 IE6 忽略外边距的倍增。
  • 解决方案 2:使用 CSS hack,针对 IE6 单独设置样式。
  • 解决方案 3:改变布局方式,避免使用浮动。

有激情

前端工程师需要对所做的工作充满热情,持续学习和自我提升。

识别方法:

  • 询问兴趣领域:如 "目前你对什么 Web 技术最感兴趣?"
  • 了解学习习惯:是否主动学习新技术、关注前沿趋势。
  • 探讨项目经验:是否在项目中展示出对技术的深入理解和应用。

重要性:

  • 技术更新迅速:持续学习才能跟上技术发展。
  • 解决问题的动力:热情驱动工程师积极解决复杂问题,提升项目质量。

最后一点

基础知识的重要性:

  • 掌握基本知识:如 DOM 操作、事件处理、AJAX 等,确保能够胜任工作。
  • 深入理解:不仅仅是记忆方法,更要理解其原理和应用场景。
  • 扩展知识面:结合项目需求,学习相关技术和工具,提升综合能力。

建议:

  • 系统学习:通过系统的学习和实践,形成自己的知识体系。
  • 实战经验:通过项目经验,深化对知识点的理解和应用。
  • 持续改进:在工作中不断反思和优化,提高技术水平和工作效率。

其他面试题

百度

  1. JavaScript 有哪几种数据类型

    • 答案ObjectNumberFunctionBooleanundefined
  2. alttitle 的区别

    • 答案alt 用于图片无法显示时提供替代文本,title 用于提供元素的额外信息,通常在鼠标悬停时显示。
  3. 下面 CSS 标签在 JavaScript 中调用应如何拼写,border-left-color-moz-

    • 答案 :在 JavaScript 中,CSS 属性使用驼峰命名法,例如 borderLeftColorMozTransform(带前缀的属性)。
  4. 动态打印 yyyy-mm-dd hh:mm:ss

    • 答案

      javascript 复制代码
      function formatDate(date) {
        const pad = (n) => n < 10 ? '0' + n : n;
        const year = date.getFullYear();
        const month = pad(date.getMonth() + 1);
        const day = pad(date.getDate());
        const hours = pad(date.getHours());
        const minutes = pad(date.getMinutes());
        const seconds = pad(date.getSeconds());
        return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
      }
      
      setInterval(() => {
        console.log(formatDate(new Date()));
      }, 1000);
  5. 如何提高网页的运行速度

    • 答案
      • 文件合并与压缩
      • 使用 CDN 托管资源
      • 图片优化与使用 CSS Sprites
      • 启用浏览器缓存
      • 延迟加载非关键资源
  6. JavaScript 中如何对一个对象进行深度 clone

    • 答案

      javascript 复制代码
      function deepClone(obj) {
        if (obj === null || typeof obj !== 'object') return obj;
        if (obj instanceof Date) return new Date(obj);
        if (obj instanceof Array) {
          const arrCopy = [];
          for (let i = 0; i < obj.length; i++) {
            arrCopy[i] = deepClone(obj[i]);
          }
          return arrCopy;
        }
        const objCopy = {};
        for (let key in obj) {
          if (obj.hasOwnProperty(key)) {
            objCopy[key] = deepClone(obj[key]);
          }
        }
        return objCopy;
      }
      
      const original = { a: 1, b: { c: 2 } };
      const copy = deepClone(original);
      console.log(copy); // { a: 1, b: { c: 2 } }
  7. Flash 中 ActionScript 2.0 和 ActionScript 3.0 面向对象的异同

    • 答案
      • ActionScript 2.0
        • 基于原型的面向对象模型。
        • 支持类和继承,但功能较为有限。
      • ActionScript 3.0
        • 基于类的面向对象模型,严格的类结构。
        • 支持接口、多继承的部分功能、命名空间等高级特性。
        • 更高的性能和更强的类型检查。
  8. 编写一个方法,求一个字符串的字节长度

    • 答案

      javascript 复制代码
      function byteLength(str) {
        let length = 0;
        for (let i = 0; i < str.length; i++) {
          const code = str.charCodeAt(i);
          if (code <= 0x7f) {
            length += 1;
          } else if (code <= 0x7ff) {
            length += 2;
          } else if (code >= 0xd800 && code <= 0xdfff) {
            // Surrogate pair
            length += 4;
            i++;
          } else {
            length += 3;
          }
        }
        return length;
      }
      
      console.log(byteLength("Hello")); // 5
      console.log(byteLength("你好")); // 6
      console.log(byteLength("😀")); // 4
  9. 如何控制 alert 中的换行

    • 答案
      • 使用转义字符 \n 实现换行。

      • 示例:

        javascript 复制代码
        alert("这是第一行\n这是第二行");
  10. 解释 document.getElementById("ElementID").style.fontSize = "1.5em"

    • 答案
      • document.getElementById("ElementID") :获取页面中 idElementID 的元素。
      • .style.fontSize = "1.5em" :设置该元素的字体大小为 1.5em,即相对于父元素字体大小的 1.5 倍。
  11. 将一个类似图中的效果分离成 CSS 和 HTML

    • 答案
      • HTML

        html 复制代码
        <div class="container">
          <div class="box">内容</div>
        </div>
      • CSS

        css 复制代码
        .container {
          display: flex;
          justify-content: center;
          align-items: center;
          height: 100vh;
        }
        
        .box {
          width: 200px;
          height: 200px;
          background-color: #f0f0f0;
          border: 1px solid #ccc;
          display: flex;
          justify-content: center;
          align-items: center;
        }
  12. 按照格式 xxxx年xx月xx日xx时xx分xx秒 动态显示时间,要求不足 10 的补 0

    • 答案

      javascript 复制代码
      function padZero(num) {
        return num < 10 ? '0' + num : num;
      }
      
      function getCurrentTime() {
        const now = new Date();
        const year = now.getFullYear();
        const month = padZero(now.getMonth() + 1);
        const day = padZero(now.getDate());
        const hours = padZero(now.getHours());
        const minutes = padZero(now.getMinutes());
        const seconds = padZero(now.getSeconds());
        return `${year}年${month}月${day}日${hours}时${minutes}分${seconds}秒`;
      }
      
      setInterval(() => {
        console.log(getCurrentTime());
      }, 1000);
  13. 编写一个方法,去掉一个数组的重复元素

    • 答案

      javascript 复制代码
      function removeDuplicates(arr) {
        const seen = {};
        const result = [];
        for (let i = 0; i < arr.length; i++) {
          const item = arr[i];
          if (!seen[item]) {
            seen[item] = true;
            result.push(item);
          }
        }
        return result;
      }
      
      const array = [1, 2, 2, 3, 4, 4, 5];
      const uniqueArray = removeDuplicates(array);
      console.log(uniqueArray); // [1, 2, 3, 4, 5]
  14. 最近看的一篇 JavaScript 的文章是?

    • 答案:可以回答最近阅读的一篇技术博客或文章,并简要描述其内容和收获。
  15. 你如何去实现这个 Tabview

    • 答案:描述使用 HTML、CSS 和 JavaScript 实现标签页切换的思路,例如通过事件监听切换显示的内容区。
  16. 常使用的库有哪些? 常用的前端开发工具? 开发过什么应用或组件?

    • 常用库

      • jQuery
      • React
      • Vue.js
      • Angular
      • Lodash
    • 常用前端开发工具

      • 编辑器:VSCode、Sublime Text、WebStorm
      • 调试工具:Chrome DevTools、Firebug
      • 版本控制:Git、SVN
      • 构建工具:Webpack、Gulp、Grunt
      • 图形工具:Photoshop、Figma、Sketch
    • 开发过的应用或组件

      • 开发过响应式网页、单页应用(SPA)、UI 组件库等。

腾讯

  1. 要动态改变层中内容可以使用的方法有哪些(AB)

    • 选项

      a) innerHTML

      b) innerText

      c) 通过设置层的隐藏和显示来实现

      d) 通过设置层的样式属性的 display 属性

    • 答案:A、B

  2. 当按键盘 A 时,使用 onKeyDown 事件打印 event.keyCode 的结果是(A)

    • 选项

      a) 65

      b) 13

      c) 97

      d) 37

    • 答案:A

  3. 在 JavaScript 里,下列选项中不属于数组方法的是(B)

    • 选项

      a) sort()

      b) length()

      c) concat()

      d) reverse()

    • 答案:B

  4. 下列哪一个选项可以用来检索被选定的选项的索引号?(B)

    • 选项

      a) disabled

      b) selectedIndex

      c) option

      d) multiple

    • 答案:B

  5. 希望图片具有"提交"按钮同样的功能,该如何编写表单提交?(A)

    • 选项

      a) 在图片的 onClick 事件中手动提交

      b) 在图片上添加 onSubmit 事件

      c) 在图片的 onSubmit 事件中手动提交

      d) 在表单中自动提交

    • 答案:A

  6. 使 div 层和文本框处在同一行的代码正确的是(D)

  7. 下列选项中,描述正确的是(选择两项)(A、D)

    • 选项

      a) options.add(new Option('a', 'A')) 可以动态添加一个下拉列表选项

      b) option.add(new Option('a', 'A')) 可以动态添加一个下拉列表选项

      c) new Option('a', 'A')'a' 表示列表选项的值,'A' 用于在页面中显示

      d) new Option('a', 'A')'A' 表示列表选项的值,'a' 用于在页面中显示

    • 答案:A、D

  8. var emp = new Array(3); for(var i in emp) 以下答案中能与 for 循环代码互换的是:(选择一项)(D)

    • 答案:D
  9. 制作级联菜单功能时调用的是下拉列表框的(A)事件。

    • 选项

      a) onChange

      b) onFocus

      c) selected

      d) onClick

    • 答案:A

  10. 下列声明数组的语句中,错误的选项是(C)。

    • 选项

      a) var arry = new Array()

      b) var arry = new Array(3)

      c) var arry[] = new Array(3)(4)

      d) var arry = new Array('3', '4')

    • 答案:C

  11. 下列属性哪一个能够实现层的隐藏?(C)

    • 选项

      a) display: false

      b) display: hidden

      c) display: none

      d) display: " "

    • 答案:C

  12. 下列哪一个选项不属于 document 对象的方法?(D)

    • 选项

      a) focus()

      b) getElementById()

      c) getElementsByName()

      d) bgColor()

    • 答案:D

  13. 下列哪项是按下键盘事件(A、B)

    • 选项

      a) onKeyDown

      b) onKeyPress

      c) keyCode

      d) onMouseOver

    • 答案:A、B

  14. JavaScript 进行表单验证的目的是(B)

    • 选项

      a) 把用户的正确信息提交给服务器

      b) 检查提交的数据必须符合实际

      c) 使得页面变得美观、大方

      d) 减轻服务器端的压力

    • 答案:B

  15. display 属性值的常用取值不包括(C)。

    • 选项

      a) inline

      b) block

      c) hidden

      d) none

    • 答案:C

  16. 以下有关 pixelTop 属性与 top 属性的说法正确的是。(D)

    • 选项

      a) 都是 Location 对象的属性

      b) 使用时返回值都是字符串

      c) 都是返回以像素为单位的数值

      d) 以上都不对

    • 答案:D

  17. 使用 open 方法打开具有浏览器工具条、地址栏、菜单栏的窗口,下列选项正确的是(D)

    • 选项

      a) open("x.html","HI","toolbas=1,scrollbars=1,status=1");

      b) open("HI","scrollbars=1,location=1,status=1");

      c) open("x.html","status=yes,menubar=1,location=1");

      d) open("x.html","HI","toolbas=yes,menubar=1,location=1");

    • 答案:D

  18. 下面关闭名为 mydiv 的层的代码正确的是(C)。

    • 选项

      a) document.getElementByIdx_x_x_x(mydiv).style.display="none";

      b) document.getElementByIdx_x_x_x("mydiv").style.display=none;

      c) document.getElementByIdx_x_x_x("mydiv").style.display="none";

      d) document.getElementByIdx_x_x_x("mydiv").style.display=="none";

    • 答案:C

  19. 为什么要使用 div + CSS 布局

    • 答案
      • 形式与内容分离:通过 CSS 控制布局和样式,使 HTML 只关注内容。
      • 减少页面代码:通过样式表集中管理样式,减少重复代码。
      • 提高页面加载速度:统一的样式表可以被浏览器缓存,减少资源加载时间。
      • 结构清晰,有利于 SEO:语义化的 HTML 结构有助于搜索引擎优化。
      • 缩短改版时间,布局更方便:通过修改 CSS 即可实现整体布局的调整,简化维护工作。
      • 一次设计,多次使用:统一的 CSS 样式可以被多个页面复用,提升开发效率。
  20. Block 元素的特点是什么? 哪些元素默认为 Block 元素

    • 特点

      • 总是在新行上开始。
      • 宽度默认占满其父容器的整个可用宽度,除非明确设置。
      • 可以设置宽高、内边距、外边距等。
    • 默认的 Block 元素

      • <div><p><h1>-<h6><ul><ol><li><form><table><tr><td>
  21. Inline 元素的特点是什么? 哪些元素属于 Inline 元素?

    • 特点

      • 和其他元素在同一行内显示。
      • 宽度和高度不可设置,只能由内容决定。
      • 不能设置上下边距和内边距的垂直方向。
    • 属于 Inline 元素的有

      • <span><a><img><em><strong><input><textarea><select><label>
  22. JavaScript 中表达式 parseInt("X8X8") + parseFloat('8') 的结果是什么?(C)

    • 选项

      a) 8 + 8

      b) 88

      c) 16

      d) "8" + '8'

    • 答案:C

    解释

    • parseInt("X8X8"):由于字符串以非数字字符 X 开头,返回 NaN
    • parseFloat('8'):返回 8
    • NaN + 8:结果为 NaN
    • 正确答案 应为 NaN,可能题目有误。
  23. String 对象的方法不包括哪一个(C)

    • 选项

      a) charAt()

      b) substring()

      c) length

      d) toUpperCase()

    • 答案:C

    解释

    • lengthString 对象的属性,不是方法。
    • 其他选项都是 String 对象的方法。
  24. 关于 setTimeout("check", 10) 中说法正确的是(D)

    • 选项

      a) 程序循环执行 10 次

      b) check 函数每 10 秒执行一次

      c) 10 作为参数传给函数 check

      d) check 函数每 10 毫秒执行一次

    • 答案:D

    解释

    • setTimeout("check", 10) 会在 10 毫秒后执行一次 check 函数。
    • 要循环执行需要使用 setInterval 或在回调中再次调用 setTimeout
  25. 以下哪个单词不属于 JavaScript 关键字:(C)

    • 选项

      a) with

      b) parent

      c) class

      d) void

    • 答案:C

    解释

    • class 是 ES6 引入的关键字,用于定义类。
    • parent 在 JavaScript 中不是关键字,是一个全局变量属性。

前端开发工程师面试知识点大纲

HTML & CSS

  • 对 WEB 标准的理解
  • 浏览器内核差异
  • 兼容性与 hack 技术
  • CSS 基本功:布局、盒子模型、选择器优先级及使用
  • HTML5、CSS3、移动端适应

JavaScript

  • 数据类型、面向对象、继承、闭包
  • 插件、作用域、跨域
  • 原型链、模块化、自定义事件
  • 内存泄漏、事件机制、异步装载回调
  • 模板引擎、Node.js、JSON、AJAX 等

其他

  • HTTP、安全、正则、优化、重构
  • 响应式设计、移动端开发、团队协作
  • 可维护性、SEO、用户体验设计(UED)、架构设计、职业生涯规划

必须掌握的知识点

  1. DOM 结构:节点关系与操作。
  2. DOM 操作:添加、移除、移动、复制、创建和查找节点。
  3. 事件:事件使用及 IE 和 DOM 事件模型差异。
  4. XMLHttpRequest:完整的 GET 请求执行及错误检测。
  5. 严格模式与混杂模式:触发方式及区别。
  6. 盒模型:外边距、内边距和边框的关系,IE8 以下盒模型差异。
  7. 块级元素与行内元素:CSS 控制与合理使用。
  8. 浮动元素:使用方法、问题与解决方案。
  9. HTML 与 XHTML:区别及使用建议。
  10. JSON:作用、用途及设计结构。

其他面试题

百度

(内容略,参考上文百度部分)

腾讯

(内容略,参考上文腾讯部分)


前言

本文总结了一些优质的前端面试题(多数源于网络),初学者阅后也要用心钻研其中的原理,重要知识需要系统学习,透彻学习,形成自己的知识链。万不可投机取巧,只求面试过关是错误的!

面试有几点需注意:

  1. 题目类型:技术视野、项目细节、理论知识题,算法题,开放性题,案例题。
  2. 进行追问:确保深入理解,应对关联知识的扩展。
  3. 态度重要:是否愿意与面试官共事,展现职业素养。
  4. 激情驱动:对 Web 开发充满热情,持续学习和自我提升。

面试技巧:

  • 少量提问:每个问题深入考察多个知识点,提升区分度和深度。
  • 解决问题能力:展示多种解决方案,理解底层机制。
  • 有激情:对所做工作充满热情,主动学习新技术。
  • 基础知识扎实:掌握核心知识点,确保能独立完成工作。

总结:

通过掌握上述知识点和面试技巧,前端工程师候选人可以更好地准备面试,展示自己的技术能力和职业素养,提升面试通过率。

参考资料

相关推荐
PleaSure乐事19 分钟前
Ant-Dseign-Pro如何去国际化及删除oneapi.json后出现程序直接结束问题的解决方案
前端·javascript·react.js·前端框架·json·oneapi·antdesignpro
榴莲千丞38 分钟前
第七章利用CSS和多媒体美化页面
前端·css·1024程序员节
奶糖 肥晨1 小时前
vue的路由的两种模式 hash与history 详细讲解
前端·vue.js·哈希算法
奶糖 肥晨1 小时前
react基础之reactHooks
前端·javascript·react.js
放逐者-保持本心,方可放逐1 小时前
vue3-ref 和 reactive
前端·javascript·vue.js
星河路漫漫1 小时前
ES6面试题:(第二天)
开发语言·前端·javascript
喝旺仔la2 小时前
Django+Vue全栈开发旅游网项目景点详情
前端·javascript·vue.js
snakeshe10102 小时前
深入理解 Web Workers:提升 Web 应用性能的利器
前端
每天都要喝奶茶2 小时前
vue3uniapp实现自定义拱形底部导航栏,解决首次闪烁问题
前端·vue.js·uni-app
May_Xu_2 小时前
vue3+less使用主题定制(多主题定制)可切换主题
前端·javascript·vue.js·vue·less·css3