当前位置:首页>IT那点事>2024年全面前端开发面试指南 | 最新前端面试题大全 | CSS/JavaScript/Vue面试宝典

2024年全面前端开发面试指南 | 最新前端面试题大全 | CSS/JavaScript/Vue面试宝典

CSS篇

1. CSS的盒模型

在HTML页面中的所有元素都可以看成是一个盒子,盒子的组成包括:

  • 内容(content)
  • 内边距(padding)
  • 边框(border)
  • 外边距(margin)

盒模型的类型:

  1. 标准盒模型:margin + border + padding + content
  2. IE盒模型:margin + content(border + padding)

控制盒模型的模式:

box-sizing: content-box; /* 默认值,标准盒模型 */
box-sizing: border-box;  /* IE盒模型 */

2. CSS选择器优先级

CSS的三大特性:继承性、层叠性、优先级

优先级排序(从高到低):

  1. !important
  2. 行内样式
  3. id选择器
  4. 类选择器/伪类选择器/属性选择器
  5. 标签选择器
  6. 全局选择器

3. 隐藏元素的方法

  1. display: none
  • 元素在页面上消失,不占据空间
  • 会导致重排重绘
  1. opacity: 0
  • 设置元素透明度为0
  • 元素不可见但占据空间
  • 可以响应事件
  1. visibility: hidden
  • 元素消失但占据空间
  • 不可见状态
  • 只会导致重绘
  1. position: absolute
  • 使用绝对定位将元素移出可视区域
  1. clip-path
  • 通过裁切使元素不可见

4. px和rem的区别

  • px是像素,是绝对单位长度
  • rem是相对单位,相对于html根节点的font-size值
  • 示例:当html的font-size: 62.5%时,1rem = 10px (16px * 62.5% = 10px)

5. 重绘重排

重排(回流)

  • 布局引擎重新计算元素的位置和大小
  • 影响其他元素的位置
  • 开销较大

重绘

  • 元素外观改变但不影响布局
  • 如颜色、背景等改变
  • 开销相对较小

6. 元素水平垂直居中的方式

  1. 定位 + margin
.parent {
    position: relative;
}
.child {
    position: absolute;
    left: 50%;
    top: 50%;
    margin-left: -50px; /* 宽度的一半 */
    margin-top: -50px;  /* 高度的一半 */
}
  1. 定位 + transform
.parent {
    position: relative;
}
.child {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
}
  1. flex布局
.parent {
    display: flex;
    justify-content: center;
    align-items: center;
}
  1. grid布局
.parent {
    display: grid;
    place-items: center;
}

7. CSS可继承的属性

可继承的属性:

  • font相关
  • text相关
  • line-height
  • color
  • visibility
  • cursor

不可继承的属性:

  • width
  • height
  • margin
  • padding
  • border

JavaScript篇

1. 浏览器加载文件(repaint/reflow)

加载顺序:

  • CSS、JS文件、图片按从上到下顺序加载
  • 不同浏览器并行下载文件数不同

建议:

  • JS文件放在页面底部
  • CSS文件放在头部

2. 存储方式对比

Cookie vs LocalStorage vs SessionStorage:

  1. 存储时间:
  • Cookie:可设置过期时间
  • SessionStorage:会话期间
  • LocalStorage:永久存储
  1. 存储大小:
  • Cookie:约5KB
  • LocalStorage/SessionStorage:约5MB
  1. 通信:
  • Cookie:参与服务器通信
  • LocalStorage/SessionStorage:仅客户端存储

3. 事件代理(委托)

原理:利用事件冒泡,把子元素的事件绑定到父元素上

优点:

  • 减少事件绑定数量
  • 动态元素也能响应事件
  • 节省内存

示例:

parent.addEventListener('click', function(e) {
    if(e.target.tagName === 'BUTTON') {
        // 处理逻辑
    }
});

4. this的工作机制

五种场景:

  1. 普通函数调用:绑定全局对象
  2. 对象方法调用:绑定到该对象
  3. 构造函数调用:绑定到新创建的对象
  4. apply/call调用:绑定到指定对象
  5. 箭头函数:继承外层作用域的this

5. 闭包

定义:有权访问另一个函数作用域中变量的函数

作用:

  • 实现私有变量
  • 保留函数内部变量
  • 防止全局污染

示例:

function counter() {
    let count = 0;
    return function() {
        return ++count;
    }
}

const increment = counter();
console.log(increment()); // 1
console.log(increment()); // 2

6. Promise

特点:

  • 三种状态:pending、fulfilled、rejected
  • 状态不可逆
  • 链式调用

基本用法:

const promise = new Promise((resolve, reject) => {
    // 异步操作
    if (/* 成功 */) {
        resolve(value);
    } else {
        reject(error);
    }
});

