前端面试题汇总

本文整理了前端面试中常见的65道题目,涵盖了变量声明、类型检查、数组操作、DOM操作、事件处理、异步编程、AJAX、Promise、闭包、事件委托、原型链、JavaScript对象创建、HTTP协议等多个核心知识点,旨在帮助开发者全面复习前端面试必备技能。
摘要由CSDN通过智能技术生成

1. var和let、const的区别

  • var是ES5语法,let、const是ES6语法;var有变量提升
  • var和let是变量,可修改;const是常量,不可修改
  • let、const有块级作用域,var没有

2. typeof返回哪些类型?

undefind、string、number、boolean、symbol、object、function
⚠️typeof null === ‘object’

3. 列举强制类型转换和隐式类型转换

  • 强制:parseInt、parseFloat、toString等
  • 隐式:if、逻辑运算、 ==、 +拼接字符串
[]+[]    // ""
[]+{
   }    // "[object Object]"
{
   }+[]    // 0
{
   }+{
   }    // "[object Object][object Object]"
true+true // 2
1+{
   a:1}  // "1[object Object]"

4. 手写深度比较,模拟lodash isEqual

<script>
    function isObject(obj){
   
        return typeof obj === 'object' && obj != null
    }
    function isEqual(obj1, obj2){
   
        if(!isObject(obj1) && !isObject(obj2)){
   
            // 值类型(注意:参与equal的一般不会是函数)
            return obj1 === obj2
        }
        if(obj1 === obj2){
   
            return true
        }

        // 两个都是对象或数组,并且不相等
        // 1. 先取出obj1和obj2的keys,比较个数
        const obj1Keys = Object.keys(obj1)
        const obj2Keys = Object.keys(obj2)
        if(obj1Keys.length !== obj2Keys.length){
   
            return false
        }

        // 2. 以obj1为基准,与obj2依次递归比较
        for(let key in obj1){
   
            //比较当前key的value -- 递归
            const res = isEqual(obj1[key], obj2[key])
            if(!res){
   
                return false
            }
        }

        // 3. 全相等
        return true
    }
    const obj1 = {
   
        a: 200,
        b: {
   
            x: 100,
            y: 200
        },
        c: 300
    }
    const obj2 = {
   
        a: 100,
        b: {
   
            x: 100,
            y: 200
        },
        c: 300
    }
    console.log(isEqual(obj1, obj2))
</script>

5. split()和join()的区别

  • split():以某个字符来拆分字符串为数组
  • join():以某种字符将数组拼接成字符串

6. 数组的pop、push、unshift、shift分别是什么?

(功能是什么,返回值是什么,是否会对原数组造成影响)

  • pop:删除数组尾部第一个元素,并返回这个元素。
  • push:在数组的尾部加入一个元素,并返回修改后数组的长度。
  • unshift:在数组的头部加入一个元素,并返回修改后数组的长度。
  • shift:删除数组头部的第一个元素,并返回这个元素。

7. 数组的API,有哪些是纯函数?

纯函数:

  • 不改变原数组(没有副作用)
  • 返回一个数组
纯函数:concat, map, filter, slice
非纯函数:pop, push, unshift, shift, forEach, some, every, reduce

8. 数组slice和splice的区别

功能区别(slice - 切片, splice - 剪接),参数和返回值,是否纯函数

const arr = [10, 20, 30, 40, 50]

// slice()纯函数
const arr1 = arr.slice() // slice()不传参相当于把原来数组深拷贝一份
const arr2 = arr.slice(1, 4) // 20,30,40
const arr3 = arr.slice(2) // 30,40,50
const arr4 = arr.slice(-2) // 40,50

// splice()非纯函数
const spliceRes = arr.splice(1, 2, 'a', 'b', 'c')
console.log(spliceRes)  // 10,a,b,c,40,50
console.log(arr)  // 20,30

9. [10,20,30].map(parseInt)返回结果是什么?

map的参数和返回值,parseInt参数和返回值

parseInt(string, radix)
string:必需。要被解析的字符串。
radix:可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。
如果省略该参数或其值为 0,则数字将以 10 为基础来解析。如果它以 “0x” 或 “0X” 开头,将以 16 为基数。
如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN。
// 拆解
[10, 20, 30].map((num, index) => {
   
	parseInt(num, index)
})

