以下是一些经典的前端面试题及其答案:
1. 什么是闭包?
闭包(Closure)是指有权访问另一个函数作用域中变量的函数。简单来说,闭包就是一个函数能够访问它声明时所处的作用域以外的变量。
2. null 和 undefined 有什么区别?
null
表示一个空对象指针,可以将其赋给一个对象来释放该对象的引用。undefined
表示一个声明的变量未被赋值,也可以将其作为函数参数来指示该参数未传递。
3. 如何判断一个变量是数组?
可以使用 Array.isArray()
方法来判断一个变量是否是数组。
Array.isArray([]); // true
Array.isArray({}); // false
4. 如何判断一个变量是对象?
可以使用 typeof
运算符,当类型为 object
并且不为 null
时,这个变量就是对象。
typeof {}; // object
typeof null; // object
5. 如何判断一个变量是字符串?
可以使用 typeof
运算符判断一个变量是否为字符串。
typeof "hello"; // string
6. 如何将字符串转换成数字?
可以使用 parseInt()
函数或 parseFloat()
函数将字符串转换成数字。
parseInt("123"); // 123
parseFloat("123.45"); // 123.45
7. 如何将数字转换成字符串?
可以使用 toString()
方法将数字转换成字符串。
var num = 123;
num.toString(); // "123"
8. 什么是事件冒泡?
事件冒泡是指事件在触发元素后,会依次向上冒泡触发父元素的同类型事件。例如,当一个按钮被点击时,按钮的 click
事件会被触发,然后会冒泡到按钮的父元素,父元素也会触发一个 click
事件,然后依次冒泡到更上层的祖先元素。
9. 如何阻止事件冒泡?
可以使用 event.stopPropagation()
方法来阻止事件冒泡。
element.addEventListener('click', function (event) {
event.stopPropagation();
}, false);
10. 如何阻止默认事件行为?
可以使用 event.preventDefault()
方法来阻止默认事件行为。
element.addEventListener('click', function (event) {
event.preventDefault();
}, false);
11. 如何判断一个元素是否包含某个 class?
可以使用 element.classList.contains()
方法来判断一个元素是否包含某个 class。
var element = document.getElementById("myDiv");
if (element.classList.contains("myClass")) {
// ...
}
12. 如何添加一个 class?
可以使用 element.classList.add()
方法来添加一个 class。
var element = document.getElementById("myDiv");
element.classList.add("myClass");
13. 如何移除一个 class?
可以使用 element.classList.remove()
方法来移除一个 class。
var element = document.getElementById("myDiv");
element.classList.remove("myClass");
14. 如何在两个元素之间插入一个元素?
可以使用 element.insertBefore()
方法来在一个元素之前插入一个元素。
var parent = document.getElementById("parent");
var referenceNode = document.getElementById("reference");
var newNode = document.createElement("div");
parent.insertBefore(newNode, referenceNode);
15. 如何移除一个元素?
可以使用 element.parentNode.removeChild(element)
方法来移除一个元素。
var element = document.getElementById("myDiv");
element.parentNode.removeChild(element);
16. 如何获取元素的属性?
可以使用 element.getAttribute()
方法来获取元素的属性。
<div id="myDiv" title="This is a title"></div>
var element = document.getElementById("myDiv");
var title = element.getAttribute("title");
17. 如何设置元素的属性?
可以使用 element.setAttribute()
方法来设置元素的属性。
<div id="myDiv"></div>
var element = document.getElementById("myDiv");
element.setAttribute("title", "This is a title");
18. 如何获取元素的样式?
可以使用 element.style
对象来获取或设置元素的样式。
<div id="myDiv" style="color: red;"></div>
var element = document.getElementById("myDiv");
var color = element.style.color;
19. 如何设置元素的样式?
可以使用 element.style
对象来获取或设置元素的样式。
<div id="myDiv"></div>
var element = document.getElementById("myDiv");
element.style.color = "red";
20. 如何获得元素的文本内容?
可以使用 element.innerHTML
属性来获取或设置元素的文本内容。
<div id="myDiv">This is some text</div>
var element = document.getElementById("myDiv");
var text = element.innerHTML;
21. 如何设置元素的文本内容?
可以使用 element.innerHTML
属性来获取或设置元素的文本内容。
<div id="myDiv"></div>
var element = document.getElementById("myDiv");
element.innerHTML = "This is some text";
22. 如何创建一个元素?
可以使用 document.createElement()
方法来创建一个元素。
var element = document.createElement("div");
23. 如何向一个元素添加子元素?
可以使用 element.appendChild()
方法来向一个元素添加子元素。
var parent = document.getElementById("parent");
var child = document.createElement("div");
parent.appendChild(child);
24. 如何获取浏览器窗口大小?
可以使用 window.innerWidth
和 window.innerHeight
属性来获取浏览器窗口的宽度和高度。
var width = window.innerWidth;
var height = window.innerHeight;
25. 如何获取元素在文档中的位置?
可以使用 element.getBoundingClientRect()
方法来获取元素在文档中的位置。
<div id="myDiv"></div>
var element = document.getElementById("myDiv");
var rect = element.getBoundingClientRect();
console.log(rect.left, rect.top);
26. 如何在 URL 中获取查询字符串参数?
可以使用 URLSearchParams
对象来获取查询字符串参数。
var params = new URLSearchParams(window.location.search);
var value = params.get("name");
27. 什么是跨域请求?如何解决跨域问题?
跨域请求是指请求一个不同于当前页面的域,跨域问题是由于浏览器的同源策略导致的。可以通过以下方式来解决跨域问题:
- JSONP:利用
<script>
标签的src
属性可以跨域加载 JS 文件的方式,在 JS 文件中调用指定的回调函数,返回数据; - CORS:服务器设置响应头
Access-Control-Allow-Origin
来允许跨域请求; - 代理:利用服务器端的代理请求数据,前端的请求通过代理服务器发送给目标服务器,然后由代理服务器代替前端处理请求和响应。
28. 什么是事件委托?
事件委托是指利用事件的冒泡机制,在父元素上监听子元素的事件。通过事件委托,可以减少 DOM 操作,提高代码的效率和可维护性。
29. 什么是虚拟 DOM?
虚拟 DOM(Virtual DOM)是指用 JS 对象来模拟 DOM 树。React 和 Vue 等框架采用了虚拟 DOM 技术来提高性能,先对虚拟 DOM 进行修改,然后再将其与真正的 DOM 进行比较,只更新真正需要更新的部分,避免了无用的 DOM 操作。
30. 前端优化的方法有哪些?
-
减少 HTTP 请求次数
- 合并和压缩文件:将多个JS或CSS文件合并为一个,减少HTTP请求次数。使用压缩工具来缩小已有文件大小。
- 内联或缓存资源:对于一些小的JS和CSS,可以采用内联或缓存的方式来加载页面。这样能够减少HTTP请求,提高速度。
- 减少资源加载:资源的加载通常是网页加载速度最慢的环节。减少首次加载的资源减少页面加载时间。可以有效的通过资源合并、按需加载、懒加载、异步加载、前置加载来减少资源加载。
- CDN: 将资源分布到不同的CDN节点上,可以加快资源的文件下载速度,使网站更稳定。
-
压缩 JavaScript 和 CSS
- 压缩文件大小对于前端优化非常重要,使用工具将 .js 和 .css 文件及时压缩,减少其文件大小。
-
使用浏览器缓存
- 使用浏览器进行缓存,利用缓存做到动态资源的静态化,让页面的加载速度更快。可以通过设置Expires、Cache-Control、Etag、Last-Modified等HTTP header来控制浏览器缓存。
-
懒加载和 Deferred Loading
- 懒加载:懒加载是在页面滚动到可视区域时动态加载资源。懒加载能够减少页面加载时间,提高页面渲染速度,使页面更具有实用性和互动性。
- Deferred Loading:Deferred Loading 是将所有不必要的资源推迟到页面的首次加载过程之后。这包括 JavaScript,CSS 等等。
-
图片优化
- 通过调整图片的格式、大小、压缩来减小图片体积,在大量使用图片的网站中,这种优化显得尤为重要。
- 可以通过使用WebP格式的图片文件替换传统文件格式,WebP压缩技术比其它图片格式更高效,也更小。
-
压缩HTML
- 将HTML中的空格、注释等从文件中提取,减小HTML文件体积,优化页面加载速度。
-
服务端渲染
- 服务端渲染(SSR)能够在服务端根据具体请求内容生成 HTML,减轻前端的工作量。使用 SSR 能够提高页面渲染性能。
-
调整资源按需加载
- 避免在首次加载是需要下载大量的脚本,可以延迟加载和按需加载,优化页面加载速度和渲染速度。按需加载的方式可以有效的减小页面的大小,同时也能在保证全部功能的情况下提高页面的加载速度。
-
JavaScript 实现并发请求
- 在处理大数据量或高性能工作时,JavaScript的异步处理请求非常关键,一个方法是使用 Web Worker,这是一种在创作页面时,允许后台运行JS脚本的技术。还有,可以使用 ES6+ 中的async/await来顺序处理异步操作。
-
减少重绘和重排
- 减少使用未优化的CSS等造成的重排重绘次数的方法。事件委托、CSS合并、DOM元素添加次数都是一个非常重要的方面。