前言
本文整理了一系列前端工程师面试中常见的 HTML、CSS 和 JavaScript 问题及其答案,涵盖基础知识、常见问题及面试技巧。适用于准备前端开发职位面试的候选人参考。
 
目录
- 前言
 - HTML & CSS
 - 1. 对 WEB 标准以及 W3C 的理解与认识
 - 2. XHTML 和 HTML 有什么区别
 - 3. Doctype? 严格模式与混杂模式
 - 4. 行内元素有哪些? 块级元素有哪些? CSS 的盒模型?
 - 5. CSS 引入的方式有哪些? `link` 和 `@import` 的区别是?
 - 6. CSS 选择符有哪些? 哪些属性可以继承? 优先级算法如何计算? 内联和 `!important` 哪个优先级高?
 - 7. 前端页面有哪三层构成,分别是什么? 作用是什么?
 - 8. CSS 的基本语句构成是?
 - 9. 你做的页面在哪些浏览器测试过? 这些浏览器的内核分别是什么? 经常遇到的浏览器的兼容性有哪些? 怎么会出现? 解决方法是什么?
 - 10. 写出几种 IE6 BUG 的解决方法
 - 11. 标签上 `title` 与 `alt` 属性的区别是什么?
 - 12. 描述 CSS Reset 的作用和用途
 - 13. 解释 CSS Sprites,如何使用
 - 14. 浏览器标准模式和怪异模式之间的区别是什么?
 - 15. 你如何对网站的文件和资源进行优化?
 - 16. 什么是语义化的 HTML?
 - 17. 清除浮动的几种方式,各自的优缺点
 
- JavaScript
 - 1. JavaScript 的 `typeof` 返回哪些数据类型
 - 2. 例举 3 种强制类型转换和 2 种隐式类型转换
 - 3. `split()` 和 `join()` 的区别
 - 4. 数组方法 `pop()`、`push()`、`unshift()`、`shift()`
 - 5. 事件绑定和普通事件有什么区别
 - 6. IE 和 DOM 事件流的区别
 - 7. IE 和标准下有哪些兼容性的写法
 - 8. AJAX 请求的时候 GET 和 POST 方式的区别
 - 9. `call` 和 `apply` 的区别
 - 10. AJAX 请求时,如何解析 JSON 数据
 - 11. B 继承 A 的方法
 - 12. 写一个获取非行间样式的函数
 - 13. 事件委托是什么
 - 14. 闭包是什么,有什么特性,对页面有什么影响
 - 15. 如何阻止事件冒泡和默认事件
 - 16. 添加、删除、替换、插入到某个节点的方法
 - 17. 解释 JSONP 的原理,以及为什么不是真正的 AJAX
 - 18. JavaScript 的本地对象,内置对象和宿主对象
 - 19. `document load` 和 `document ready` 的区别
 - 20. `==` 和 `===` 的不同
 - 21. JavaScript 的同源策略
 - 22. 编写一个数组去重的方法
 - 23. `String` 对象的方法不包括哪一个
 - 24. 关于 `setTimeout("check", 10)` 中说法正确的是
 - 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 元素在浏览器中被视为一个盒子,包含以下部分:
- 内容区(Content):实际内容显示区域。
 - 内边距(Padding):内容周围的空白区域,透明。
 - 边框(Border):包围内边距和内容的边框。
 - 外边距(Margin):盒子外部的空白区域,透明。
 
+---------------------------+
|         Margin            |
|  +---------------------+  |
|  |      Border         |  |
|  |  +---------------+  |  |
|  |  |   Padding     |  |  |
|  |  | +-----------+ |  |  |
|  |  | |  Content  | |  |  |
|  |  | +-----------+ |  |  |
|  |  |               |  |  |
|  |  +---------------+  |  |
|  |                     |  |
|  +---------------------+  |
|                           |
+---------------------------+
 
5. CSS 引入的方式有哪些? link 和 @import 的区别是?
 
CSS 引入方式:
-  
内联样式(Inline Styles):
- 直接在 HTML 元素的 
style属性中定义样式。 - 示例:
<div style="color: red;">文本</div> 
 - 直接在 HTML 元素的 
 -  
内嵌样式(Internal Styles):
- 在 HTML 文档的 
<head>部分使用<style>标签定义样式。 - 示例:
<head> <style> .text { color: red; } </style> </head> 
 - 在 HTML 文档的 
 -  
外链样式(External Styles):
- 使用 
<link>标签在 HTML 文档中引入外部 CSS 文件。 - 示例:
<head> <link rel="stylesheet" href="styles.css"> </head> 
 - 使用 
 -  
@import 引入:
- 在 CSS 文件中使用 
@import语句引入其他 CSS 文件。 - 示例:
@import url("styles.css"); 
 - 在 CSS 文件中使用 
 
link 和 @import 的区别:
| 特性 | <link> 标签 | @import 语句 | 
|---|---|---|
| 加载方式 | 同时加载,减少延迟 | 顺序加载,可能增加延迟 | 
| 兼容性 | 所有浏览器均支持 | CSS2.1 以下浏览器不支持 | 
| 动态修改 | 支持使用 JavaScript 动态改变样式 | 不支持使用 JavaScript 动态改变样式 | 
| 优先级 | 较高 | 较低 | 
| 性能 | 更优,减少 HTTP 请求时间 | 较差,可能阻塞后续样式的加载 | 
总结:
- 外链样式 (
<link>):推荐使用,因为它性能更好,兼容性更强,且支持动态修改。 - @import:适用于需要在 CSS 文件中组织和引入样式,但可能会影响性能,尽量减少使用。
 
6. CSS 选择符有哪些? 哪些属性可以继承? 优先级算法如何计算? 内联和 !important 哪个优先级高?
 
CSS 选择符(Selectors):
-  
标签选择器(Type Selector):
- 例如:
div、p、h1 
 - 例如:
 -  
类选择器(Class Selector):
- 例如:
.container、.active 
 - 例如:
 -  
ID 选择器(ID Selector):
- 例如:
#header、#footer 
 - 例如:
 -  
后代选择器(Descendant Selector):
- 例如:
div p、ul li 
 - 例如:
 -  
群组选择器(Group Selector):
- 例如:
h1, h2, h3、.btn, .link 
 - 例如:
 -  
伪类选择器(Pseudo-class Selector):
- 例如:
:hover、:active、:nth-child(2) 
 - 例如:
 -  
属性选择器(Attribute Selector):
- 例如:
input[type="text"]、a[href^="https"] 
 - 例如:
 