10. ajax请求get和post的区别

  • get一般用于查询操作,post一般用于提交操作
  • get参数拼接在url上,post放在请求体内(数据体积可更大)
  • 安全性:post易于防止CSRF

11. 函数call和apply的区别

主要是参数上的不同,call后面的参数是一个一个零散传进去的,apply后面的参数是以一个数组或者类数组的方式传进去的。

fn.call(this, p1, p2, p3, p4)
fn,apply(this, aruguments)

12. 事件代理(委托)是什么?

  • js中事件冒泡我们知道,子元素身上的事件会冒泡到父元素身上。
  • 事件代理就是,本来加在子元素身上的事件,加在了其父级身上。
  • 那就产生了问题:父级那么多子元素,怎么区分事件本应该是哪个子元素的?
  • 答案是:event对象里记录的有“事件源”,它就是发生事件的子元素。
  • 它存在兼容性问题,在老的IE下,事件源是 window.event.srcElement,其他浏览器是 event.target
  • 用事件委托有什么好处呢?
  • 第一个好处是效率高,比如,不用for循环为子元素添加事件了
  • 第二个好处是,js新生成的子元素也不用新为其添加事件了,程序逻辑上比较方便

13. 闭包是什么?有什么特性?有什么负面影响?

作用域和自由变量
闭包应用场景:a. 函数作为参数被传入; b. 函数作为返回值被返回
自由变量的查找,要在函数定义的地方,而非执行的地方!
影响:

  • 变量会常驻内存,得不到释放,闭包不要乱用。
// 自由变量示例 - 内存会被释放
let a = 0
function fn1(){
   
	let a1 = 100
	function fn2(){
   
		let a2 = 200
		function fn3(){
   
			let a3 = 300
			return a + a1 + a2 + a3
		}
		fn3()
	}
	fn2()
}
fn1()
// 闭包 - 函数作为返回值 - 内存不会被释放
function create(){
   
	let a = 100
	return function(){
   
		console.log(a)
	}
}
let fn = create()
let a = 200
fn()  // 100
// 闭包 - 函数作为参数 - 内存不会被释放
function print(fn1){
   
    let d = 200;
    fn1();
}
let d = 100;
function fn1(){
   
    console.log(d);
}
print(fn1);

闭包相关题目

14. 如何阻止事件冒泡和默认行为?

  • event.stopPropagation
  • event.preventDefault

15. 查找、添加、删除、移动DOM节点的方法?

答案

16. 如何减少DOM操作?

同上。

17. 解释jsonp的原理,为何它不是真正的ajax?

  • ajax是通过XMLHttpRequest()来实现的,jsonp是通过script标签来实现的。
  • 浏览器的同源策略(服务端没有同源策略)和跨域
  • 哪些html标签能绕过跨域?img标签,script标签
  • jsonp原理
// 客户端
<script>
window.abc = funtion(data){
   
	console.log(data)
}
</script>
<script src="http://localhost:8002/jsonp.js?username=xxx&callback=abc"></script>

// 服务器端返回jsonp.js
abc(
	{
   name: 'xxx'}
)

参考资料

18. document load和ready的区别?

window.addEventListener('load', funtion(){
   
	// 页面的全部资源加载完才会执行,包括图片、视频等
})
window.addEventListener('DOMContentLoaded', funtion(){
   . 
    // jquery中的ready也是
	// DOM渲染完即可执行,此时图片、视频还可能没有加载完
})

19. == 和 === 的区别

  • == 会尝试类型转换
  • === 严格相等
  • 哪些场景采用 == ?
    ⚠️除了 == null之外,其他都一律用 === ,例如:
const obj = {
    x: 100 }
if(obj.a == null){
   }
// 相当于
if(obj.a === null || obj.a === undefined){
   }

20. 函数声明和函数表达式的区别?

  • 函数声明 function fn(){…}
  • 函数表达式 const fn = function(){…}
  • 函数声明会在代码执行前预加载,而函数表达式不会

21. new Object()和Object.create()的区别

  • {}等同于new Object(),原型Object.prototype
  • Object.create(null) 没有原型
  • Object.create({…})可指定原型
const obj1 = {
   
	a: 10,
	b
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值