前端面试总结

383 阅读8分钟

前端面试总结

把近段时间面试的题目整理归类了一下,希望对大家有所帮助!后面的答案为自行整理,如有疏漏,欢迎指正!

CSS

1. css有几种隐藏元素的方法,区别是什么?

display:none 彻底隐藏元素,不占据空间,也就不影响布局,无法点击。
overflow:hidden 用来隐藏元素溢出部分,占据空间,无法点击。
visibility:hidden 占据空间,无法点击。在读屏软件中不会被识别。
opacity:0 只是一种视觉隐藏,占据空间,可以响应点击事件。在读屏软件中会被识别。
position:absolute 相当于把元素放到可视区域外,不影响布局,可以点击。在读屏软件中会被识别
clip(clip-path):rect()/inset()/polygon() 占据空间,无法点击
z-index:-1000 不占据空间,无法点击
transform:scale(0, 0) 占据空间,无法点击

2. css设置颜色透明度有几种方法?

rgba()
R:红色值。正整数 (0~255)
G:绿色值。正整数 (0~255)
B:蓝色值。正整数(0~255)
A:透明度。取值0~1之间
opacity: value
value:指定不透明度,从0.0(完全透明)到1.0(完全不透明)
opacity:属性具有继承性,会使容器中的所有元素都具有透明度

3. css选择器有哪些?它们的优先顺序分别是什么?