可继承的属性(Inherited Properties):
- 字体相关:
font-family、font-size、font-weight、color、line-height - 文本相关:
text-align、text-indent、text-transform - 其他:
visibility、cursor 
不可继承的属性:
- 布局相关:
margin、padding、border、width、height、display、position 
优先级算法(Specificity)计算:
优先级由四个部分组成,按照从高到低依次为:
- 内联样式(Inline styles):最高优先级。
 - ID 选择器(ID selectors)
 - 类、属性、伪类选择器(Classes, attributes, pseudo-classes)
 - 标签、伪元素选择器(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. 前端页面有哪三层构成,分别是什么? 作用是什么?
前端页面的三层构成:
-  
结构层(Structure Layer):
- 技术:HTML、XHTML
 - 作用:定义网页的基本结构和内容,如标题、段落、列表等。
 
 -  
表现层(Presentation Layer):
- 技术:CSS
 - 作用:控制网页的视觉表现,如布局、颜色、字体、边距等。
 
 -  
行为层(Behavior Layer):
- 技术:JavaScript
 - 作用:实现网页的动态交互和行为,如按钮点击、表单验证、动画效果等。
 
 
总结:
- 结构层:负责内容的组织和呈现。
 - 表现层:负责内容的视觉样式和布局。
 - 行为层:负责内容的交互和动态行为。
 
8. CSS 的基本语句构成是?
CSS 基本语句构成:
选择器 {
  属性1: 值1;
  属性2: 值2;
  /* 更多属性 */
}
 
示例:
.container {
  width: 100%;
  padding: 20px;
  background-color: #f0f0f0;
}
 
9. 你做的页面在哪些浏览器测试过? 这些浏览器的内核分别是什么? 经常遇到的浏览器的兼容性有哪些? 怎么会出现? 解决方法是什么?
测试过的浏览器及其内核:
- IE(Trident 内核)
 - 火狐(Firefox)(Gecko 内核)
 - 谷歌(Chrome)(Blink 内核,基于 WebKit)
 - Opera(Presto 内核,最新版本基于 Blink)
 - Safari(WebKit 内核)
 - Maxthon(Trident/WebKit 双内核)
 
常见的浏览器兼容性问题及解决方法:
-  
默认字体大小差异:
- 问题:不同浏览器的默认字体大小不同,导致字体显示不一致。
 - 解决方法:在 CSS 中统一设置字体大小,例如 
body { font-size: 14px; }。 
 -  
嵌套
<a>标签:- 问题:某些浏览器不允许 
<a>标签嵌套<a>标签,会导致结构错误。 - 解决方法:避免在 
<a>标签内嵌套其他<a>标签,使用其他元素包裹。 
 - 问题:某些浏览器不允许 
 -  
链接内容样式差异:
- 问题:不同浏览器对 
<a>标签内部内容的样式处理不同。 - 解决方法:在 CSS 中明确设置 
<a>标签的display属性,例如display: block;,并统一样式。 
 - 问题:不同浏览器对 
 -  
列表样式和内边距:
- 问题:不同浏览器对 
<ul>、ol>和<dl>等列表标签的默认样式和内边距处理不同。 - 解决方法:在 CSS 中重置列表样式和内边距,例如:
ul, ol, dl { margin: 0; padding: 0; list-style: none; } 
 - 问题:不同浏览器对 
 -  
Wrapper
<div>高度问题:- 问题:外部包裹的 
<div>高度在不同浏览器中表现不一致。 - 解决方法:设置 
overflow: hidden;使高度自适应,避免固定高度。 
 - 问题:外部包裹的 
 -  
手形光标兼容性:
- 问题:不同浏览器对 
cursor: hand;和cursor: pointer;的支持不同。 - 解决方法:统一使用 
cursor: pointer;,兼容性更好。 
 - 问题:不同浏览器对 
 -  
居中问题:
- 问题:不同浏览器对居中方式的支持不同,特别是浮动元素的居中。
 - 解决方法: 
    
- 对父元素使用 
text-align: center;,对子元素使用margin: 0 auto;。 - 使用 Flexbox 布局实现居中。
 
 - 对父元素使用 
 
 -  
浮动引起的双倍边距:
- 问题:在 IE 中,浮动元素可能会导致双倍边距。
 - 解决方法:设置 
display: inline;使浮动忽略元素间的空隙,或使用其他清除浮动的方法。 
 -  
居中浮动元素:
- 问题:浮动元素无法通过常规方式居中。
 - 解决方法:使用 
margin: 0 auto;配合display: block;,或使用 Flexbox 实现居中。 
 
10. 写出几种 IE6 BUG 的解决方法
-  
双边距 BUG(Double Margin Float Bug):
- 问题:在 IE6 中,浮动元素的左右外边距会被倍增。
 - 解决方法:设置 
display: inline;,使 IE6 忽略外边距的倍增。.float-element { float: left; margin-left: 10px; display: inline; } 
 -  
3 像素问题:
- 问题:IE6 中,浮动元素的高度可能出现 3 像素的误差。
 - 解决方法:调整 
line-height或使用zoom: 1;触发 hasLayout。.float-element { float: left; line-height: 1px; zoom: 1; } 
 -  
超链接
hover点击后失效:- 问题:在 IE6 中,超链接在 
:hover状态下点击后失效。 - 解决方法:确保 CSS 中的链接伪类顺序为 
:link、:visited、:hover、:active。a:link { /* 样式 */ } a:visited { /* 样式 */ } a:hover { /* 样式 */ } a:active { /* 样式 */ } 
 - 问题:在 IE6 中,超链接在 
 -  
IE
z-index问题:- 问题:在 IE6 中,子元素的 
z-index无法超越父元素。 - 解决方法:给父元素添加 
position: relative;。.parent { position: relative; z-index: 1; } .child { position: absolute; z-index: 2; } 
 - 问题:在 IE6 中,子元素的 
 -  
PNG 透明问题:
- 问题:IE6 不支持 PNG 图片的透明背景。
 - 解决方法:使用 JavaScript 或滤镜(filter)修复透明效果。
.png-fix { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='image.png', sizingMethod='scale'); } 
 -  
min-height最小高度问题:- 问题:IE6 不支持 
min-height属性。 - 解决方法:使用 
height代替,并触发 hasLayout。.container { height: 300px; /* 代替 min-height */ zoom: 1; /* 触发 hasLayout */ } 
 - 问题:IE6 不支持 
 -  
select元素遮盖问题:- 问题:在 IE6 中,
select元素会遮盖浮动元素。 - 解决方法:使用 iframe 嵌套层级,或者使用其他替代方案。
<!-- 使用 iframe 作为遮罩层 --> <iframe src="about:blank" style="position:absolute; top:0; left:0; width:100%; height:100%;"></iframe> 
 - 问题:在 IE6 中,
 -  
无法定义 1px 宽度的容器:
- 问题:IE6 默认行高导致无法准确设置 1px 宽度。
 - 解决方法:使用 