promise
    .then(value => {})
    .catch(error => {});

7. async/await vs Promise

区别:

  • async/await是基于Promise实现
  • async/await语法更简洁
  • async/await便于错误处理
  • async/await便于调试

示例:

// Promise方式
function getData() {
    return fetch(url)
        .then(res => res.json())
        .then(data => console.log(data))
        .catch(err => console.error(err));
}

// async/await方式
async function getData() {
    try {
        const res = await fetch(url);
        const data = await res.json();
        console.log(data);
    } catch(err) {
        console.error(err);
    }
}

Vue篇

1. 生命周期

主要生命周期钩子:

export default {
    beforeCreate() {
        // 实例创建前
    },
    created() {
        // 实例创建后
    },
    beforeMount() {
        // 挂载前
    },
    mounted() {
        // 挂载后
    },
    beforeUpdate() {
        // 更新前
    },
    updated() {
        // 更新后
    },
    beforeDestroy() {
        // 销毁前
    },
    destroyed() {
        // 销毁后
    }
}

使用keep-alive时额外的生命周期:

  • activated:激活时
  • deactivated:停用时

2. keep-alive

作用:

  • 缓存组件状态
  • 避免重复创建组件
  • 提升性能

使用场景:

  • 频繁切换的组件
  • 需要保持组件状态的场景
  • 需要避免重复请求的场景

3. v-if vs v-show

v-if:

  • 真正的条件渲染
  • 会销毁和重建组件
  • 适合不经常变化的场景

v-show:

  • 基于CSS display控制显示
  • 只是切换显示状态
  • 适合频繁切换的场景

4. ref的使用

作用:获取DOM元素或组件实例

示例:

<template>
    <div>
        <input ref="inputRef">
    </div>
</template>

<script>
export default {
    mounted() {
        this.$refs.inputRef.focus();
    }
}
</script>

5. nextTick

作用:

  • 等待DOM更新完成后执行回调
  • 获取更新后的DOM内容

示例:

this.message = 'updated'
this.$nextTick(() => {
    // DOM已更新
    console.log(this.$refs.msg.textContent)
})

浏览器相关

1. 跨域解决方案

  1. CORS
// 服务端设置
header('Access-Control-Allow-Origin: *');
  1. JSONP
function jsonp({ url, params, callback }) {
    return new Promise((resolve, reject) => {
        let script = document.createElement('script');
        window[callback] = function(data) {
            resolve(data);
            document.body.removeChild(script);
        }
        params = { ...params, callback };
        let arrs = [];
        for (let key in params) {
            arrs.push(`${key}=${params[key]}`);
        }
        script.src = `${url}?${arrs.join('&')}`;
        document.body.appendChild(script);
    });
}
  1. 代理服务器
// vue.config.js
module.exports = {
    devServer: {
        proxy: {
            '/api': {
                target: 'http://target-server',
                changeOrigin: true
            }
        }
    }
}

2. 页面渲染过程

  1. 解析HTML生成DOM树
  2. 解析CSS生成CSSOM树
  3. 将DOM和CSSOM合并成渲染树
  4. 布局(Layout)
  5. 绘制(Paint)

3. 防抖和节流

防抖:

function debounce(fn, delay) {
    let timer = null;
    return function(...args) {
        if (timer) clearTimeout(timer);
        timer = setTimeout(() => {
            fn.apply(this, args);
        }, delay);
    }
}

节流:

function throttle(fn, delay) {
    let flag = true;
    return function(...args) {
        if (!flag) return;
        flag = false;
        setTimeout(() => {
            fn.apply(this, args);
            flag = true;
        }, delay);
    }
}

4. 大文件上传

实现要点:

  1. 文件切片
  2. 并发控制
  3. 断点续传
  4. 进度监控

示例代码:

// 文件切片
function createFileChunk(file, size = 2 * 1024 * 1024) {
    const chunks = [];
    let cur = 0;
    while (cur < file.size) {
        chunks.push({ file: file.slice(cur, cur + size) });
        cur += size;
    }
    return chunks;
}

// 上传请求
async function uploadChunks(chunks) {
    const requests = chunks.map((chunk, index) => {
        const formData = new FormData();
        formData.append('chunk', chunk.file);
        formData.append('index', index);
        return axios.post('/upload', formData);
    });
    await Promise.all(requests);
}

这些内容涵盖了前端面试中的主要知识点,建议结合实际项目经验来理解和运用这些概念。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

给TA打赏
共{{data.count}}人
人已打赏
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
有新私信 私信列表
搜索

本站承接WordPress建站仿站、二次开发、主题插件定制等PHP开发服务!