1.id选择器(#myid)
2.类选择器(.myclassname)
3.标签选择器(div,h1,p)
4.相邻选择器(h1+p)
5.子选择器(ul > li)
6.后代选择器(li a)
7.通配符选择器(*)
8.属性选择器(a[rel="external"])
9.伪类选择器(a:hover, li:nth-child)
!important > 行内样式 > ID选择器 > 类选择器 > 标签选择器 > 通配符选择器 > 继承 > 浏览器默认属性

渲染机制

1.重绘和回流分别是什么? 什么时候会触发重绘,什么时候会触发回流

  • 重绘是 当节点需要更改外观而不会影响布局的,比如改变 color、background-color、visibility等就叫称为重绘
  • 回流是 布局或者几何属性需要改变 就称为回流。
注意: 回流必定会发生重绘,重绘不一定会引发回流。回流所需的成本比重绘高的多,改变深层次的节点很可能导致父节点的一系列回流。

会导致回流的操作:

  • 页面首次渲染
  • 浏览器窗口大小发生改变
  • 元素尺寸或位置发生改变
  • 元素内容变化(文字数量或图片大小等等)
  • 元素字体大小变化
  • 添加或者删除可见的DOM元素
  • 激活CSS伪类(例如::hover)
  • 查询某些属性或调用某些方法

JS

1. js事件捕获和事件冒泡是什么?

oakland.github.io/2016/06/14/…

2. es6数组常用方法

1.  Array.from(targeObj, mapFunction, mapThis)
2.  Array.of(val1, val2, val3, ....)
3.  Array.copyWithin(target, start = 0, end = this.length)
4.  Array.find((value, index ,arr) => {})
5.  Array.findIndex
6.  Array.fill(value, start, end)
7.  Array.entries()
8.  Array.keys()
9.  Array.values()
10. Array.includes(start = 0)
11. Array.flat()
12. Array.flatMap(function)

3. es6对象新增方法

Object.is()
Object.assign()
Object.getOwnPropertyDescriptors()
__proto__属性
Object.getPrototypeOf()
Object.setPrototypeOf()
Object.keys()
Object.values()
Object.entries()
Object.fromEntries()

4. function和箭头函数有什么区别?

箭头函数是普通函数function的简写,可以更优雅的定义一个函数,和普通函数相比,有以下几点差异:

  • 函数体内的 this 对象,就是定义时所在的对象,而不是使用时所在的对象。
  • 不可以使用 arguments 对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
  • 不可以使用 yield 命令,因此箭头函数不能用作 Generator 函数。
  • 不可以使用 new 命令,因为:
    • 没有自己的 this,无法调用 call,apply。
    • 没有 prototype 属性 ,而 new 命令在执行时需要将构造函数的 prototype 赋值给新的对象的__proto__

5. 谈谈对this的理解

  • this总是指向函数的直接调用者(而非间接调用者)--谁调用它,它就指向谁
  • 当有new关键字时,this指向new出来的那个对象
  • 在事件中,this指向触发这个事件的对象
  • 特殊的是,IE中的attachEvent中的this总是指向全局对象Window

6. js的变量作用域有几种?分别是什么?

JavaScript 有两种作用域:全局和局部。
在函数定义之外声明的变量是全局变量,它的值可在整个程序中访问和修改。
在函数定义内声明的变量是局部变量。每当执行函数时,都会创建和销毁该变量,且无法通过函数之外的任何代码访问该变量。

7. let,const,var的区别是什么?

var声明变量可以重复声明,而let不可以重复声明
var是不受限于块级的,而let是受限于块级
var会与window相映射(会挂一个属性),而let不与window相映射
var可以在声明的上面访问变量,而let有暂时性死区,在声明的上面访问变量会报错
const声明之后必须赋值,否则会报错
const定义不可变的量,改变了就会报错
const和let一样不会与window相映射、支持块级作用域、在声明的上面访问变量会报错

8. es6解构赋值

数组解构

let [a, b, c] = [1, 2, 3]   //a=1, b=2, c=3
let [d, [e], f] = [1, [2], 3]    //嵌套数组解构 d=1, e=2, f=3
let [g, ...h] = [1, 2, 3]   //数组拆分 g=1, h=[2, 3]
let [i,,j] = [1, 2, 3]   //不连续解构 i=1, j=3
let [k,l] = [1, 2, 3]   //不完全解构 k=1, l=2

对象解构

let {a, b} = {a: 'aaaa', b: 'bbbb'}      //a='aaaa' b='bbbb'
let obj = {d: 'aaaa', e: {f: 'bbbb'}}
let {d, e:{f}} = obj    //嵌套解构 d='aaaa' f='bbbb'
let g;
(g = {g: 'aaaa'})   //以声明变量解构 g='aaaa'
let [h, i, j, k] = 'nice'    //字符串解构 h='n' i='i' j='c' k='e'

函数参数的定义

function personInfo({name, age, address}) {
  console.log(name, age, address)
}
personInfo({ address: 'shenzhen', name: 'felix', age: 18})

函数默认参数

function saveInfo({name= 'felix', age= 18, address= 'shenzhen'} = {}) {
  console.log(name, age, address)
}
saveInfo()

9. promise中有几种状态?

promise有三种状态:pending/reslove/reject
pending进行中,resolve已完成,reject已失败

10. 闭包是什么?闭包可以用来做什么?

函数A 里面包含了函数B,而 函数B 里面使用了 函数A 的变量,那么 函数B 被称为闭包。也就是说:闭包就是能够读取其他函数内部变量的函数

function A() {
  var a = 1;
  function B() {
    console.log(a);
  }
  return B();
}

闭包的特征

  • 函数内再嵌套函数
  • 内部函数可以引用外层的参数和变量
  • 参数和变量不会被垃圾回收制回收

对闭包的理解

使用闭包主要是为了设计私有的方法和变量。
闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。
在js中,函数即闭包,只有函数才会产生作用域的概念
闭包 的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量始终保持在内存中
闭包的另一个用处,是封装对象的私有属性和私有方法

闭包的好处
能够实现封装和缓存等

闭包的坏处
就是消耗内存、不正当使用会造成内存溢出的问题

使用闭包的注意点
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露

解决方法是:在退出函数之前,将不使用的局部变量全部删除

11. 如何让if(a == 5 && a == 8)为true

重写toString / valueOf

let a = {
    i: 1,
    toString: function () {
        return a.i+3;
    }
}

12.防抖和节流是什么?分别怎么实现的

防抖:任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行

function debounce(fn, waitTime) {
    // 1、创建一个标记用来存放定时器的返回值
    let timeout = null;
    return function() {
        // 2、每次当用户点击/输入的时候,把前一个定时器清除
        clearTimeout(timeout);
        // 3、然后创建一个新的 setTimeout,
        // 这样就能保证点击按钮后的 interval 间隔内
        // 如果用户还点击了的话,就不会执行 fn 函数
        timeout = setTimeout(() => {
            fn.call(this, arguments)
        }, waitTime)
    }
}
// 需要进行防抖的事件处理
function sayDebounce() {
    // 需要防抖的工作,在这里执行
    console.log("防抖成功!")
}
const myDebounce = document.getElementById("debounceBtn")
myDebounce.addEventListener("click", debounce(sayDebounce, 1000))

节流:指定时间间隔内只会执行一次任务

function throttle(fn, waitTime) {
    // 1、通过闭包保存一个标记
    let canRun = true;
    return function() {
        // 2、在函数开头判断标志是否为 true,不为 true 则中断函数
        if(!canRun) {
            return;
        }
        // 3、将 canRun 设置为 false,防止执行之前再被执行
        canRun = false;
        setTimeout( () => {
            fn.call(this, arguments);
            // 4、执行完事件之后,重新将这个标志设置为 true
            canRun = true;
        }, waitTime);
    }
}
// 需要节流的事件
function sayThrottle() {
    console.log("节流成功!")
}
const myThrottle = document.getElementById("throttleBtn")
myThrottle.addEventListener("click", throttle(sayThrottle, 1000))

13. 使用递归实现数组求和

function sum(arr) {
    const len = arr.length
    if (len === 0) {
        return 0
    } else if (len === 1) {
        return arr[0]
    } else {
        return arr[0] + sum(arr.slice(1))
    }
}

14. 使用冒泡排序算法将数组var a = [B,A,E,C,D];排序为var a=[A,B,C,D,E];

function mysort(list) {
    const len = list.length
    for (let i = 0; i < len; i++) {
        for (let j = i + 1; j < len; j++) {
            if (list[i] > list[j]) { // 相邻元素两两对比
                let temp = list[j] // 元素交换
                list[j] = list[i]
                list[i] = temp 
            }
        }
    }
    return list
}

参考文献

初中级前端面试题