overflow: hidden;、zoom: 1;或调整line-height。.one-pixel { width: 1px; overflow: hidden; zoom: 1; line-height: 1px; } 
 
11. 标签上 title 与 alt 属性的区别是什么?
 
-  
alt属性:- 用途:为图片提供替代文本,当图片无法显示时显示该文字。
 - 示例:
<img src="image.jpg" alt="描述性文本"> 
 -  
title属性:- 用途:为元素提供额外的信息,通常在鼠标悬停时显示为工具提示。
 - 示例:
<a href="#" title="更多信息">链接</a> 
 
总结:
alt用于替代内容,增强可访问性。title用于提供额外信息,提升用户体验。
12. 描述 CSS Reset 的作用和用途
CSS Reset 的作用是重置不同浏览器的默认样式,使各浏览器在渲染网页时有一致的基础,从而减少跨浏览器的兼容性问题。
用途:
- 统一样式:消除不同浏览器默认的内边距、外边距、字体等差异。
 - 简化样式管理:提供一个统一的起点,便于后续的样式设计和开发。
 - 提升可维护性:减少因浏览器差异导致的样式调整和修复工作。
 
常见的 CSS Reset 工具:
- Eric Meyer’s Reset CSS
 - Normalize.css
 
示例:
/* 简单的 CSS Reset */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
 
13. 解释 CSS Sprites,如何使用
CSS Sprites 是一种将多个小图标或图片合并为一张大图的技术,通过 CSS 的 background-image 和 background-position 属性来显示不同部分的图片。
优点:
- 减少 HTTP 请求:合并图片减少页面加载时的 HTTP 请求数量,提升加载速度。
 - 提高性能:减少服务器资源的消耗,提升用户体验。
 
使用方法:
-  
创建 Sprites 图:
- 将多个小图标拼接成一张大图,记录每个小图标在大图中的位置(坐标)。
 
 -  
CSS 设置:
- 使用 
background-image指定大图。 - 使用 
background-position设置显示大图的特定部分。 - 设置元素的宽度和高度为小图标的尺寸。
 
 - 使用 
 
示例:
.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;
}
 
<span class="icon icon-home"></span>
<span class="icon icon-search"></span>
<span class="icon icon-settings"></span>
 
14. 浏览器标准模式和怪异模式之间的区别是什么?
浏览器标准模式(Standards Mode) 和 怪异模式(Quirks Mode) 是浏览器解析和渲染网页时的两种模式,主要区别体现在以下方面:
-  
盒模型:
- 标准模式:采用标准的盒模型,元素的宽高只包含内容区,不包括内边距和边框。
 - 怪异模式:采用 IE6 盒模型,元素的宽高包括内容、内边距和边框。
 
 -  
渲染行为:
- 标准模式:严格遵循 W3C 标准,提供一致和可预测的渲染结果。
 - 怪异模式:兼容旧版浏览器的渲染方式,可能导致不一致和不可预测的布局问题。
 
 -  
触发方式:
- 标准模式:通过正确的 Doctype 声明,如 
<!DOCTYPE html>。 - 怪异模式:缺少 Doctype 或使用不正确的 Doctype 声明。
 
 - 标准模式:通过正确的 Doctype 声明,如 
 
检测渲染模式:
if (document.compatMode === "CSS1Compat") {
  console.log("标准模式");
} else {
  console.log("怪异模式");
}
 
意义:
- 一致性:标准模式提供更一致的跨浏览器表现,便于开发和维护。
 - 兼容性:怪异模式用于兼容旧版浏览器的网页,确保旧网站正常显示。
 
15. 你如何对网站的文件和资源进行优化?
文件和资源优化方法:
-  
文件合并:
- 将多个 CSS 或 JavaScript 文件合并为一个文件,减少 HTTP 请求次数。
 
 -  
文件最小化/压缩:
- 使用工具(如 UglifyJS、CSSNano)压缩 JavaScript 和 CSS 文件,减少文件大小。
 
 -  
使用 CDN 托管:
- 将静态资源(如图片、库文件)托管在 CDN 上,提升加载速度和分发效率。
 
 -  
缓存的使用:
- 利用浏览器缓存,通过设置合适的 HTTP 缓存头(如 
Cache-Control、Expires)提高资源加载效率。 
 - 利用浏览器缓存,通过设置合适的 HTTP 缓存头(如 
 -  
图片优化:
- 压缩图片文件,选择合适的格式(如 JPEG、PNG、WebP),使用 CSS Sprites 减少图片请求。
 
 -  
延迟加载(Lazy Loading):
- 对不在视口内的资源进行延迟加载,提升页面初始加载速度。
 
 -  
代码分割(Code Splitting):
- 将代码拆分成按需加载的模块,减少初始加载的 JavaScript 量。
 
 -  
使用 GZIP 压缩:
- 启用 GZIP 压缩,减少传输数据量,提升加载速度。
 
 
总结:
通过以上优化方法,可以显著提升网站的加载速度、响应效率和用户体验。
16. 什么是语义化的 HTML?
语义化 HTML 指的是使用具有明确意义的 HTML 标签来描述内容,使代码更具可读性和可维护性,同时提升搜索引擎优化(SEO)效果和可访问性。
优势:
- 提高可读性:开发者和其他人更容易理解代码结构和内容。
 - 增强 SEO:搜索引擎更容易抓取和理解网页内容,提高网站排名。
 - 改善可访问性:辅助技术(如屏幕阅读器)更好地理解和呈现内容,提升无障碍体验。
 
示例:
- 使用 
<header>、<nav>、<main>、<footer>来定义页面的不同部分。 - 使用 
<article>、<section>、<aside>来组织内容。 - 使用 
<figure>、<figcaption>来描述图像和其说明。 
<article>
  <header>
    <h1>文章标题</h1>
    <p>作者信息</p>
  </header>
  <section>
    <h2>章节标题</h2>
    <p>内容...</p>
  </section>
  <footer>
    <p>版权信息</p>
  </footer>
</article>
 
17. 清除浮动的几种方式,各自的优缺点
1. 使用空标签清除浮动(Clearfix Hack)
<div class="container">
  <div class="float-element">浮动元素</div>
  <div class="float-element">浮动元素</div>
  <div class="clearfix"></div>
</div>
 
.clearfix {
  clear: both;
}
 
优点:
- 简单直接,易于理解和实现。
 
缺点:
- 增加了无意义的 HTML 标签,影响语义化。
 
2. 使用 overflow: auto 或 overflow: hidden
.container {
  overflow: hidden;
}
 
优点:
- 不需要额外的 HTML 元素,保持结构简洁。
 - 触发块级格式化上下文,自动清除浮动。
 
缺点:
- 可能会截断溢出的内容,不适用于需要显示溢出部分的场景。
 
3. 使用 ::after 伪元素
.container::after {
  content: "";
  display: table;
  clear: both;
}
 
<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 引入)
示例:
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):
-  
parseInt- 将字符串转换为整数。
 - 示例:
parseInt("123"); // 123 
 -  
parseFloat- 将字符串转换为浮点数。
 - 示例:
parseFloat("123.45"); // 123.45 
 -  
Number- 将值转换为数字类型。
 - 示例:
Number("123"); // 123 
 
隐式类型转换(Implicit Type Conversion):
-  
使用
==进行比较- 自动转换不同类型的值后进行比较。
 - 示例:
5 == "5"; // true 
 -  
使用算术运算符
- 在运算过程中自动转换类型。
 - 示例:
"5" * "2"; // 10 
 
3. split() 和 join() 的区别
 
-  
split()方法- 用途:将字符串按指定分隔符拆分为数组。
 - 示例:
const str = "apple,banana,cherry"; const arr = str.split(","); // ["apple", "banana", "cherry"] 
 -  
join()方法- 用途:将数组元素按指定分隔符连接为字符串。
 - 示例:
const arr = ["apple", "banana", "cherry"]; const str = arr.join(","); // "apple,banana,cherry" 
 
总结:
split():字符串 → 数组join():数组 → 字符串
4. 数组方法 pop()、push()、unshift()、shift()
 
-  
push()- 用途:在数组末尾添加一个或多个元素。
 - 示例:
const arr = [1, 2, 3]; arr.push(4); // [1, 2, 3, 4] 
 -  
pop()- 用途:移除数组末尾的元素并返回该元素。
 - 示例:
const arr = [1, 2, 3, 4]; const last = arr.pop(); // last = 4, arr = [1, 2, 3] 
 -  
unshift()- 用途:在数组开头添加一个或多个元素。
 - 示例:
const arr = [2, 3]; arr.unshift(1); // [1, 2, 3] 
 -  
shift()- 用途:移除数组开头的元素并返回该元素。
 - 示例:
const arr = [1, 2, 3]; const first = arr.shift(); // first = 1, arr = [2, 3] 
 
5. 事件绑定和普通事件有什么区别
事件绑定(Event Binding):
- 定义:通过 JavaScript 动态地将事件处理函数绑定到元素上。
 - 方法: 
  
- 使用 
addEventListener(现代浏览器)element.addEventListener('click', function() { // 处理代码 }); - 使用 
attachEvent(IE8 及以下)element.attachEvent('onclick', function() { // 处理代码 }); 
 - 使用 
 
普通事件(Inline Event Handlers):
- 定义:在 HTML 标签中直接使用事件属性绑定事件处理函数。
 - 示例:
<button onclick="handleClick()">点击我</button> 
区别:
-  
可维护性:
- 事件绑定:代码与 HTML 分离,易于维护和管理。
 - 普通事件:代码混杂在 HTML 中,难以维护。
 
 -  
多重绑定:
- 事件绑定:允许为同一事件绑定多个处理函数。
 - 普通事件:只能绑定一个处理函数,后绑定的会覆盖前面的。
 
 -  
兼容性:
- 事件绑定:现代方法 
addEventListener在所有现代浏览器中支持,attachEvent支持 IE8 及以下。 - 普通事件:所有浏览器都支持,但功能有限。
 
 - 事件绑定:现代方法 
 
总结:
- 推荐使用事件绑定方法(如 
addEventListener),以提高代码的可维护性和灵活性。 
6. IE 和 DOM 事件流的区别
IE 事件模型(IE Event Model):
- 事件处理方式:基于 
attachEvent和detachEvent方法。 - 事件对象:通过全局变量 
window.event获取。 - 事件冒泡:事件总是从目标元素向上冒泡。
 - 取消默认行为:使用 
return false;或设置event.cancelBubble = true;。 
DOM 事件模型(W3C DOM Event Model):
- 事件处理方式:基于 
addEventListener和removeEventListener方法。 - 事件对象:作为事件处理函数的参数传递。
 - 事件流:包括捕获阶段、目标阶段和冒泡阶段。
 - 取消默认行为:使用 
event.preventDefault();和event.stopPropagation();。 
主要区别:
-  
事件绑定方法:
- IE:
attachEvent/detachEvent - DOM:
addEventListener/removeEventListener 
 - IE:
 -  
事件对象获取:
- IE:通过 
window.event - DOM:通过事件处理函数的参数
 
 - IE:通过 
 -  
事件流控制:
- IE:仅支持冒泡
 - DOM:支持捕获和冒泡
 
 -  
取消冒泡和默认行为的方法:
- IE:
event.cancelBubble = true;和return false; - DOM:
event.stopPropagation();和event.preventDefault(); 
 - IE:
 
总结:
- 现代浏览器支持 W3C DOM 事件模型,建议使用 
addEventListener等标准方法进行事件处理。 - 对于需要兼容 IE8 及以下版本的项目,需结合 
attachEvent方法进行兼容处理。 
7. IE 和标准下有哪些兼容性的写法
常见的 IE 和标准兼容写法:
-  
获取事件对象
function handleEvent(event) { var e = event || window.event; // 兼容 IE // 处理事件 } -  
获取元素的宽度
var width = document.documentElement.clientWidth || document.body.clientWidth; // 兼容 IE -  
获取事件目标元素
var target = event.srcElement || event.target; // 兼容 IE -  
阻止事件冒泡
if (event.stopPropagation) { event.stopPropagation(); // 标准 } else { event.cancelBubble = true; // IE } -  
阻止默认行为
if (event.preventDefault) { event.preventDefault(); // 标准 } else { event.returnValue = false; // IE } -  
添加事件处理函数
if (element.addEventListener) { element.addEventListener('click', handler, false); // 标准 } else if (element.attachEvent) { element.attachEvent('onclick', handler); // IE } -  
移除事件处理函数
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. call 和 apply 的区别
 
call 和 apply 方法用于改变函数的上下文(this)并调用函数。
-  
call方法- 语法:
function.call(thisArg, arg1, arg2, ...) - 用法:传递参数列表。
 - 示例:
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]) - 用法:传递参数数组。
 - 示例:
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 数据的方法:
-  
使用
JSON.parse()- 用途:将 JSON 字符串转换为 JavaScript 对象。
 - 示例:
const jsonString = '{"name": "Alice", "age": 25}'; const obj = JSON.parse(jsonString); console.log(obj.name); // "Alice" 
 -  
使用
eval()- 用途:将字符串当作 JavaScript 代码执行。
 - 注意:存在安全风险,容易受到 XSS 攻击,不推荐使用。
 - 示例:
const jsonString = '{"name": "Bob", "age": 30}'; const obj = eval('(' + jsonString + ')'); console.log(obj.name); // "Bob" 
 
推荐方法:
- 使用 
JSON.parse(),因为它安全、标准且高效。 - 避免使用 
eval(),因其潜在的安全风险和性能问题。 
11. B 继承 A 的方法
实现继承的方法有多种,以下为常见的两种:
- 原型链继承
 
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"
 
- 寄生组合继承
 
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. 写一个获取非行间样式的函数
获取元素非行内样式的函数示例:
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) 来处理子元素的事件。 
优点:
- 减少事件处理器:避免为每个子元素绑定事件处理器,节省内存和提高性能。
 - 动态元素支持:自动支持动态添加的子元素,无需重新绑定事件。
 
示例:
<ul id="parentList">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>
 
document.getElementById('parentList').addEventListener('click', function(event) {
  const target = event.target;
  if (target && target.nodeName === 'LI') {
    alert('Clicked on ' + target.textContent);
  }
});
 
总结:
- 事件委托 通过绑定单一的事件处理器到父元素,管理所有子元素的事件,提升代码效率和可维护性。
 
14. 闭包是什么,有什么特性,对页面有什么影响
闭包(Closure) 是指在函数内部创建的函数,可以访问其外部函数的作用域,即使外部函数已经执行完毕。
特性:
- 访问外部函数的变量:闭包可以访问并操作外部函数的变量和参数。
 - 保持变量状态:即使外部函数执行完毕,闭包仍然保持对变量的引用。
 - 私有变量:通过闭包,可以创建私有变量和方法,增强封装性。
 
影响:
- 数据隐私:通过闭包可以保护变量不被外部直接访问和修改。
 - 内存管理:过多的闭包可能导致内存泄漏,因为它们保持对外部变量的引用。
 - 功能扩展:闭包在模块化开发、函数式编程等方面具有重要应用。
 
示例:
function outerFunction() {
  var count = 0;
  function innerFunction() {
    count++;
    console.log(count);
  }
  return innerFunction;
}
const counter = outerFunction();
counter(); // 输出: 1
counter(); // 输出: 2
 
总结:
- 闭包 是理解 JavaScript 作用域和函数特性的关键,合理使用闭包可以提升代码的灵活性和封装性,但需注意内存管理。
 
15. 如何阻止事件冒泡和默认事件
阻止事件冒泡(Event Bubbling):
-  
标准方法:
event.stopPropagation(); -  
IE 兼容方法:
event.cancelBubble = true; 
阻止默认事件(Prevent Default Behavior):
-  
标准方法:
event.preventDefault(); -  
IE 兼容方法:
event.returnValue = false; 
示例:
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 操作方法:
-  
创建新节点
-  
createDocumentFragment():创建一个空的文档片段,用于批量添加节点。const fragment = document.createDocumentFragment(); -  
createElement():创建一个新的元素节点。const newDiv = document.createElement('div'); -  
createTextNode():创建一个新的文本节点。const text = document.createTextNode('Hello World'); 
 -  
 -  
添加、删除、替换、插入
-  
appendChild():在父节点末尾添加一个子节点。parent.appendChild(child); -  
removeChild():从父节点中移除一个子节点。parent.removeChild(child); -  
replaceChild():用一个新节点替换父节点中的一个子节点。parent.replaceChild(newChild, oldChild); -  
insertBefore():在指定子节点之前插入一个新节点。parent.insertBefore(newChild, referenceChild); 
 -  
 -  
查找节点
-  
getElementsByTagName():通过标签名称查找元素。const divs = document.getElementsByTagName('div'); -  
getElementsByName():通过元素的name属性查找元素。const inputs = document.getElementsByName('username'); -  
getElementById():通过元素的id查找元素。const header = document.getElementById('header'); 
 -  
 
总结:
- 使用 DOM 方法进行节点操作可以动态改变网页内容和结构,提升用户体验和交互性。
 
17. 解释 JSONP 的原理,以及为什么不是真正的 AJAX
JSONP(JSON with Padding) 是一种跨域请求数据的技术,通过动态创建 <script> 标签并使用回调函数来实现数据的跨域获取。
原理:
-  
创建
<script>标签:在页面中动态添加一个<script>标签,设置其src属性指向跨域的数据源,并包含回调函数名称。const script = document.createElement('script'); script.src = 'https://api.example.com/data?callback=handleData'; document.body.appendChild(script); -  
服务器返回 JSONP 格式的数据:服务器响应时,将数据包裹在回调函数中。
handleData({"name": "Alice", "age": 25}); -  
回调函数执行:页面中的回调函数接收数据并处理。
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 对象分类:
-  
本地对象(Native Objects):
- 定义:JavaScript 语言本身提供的对象,可以通过 
new关键字实例化。 - 示例: 
    
- 构造函数:
Array、Object、Function、Date、RegExp - 实例:
const arr = new Array(); const obj = new Object(); const func = new Function(); const date = new Date(); const regex = new RegExp('pattern'); 
 - 构造函数:
 
 - 定义:JavaScript 语言本身提供的对象,可以通过 
 -  
内置对象(Built-in Objects):
- 定义:JavaScript 环境预定义的对象,不能通过 
new关键字实例化。 - 示例: 
    
- 全局对象:
Math、JSON、Promise - 对象实例:
const pi = Math.PI; const json = JSON.stringify({ name: 'Alice' }); const promise = new Promise((resolve, reject) => {}); 
 - 全局对象:
 
 - 定义:JavaScript 环境预定义的对象,不能通过 
 -  
宿主对象(Host Objects):
- 定义:由宿主环境(如浏览器、Node.js)提供的对象,用于与环境交互。
 - 示例: 
    
- 浏览器宿主对象:
window、document、navigator、location - Node.js 宿主对象:
process、Buffer、fs 
 - 浏览器宿主对象:
 
 
总结:
- 本地对象:JavaScript 内置的可实例化对象。
 - 内置对象:JavaScript 环境提供的预定义对象,无法实例化。
 - 宿主对象:宿主环境提供的对象,用于与环境交互。
 
19. document load 和 document ready 的区别
 
document.onload 和 document.ready 的区别:
-  
document.onload(window.onload):- 触发时机:在整个页面(包括所有依赖资源如图片、样式表、脚本等)加载完成后触发。
 - 使用方法:
window.onload = function() { // 页面完全加载后执行 }; 
 -  
document.ready(jQuery 的$(document).ready()):- 触发时机:在 DOM 树构建完成后触发,不等待图片、样式表等资源加载。
 - 使用方法:
$(document).ready(function() { // DOM 树构建完成后执行 }); - 原生实现:
document.addEventListener('DOMContentLoaded', function() { // DOM 树构建完成后执行 }); 
 
区别与意义:
-  
执行时机:
window.onload适用于需要确保所有资源加载完成后执行的操作。document.ready适用于需要在 DOM 准备好后立即执行的操作,如绑定事件、操作 DOM 元素。
 -  
性能与用户体验:
document.ready提升页面响应速度,用户可以更早地与页面交互。window.onload可能会延迟执行,影响用户体验。
 
总结:
document.ready:适用于大多数 DOM 操作,提升页面交互性。window.onload:适用于需要所有资源加载完成后执行的任务。
20. == 和 === 的不同
 
==(双等号)与 ===(三等号)的区别:
-  
==(相等运算符):- 特性:进行类型转换后再比较,可能导致不同类型的值相等。
 - 示例:
5 == '5'; // true null == undefined; // true 0 == false; // true 
 -  
===(严格相等运算符):- 特性:不进行类型转换,只有在类型和值都相等时返回 
true。 - 示例:
5 === '5'; // false null === undefined; // false 0 === false; // false 
 - 特性:不进行类型转换,只有在类型和值都相等时返回 
 
优先级:
===的优先级高于==。===优先级高于!important。
总结:
- 使用 
===:推荐使用严格相等运算符,避免类型转换带来的潜在问题,提升代码可靠性。 - 使用 
==:仅在确实需要类型转换时使用,需谨慎处理。 
21. JavaScript 的同源策略
同源策略(Same-Origin Policy) 是浏览器的安全机制,限制从一个源加载的文档或脚本如何与来自不同源的资源进行交互。
定义:
- 同源:协议(如 
http、https)、主机(如www.example.com)、端口(如:80、:443)都相同。 - 不同源:只要协议、主机或端口有一个不同,即为不同源。
 
作用:
- 防止恶意脚本在未经授权的情况下访问或篡改其他网站的敏感数据。
 - 限制跨域的 AJAX 请求,确保数据的安全性和隐私。
 
示例:
-  
同源:
http://www.example.com/page1.htmlhttp://www.example.com/page2.html
 -  
不同源:
http://www.example.com与https://www.example.comhttp://www.example.com与http://api.example.comhttp://www.example.com与http://www.example.com:8080
 
绕过同源策略的方法:
- CORS(跨域资源共享):通过服务器设置响应头 
Access-Control-Allow-Origin允许跨域请求。 - JSONP:利用 
<script>标签的跨域能力,传递回调函数处理数据。 - 代理服务器:通过同源的服务器代理跨域请求。
 
总结:
- 同源策略是浏览器安全的重要组成部分,理解其机制有助于开发安全和高效的前端应用。
 
22. 编写一个数组去重的方法
示例:使用对象存储法
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中出现时,才添加到结果数组中。 
其他方法:
-  
使用
Set(ES6)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] -  
使用
filter和indexOffunction 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
解释:
length是String对象的属性,不是方法。- 其他选项都是 
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 版本中,关键字的定义可能有所变化。
前端工程师面试心得
基本知识
作为一名前端工程师,以下知识点是必须掌握的:
-  
DOM 结构:
- 理解节点之间的关系:父子关系、兄弟关系等。
 - 如何在节点之间任意移动:使用 DOM 方法如 
appendChild、insertBefore等。 
 -  
DOM 操作:
- 添加、移除、移动、复制、创建和查找节点。
 - 常用方法:
createElement、createTextNode、appendChild、removeChild、replaceChild、insertBefore、getElementById、getElementsByTagName、getElementsByName。 
 -  
事件:
- 如何使用事件:绑定事件处理函数、事件对象的使用。
 - IE 和 DOM 事件模型的主要差别:事件绑定方法、事件对象获取方式、事件流控制方法等。
 
 -  
XMLHttpRequest:
- 定义:用于在后台与服务器交换数据。
 - 完整的 GET 请求流程:创建 
XMLHttpRequest对象、配置请求、发送请求、处理响应、检测错误。 
 -  
严格模式与混杂模式:
- 触发方式:通过正确或错误的 Doctype 声明。
 - 区别:盒模型、渲染行为等。
 
 -  
盒模型:
- 外边距(Margin)、内边距(Padding)、边框(Border) 的关系。
 - IE8 以下的浏览器盒模型差异:内容宽高是否包含内边距和边框。
 
 -  
块级元素与行内元素:
- CSS 控制:
display属性的使用,如block、inline、inline-block。 - 合理使用:根据内容语义和布局需求选择合适的元素类型。
 
 - CSS 控制:
 -  
浮动元素:
- 使用方法:
float属性的应用。 - 问题:浮动导致父容器高度塌陷、元素重叠等。
 - 解决方法:清除浮动、使用 Flexbox 等现代布局方法。
 
 - 使用方法:
 -  
HTML 与 XHTML:
- 区别:严格的语法规则、标签闭合、标签小写等。
 - 选择建议:推荐使用 HTML5,因其更灵活且广泛支持。
 
 -  
JSON:
- 定义:轻量级的数据交换格式。
 - 作用:在客户端和服务器之间传递数据。
 - 用途:配置文件、API 数据响应等。
 - 设计结构:键值对形式,支持嵌套和数组。
 
 
少量提问
面试时,应尽量减少提问数量,但每个问题深入考察多个知识点。
示例问题:
- 问题:现在有一个正显示着 Yahoo! 股票价格的页面。页面上有一个按钮,你可以单击它来刷新价格,但不会重新加载页面。请你描述一下实现这个功能的过程,假设服务器会负责准备好正确的股票价格数据。
 
考察知识点:
- DOM 结构:如何获取和操作 DOM 元素。
 - 事件处理:绑定按钮点击事件。
 - XMLHttpRequest:发送 AJAX 请求获取数据。
 - JSON:处理服务器返回的数据格式。
 - 动态更新:将新数据更新到页面中。
 
深入提问:
- 替代方法:如果不使用 AJAX,你还能如何实现数据刷新?
 - 安全问题:如何确保数据传输的安全性?
 - 性能优化:如何优化数据请求和页面更新的性能?
 
解决问题
关键能力:找出问题的多种解决方案,理解底层机制。
重要性:
- 应对复杂问题:如 IE6 的兼容性问题,能灵活应对不同浏览器的差异。
 - 创新思维:能够在既有方法受限时,创造新的解决方案。
 - 技术掌握:深入理解浏览器技术,能高效解决实际开发中的问题。
 
示例:
- 问题:IE6 中浮动元素的双倍边距问题。
 - 解决方案 1:设置 
display: inline;使 IE6 忽略外边距的倍增。 - 解决方案 2:使用 CSS hack,针对 IE6 单独设置样式。
 - 解决方案 3:改变布局方式,避免使用浮动。
 
有激情
前端工程师需要对所做的工作充满热情,持续学习和自我提升。
识别方法:
- 询问兴趣领域:如 “目前你对什么 Web 技术最感兴趣?”
 - 了解学习习惯:是否主动学习新技术、关注前沿趋势。
 - 探讨项目经验:是否在项目中展示出对技术的深入理解和应用。
 
重要性:
- 技术更新迅速:持续学习才能跟上技术发展。
 - 解决问题的动力:热情驱动工程师积极解决复杂问题,提升项目质量。
 
最后一点
基础知识的重要性:
- 掌握基本知识:如 DOM 操作、事件处理、AJAX 等,确保能够胜任工作。
 - 深入理解:不仅仅是记忆方法,更要理解其原理和应用场景。
 - 扩展知识面:结合项目需求,学习相关技术和工具,提升综合能力。
 
建议:
- 系统学习:通过系统的学习和实践,形成自己的知识体系。
 - 实战经验:通过项目经验,深化对知识点的理解和应用。
 - 持续改进:在工作中不断反思和优化,提高技术水平和工作效率。
 
其他面试题
百度
-  
JavaScript 有哪几种数据类型
- 答案:
Object、Number、Function、Boolean、undefined 
 - 答案:
 -  
alt和title的区别- 答案:
alt用于图片无法显示时提供替代文本,title用于提供元素的额外信息,通常在鼠标悬停时显示。 
 - 答案:
 -  
下面 CSS 标签在 JavaScript 中调用应如何拼写,
border-left-color,-moz-- 答案:在 JavaScript 中,CSS 属性使用驼峰命名法,例如 
borderLeftColor,MozTransform(带前缀的属性)。 
 - 答案:在 JavaScript 中,CSS 属性使用驼峰命名法,例如 
 -  
动态打印
yyyy-mm-dd hh:mm:ss- 答案:
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); 
 - 答案:
 -  
如何提高网页的运行速度
- 答案: 
    
- 文件合并与压缩
 - 使用 CDN 托管资源
 - 图片优化与使用 CSS Sprites
 - 启用浏览器缓存
 - 延迟加载非关键资源
 
 
 - 答案: 
    
 -  
JavaScript 中如何对一个对象进行深度 clone
- 答案:
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 } } 
 - 答案:
 -  
Flash 中 ActionScript 2.0 和 ActionScript 3.0 面向对象的异同
- 答案: 
    
- ActionScript 2.0: 
      
- 基于原型的面向对象模型。
 - 支持类和继承,但功能较为有限。
 
 - ActionScript 3.0: 
      
- 基于类的面向对象模型,严格的类结构。
 - 支持接口、多继承的部分功能、命名空间等高级特性。
 - 更高的性能和更强的类型检查。
 
 
 - ActionScript 2.0: 
      
 
 - 答案: 
    
 -  
编写一个方法,求一个字符串的字节长度
- 答案:
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 
 - 答案:
 -  
如何控制
alert中的换行- 答案: 
    
- 使用转义字符 
\n实现换行。 - 示例:
alert("这是第一行\n这是第二行"); 
 - 使用转义字符 
 
 - 答案: 
    
 -  
解释
document.getElementById("ElementID").style.fontSize = "1.5em"- 答案: 
    
document.getElementById("ElementID"):获取页面中id为ElementID的元素。.style.fontSize = "1.5em":设置该元素的字体大小为1.5em,即相对于父元素字体大小的 1.5 倍。
 
 - 答案: 
    
 -  
将一个类似图中的效果分离成 CSS 和 HTML
- 答案: 
    
- HTML:
<div class="container"> <div class="box">内容</div> </div> - 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; } 
 - HTML:
 
 - 答案: 
    
 -  
按照格式
xxxx年xx月xx日xx时xx分xx秒动态显示时间,要求不足 10 的补 0- 答案:
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); 
 - 答案:
 -  
编写一个方法,去掉一个数组的重复元素
- 答案:
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] 
 - 答案:
 -  
最近看的一篇 JavaScript 的文章是?
- 答案:可以回答最近阅读的一篇技术博客或文章,并简要描述其内容和收获。
 
 -  
你如何去实现这个 Tabview
- 答案:描述使用 HTML、CSS 和 JavaScript 实现标签页切换的思路,例如通过事件监听切换显示的内容区。
 
 -  
常使用的库有哪些? 常用的前端开发工具? 开发过什么应用或组件?
-  
常用库:
- jQuery
 - React
 - Vue.js
 - Angular
 - Lodash
 
 -  
常用前端开发工具:
- 编辑器:VSCode、Sublime Text、WebStorm
 - 调试工具:Chrome DevTools、Firebug
 - 版本控制:Git、SVN
 - 构建工具:Webpack、Gulp、Grunt
 - 图形工具:Photoshop、Figma、Sketch
 
 -  
开发过的应用或组件:
- 开发过响应式网页、单页应用(SPA)、UI 组件库等。
 
 
 -  
 
腾讯
-  
要动态改变层中内容可以使用的方法有哪些(AB)
-  
选项:
a)innerHTMLb)
innerTextc) 通过设置层的隐藏和显示来实现
d) 通过设置层的样式属性的
display属性 -  
答案:A、B
 
 -  
 -  
当按键盘 A 时,使用
onKeyDown事件打印event.keyCode的结果是(A)-  
选项:
a) 65b) 13
c) 97
d) 37
 -  
答案:A
 
 -  
 -  
在 JavaScript 里,下列选项中不属于数组方法的是(B)
-  
选项:
a)sort()b)
length()c)
concat()d)
reverse() -  
答案:B
 
 -  
 -  
下列哪一个选项可以用来检索被选定的选项的索引号?(B)
-  
选项:
a)disabledb)
selectedIndexc)
optiond)
multiple -  
答案:B
 
 -  
 -  
希望图片具有“提交”按钮同样的功能,该如何编写表单提交?(A)
-  
选项:
a) 在图片的onClick事件中手动提交b) 在图片上添加
onSubmit事件c) 在图片的
onSubmit事件中手动提交d) 在表单中自动提交
 -  
答案:A
 
 -  
 -  
使
div层和文本框处在同一行的代码正确的是(D) -  
下列选项中,描述正确的是(选择两项)(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
 
 -  
 -  
var emp = new Array(3); for(var i in emp)以下答案中能与for循环代码互换的是:(选择一项)(D)- 答案:D
 
 -  
制作级联菜单功能时调用的是下拉列表框的(A)事件。
-  
选项:
a)onChangeb)
onFocusc)
selectedd)
onClick -  
答案:A
 
 -  
 -  
下列声明数组的语句中,错误的选项是(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
 
 -  
 -  
下列属性哪一个能够实现层的隐藏?(C)
-  
选项:
a)display: falseb)
display: hiddenc)
display: noned)
display: " " -  
答案:C
 
 -  
 -  
下列哪一个选项不属于
document对象的方法?(D)-  
选项:
a)focus()b)
getElementById()c)
getElementsByName()d)
bgColor() -  
答案:D
 
 -  
 -  
下列哪项是按下键盘事件(A、B)
-  
选项:
a)onKeyDownb)
onKeyPressc)
keyCoded)
onMouseOver -  
答案:A、B
 
 -  
 -  
JavaScript 进行表单验证的目的是(B)
-  
选项:
a) 把用户的正确信息提交给服务器b) 检查提交的数据必须符合实际
c) 使得页面变得美观、大方
d) 减轻服务器端的压力
 -  
答案:B
 
 -  
 -  
display属性值的常用取值不包括(C)。-  
选项:
a)inlineb)
blockc)
hiddend)
none -  
答案:C
 
 -  
 -  
以下有关
pixelTop属性与top属性的说法正确的是。(D)-  
选项:
a) 都是 Location 对象的属性b) 使用时返回值都是字符串
c) 都是返回以像素为单位的数值
d) 以上都不对
 -  
答案:D
 
 -  
 -  
使用
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
 
 -  
 -  
下面关闭名为
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
 
 -  
 -  
为什么要使用
div + CSS布局- 答案: 
    
- 形式与内容分离:通过 CSS 控制布局和样式,使 HTML 只关注内容。
 - 减少页面代码:通过样式表集中管理样式,减少重复代码。
 - 提高页面加载速度:统一的样式表可以被浏览器缓存,减少资源加载时间。
 - 结构清晰,有利于 SEO:语义化的 HTML 结构有助于搜索引擎优化。
 - 缩短改版时间,布局更方便:通过修改 CSS 即可实现整体布局的调整,简化维护工作。
 - 一次设计,多次使用:统一的 CSS 样式可以被多个页面复用,提升开发效率。
 
 
 - 答案: 
    
 -  
Block 元素的特点是什么? 哪些元素默认为 Block 元素
-  
特点:
- 总是在新行上开始。
 - 宽度默认占满其父容器的整个可用宽度,除非明确设置。
 - 可以设置宽高、内边距、外边距等。
 
 -  
默认的 Block 元素:
<div>、<p>、<h1>-<h6>、<ul>、<ol>、<li>、<form>、<table>、<tr>、<td>
 
 -  
 -  
Inline 元素的特点是什么? 哪些元素属于 Inline 元素?
-  
特点:
- 和其他元素在同一行内显示。
 - 宽度和高度不可设置,只能由内容决定。
 - 不能设置上下边距和内边距的垂直方向。
 
 -  
属于 Inline 元素的有:
<span>、<a>、<img>、<em>、<strong>、<input>、<textarea>、<select>、<label>
 
 -  
 -  
JavaScript 中表达式
parseInt("X8X8") + parseFloat('8')的结果是什么?(C)-  
选项:
a) 8 + 8b) 88
c) 16
d) “8” + ‘8’
 -  
答案:C
 
解释:
parseInt("X8X8"):由于字符串以非数字字符X开头,返回NaN。parseFloat('8'):返回8。NaN + 8:结果为NaN。- 正确答案应为 
NaN,可能题目有误。 
 -  
 -  
String对象的方法不包括哪一个(C)-  
选项:
a)charAt()b)
substring()c)
lengthd)
toUpperCase() -  
答案:C
 
解释:
length是String对象的属性,不是方法。- 其他选项都是 
String对象的方法。 
 -  
 -  
关于
setTimeout("check", 10)中说法正确的是(D)-  
选项:
a) 程序循环执行 10 次b)
check函数每 10 秒执行一次c)
10作为参数传给函数checkd)
check函数每 10 毫秒执行一次 -  
答案:D
 
解释:
setTimeout("check", 10)会在 10 毫秒后执行一次check函数。- 要循环执行需要使用 
setInterval或在回调中再次调用setTimeout。 
 -  
 -  
以下哪个单词不属于 JavaScript 关键字:(C)
-  
选项:
a)withb)
parentc)
classd)
void -  
答案:C
 
解释:
class是 ES6 引入的关键字,用于定义类。parent在 JavaScript 中不是关键字,是一个全局变量属性。
 -  
 
前端开发工程师面试知识点大纲
HTML & CSS
- 对 WEB 标准的理解
 - 浏览器内核差异
 - 兼容性与 hack 技术
 - CSS 基本功:布局、盒子模型、选择器优先级及使用
 - HTML5、CSS3、移动端适应
 
JavaScript
- 数据类型、面向对象、继承、闭包
 - 插件、作用域、跨域
 - 原型链、模块化、自定义事件
 - 内存泄漏、事件机制、异步装载回调
 - 模板引擎、Node.js、JSON、AJAX 等
 
其他
- HTTP、安全、正则、优化、重构
 - 响应式设计、移动端开发、团队协作
 - 可维护性、SEO、用户体验设计(UED)、架构设计、职业生涯规划
 
必须掌握的知识点
- DOM 结构:节点关系与操作。
 - DOM 操作:添加、移除、移动、复制、创建和查找节点。
 - 事件:事件使用及 IE 和 DOM 事件模型差异。
 - XMLHttpRequest:完整的 GET 请求执行及错误检测。
 - 严格模式与混杂模式:触发方式及区别。
 - 盒模型:外边距、内边距和边框的关系,IE8 以下盒模型差异。
 - 块级元素与行内元素:CSS 控制与合理使用。
 - 浮动元素:使用方法、问题与解决方案。
 - HTML 与 XHTML:区别及使用建议。
 - JSON:作用、用途及设计结构。
 
其他面试题
百度
(内容略,参考上文百度部分)
腾讯
(内容略,参考上文腾讯部分)
前言
本文总结了一些优质的前端面试题(多数源于网络),初学者阅后也要用心钻研其中的原理,重要知识需要系统学习,透彻学习,形成自己的知识链。万不可投机取巧,只求面试过关是错误的!
面试有几点需注意:
- 题目类型:技术视野、项目细节、理论知识题,算法题,开放性题,案例题。
 - 进行追问:确保深入理解,应对关联知识的扩展。
 - 态度重要:是否愿意与面试官共事,展现职业素养。
 - 激情驱动:对 Web 开发充满热情,持续学习和自我提升。
 
面试技巧:
- 少量提问:每个问题深入考察多个知识点,提升区分度和深度。
 - 解决问题能力:展示多种解决方案,理解底层机制。
 - 有激情:对所做工作充满热情,主动学习新技术。
 - 基础知识扎实:掌握核心知识点,确保能独立完成工作。
 
总结:
通过掌握上述知识点和面试技巧,前端工程师候选人可以更好地准备面试,展示自己的技术能力和职业素养,提升面试通过率。
参考资料
- Ant Design Tree 组件文档
 - React 官方文档 - 状态提升
 - React Hooks 使用指南
 - MDN Web Docs: CSS Grid Layout
 - CSS-Tricks: A Complete Guide to Grid
 - Grid by Example
 - Can I Use: CSS Grid
 










