前端面试题(可直接背诵)

292 阅读10分钟

JavaScript

数据类型

数据类型分两种,基础类型和复杂类型,基础类型存储在栈中,复杂类型的对象存储在堆中,基础类型包括6种,分别是Undefined/Null/Boolean/Number/String/Symbol,除了基础类型外都是复杂类型,包括Object/Array/Function等。

原型

原型其实就是每个对象的父级,通过proto获取。在JavaScript中,一切都是对象。我可以将对象分成三类,分别是普通对象、函数对象、原型对象。
比如我们定一个函数Person,Person就是函数对象,new Person就是普通对象,Person.prototype就是原型对象,Person.proto是Person的父级,也就是Functuon的原型对象,相比普通对象,原型对象多了一个constructor属性,指向函数对象。
原型对象可以通过proto属性,访问父级的原型对象,这样就构成了原型通过proto连接原型的链状结构,也就是常说的原型链。
当我们访问对象的属性时,会先在对象上查找,如果没有定义该属性,则会在原型链中逐级查找。

继承

继承是一种概念,子类通过继承可以访问父类的属性和方法,在JavaScript中,对象的属性和方法分成两种,

  • 第一种是内部对象this上面的属性和方法
  • 第二种是原型上的属性和方法。

所以继承可以分成两步,

  • 第一步,是构建原型链,设置子类原型的proto指向父类的原型,这样就继承了父类原型上的属性和方法。
  • 第二步,在子函数第一行调用父函数,可以通过父函数.call的方式调用,这样就继承了父类内部对象this的属性和方法。

作用域

变量和函数能被访问的区域称为作用域,可以分成三类

  • 全局作用域:任何不在函数或者大括号中申明的变量,就是全局作用域。
  • 函数作用域:在函数内部申明,就是函数作用域。
  • 块级作用域:在大括号里面申明的,就是块级作用域,是es6新引入作用域。

而变量或函数的作用域所处的层级,是在创建阶段确认的,也就是常说的词法作用域,而非运行阶段。。当访问某个变量时,会先从当前作用域查找,如果没有找到会逐层往上查找,如果一直到全局作用域还没找到,则会在全局作用域创建一个变量。

闭包

闭包是指定义在函数内部的函数,通过闭包可以访问函数作用域的特性,可以实现两个功能。

  • 对象的私有变量
  • 变量的持久化,比如柯里化函数:把接受多个参数的函数变换成接受一个单一参数的函数,并返回一个新函数,这个新函数可以接受余下的函数,执行后返回结果。

注意事项
对于函数对象,我可以利用闭包的特性,将内部对象绑定的函数,写到prototype中。

this

this是函数运行时的内部对象,指向调用它的对象,调用方式通常有以下几种。

  • 在顶层直接调用函数,this就是全局对象window。
  • 如果函数是某个对象的属性,通过对象点函数的方式调用,this就是这个对象。
  • 函数通过apply/call注入对象的方式调用,this就是注入的这个对象。
  • 函数通过bind绑定某个对象,那么函数运行时,this就是绑定的这个对象。 箭头函数比较特殊,在编译期就已经绑定了当前对象。

数组

  • 操作方法
      • push(...插入的元素)
      • unshift(...插入的元素) 开头添加
      • splice(起始位置,删除数量,...插入的元素)
      • concat(...插入的元素,[...插入的元素]) 不会影响原数组
      • pop 删除最后一个
      • shift 删除第一个
      • splice
      • slice(开始位置,截止位置) 截取元素生成数组
      • splice
      • indexOf
      • includes
      • find
  • 排序
    • reverse 逆转
    • sort
  • 转换
    • reduce
    • join
  • 迭代
    • map
    • forEach
    • filter
    • every 全部true标识true
    • some 有一个true表示true

ES6

var/let/const

  1. var 用于申明变量,可以重复申明,如果是在顶层相当于全局变量,如果声明在方法里面是局部变量,var存在变量提升的情况,。
  2. let和const是es6新加入的语法,let用于申明变量,const用于申明常量,他们都是块级作用域,不可重复申明,在申明前存在暂时性死区。

Promise

Promise是异步编程的解决方案,可以通过new Promise来创建异步任务,又叫微任务,执行结果有两种,成功和失败。Promise对象有3个方法,分别是then、catch、finally,调用这三个方法都会返回一个新的Promise对象,其中then和catch可以通过监听函数的返回值来修改新的Promise对象的执行结果。
Promise还提供了几个静态方法

  • resolve
  • reject
  • all 全部成功
  • allSettled 全部结束
  • race 第一个成功

Proxy

Proxy可以用于实现修改对象或函数的行为,通过new-Proxy将需要代理的对象或函数传入第一个参数,第二个参数为代理的具体实现,常用可代理的方法有

  • get
  • set
  • apply

ES6 模块

ES6模块是ES6新增的模块化方案,早期的JavaScript是没有模块的概念,资源的加载是通过script标签自上而下,容易造成变量污染,大项目难以维护。为了解决这些问题,出现了几种JavaScript模块化方案。包括CommonJs、AMD、CMD、UMD、ES模块。

  • CommonJS 是NodeJs采用的模块化方式,加载是同步的,一个单独的文件就是一个模块,通过exports导出require导入。

  • AMD 是异步模块化规范,代表库是RequireJs,所有的依赖都定义在require函数中,等模块加载完后,require回调函数才会执行。

    /** main.js 入口文件/主模块 **/
    // 首先用config()指定各模块路径和引用名
    require.config({
      baseUrl: "js/lib",
      paths: {
        "jquery": "jquery.min",  //实际路径为js/lib/jquery.min.js
        "underscore": "underscore.min",
      }
    });
    // 执行基本操作
    require(["jquery","underscore"],function($,_){
      // some code here
    });
    

    很明显,所有依赖都写在前面,这是很不符合编码思想的,于是就出现了CMD。

  • CMD 也是异步模块化的一种,代表库是SeaJS,相比AMD的依赖前置,CMD采用的是依赖就近。

    define(function (requie, exports, module) {
         
        //依赖可以就近书写
        var a = require('./a');
        a.test();
         
        ...
        //软依赖
        if (status) {
         
            var b = requie('./b');
            b.test();
        }
    });
    
  • UMD 通用模块规范,既可用于服务端,也可以用于浏览器端,实际是CommonJs和AMD的糅合,会根据当前环境选择对应的加载方式。

  • ES6,是语言层面的模块化方案,完全可以取代AMD和CommonJS,可用于服务端和浏览器端。

    • ES6模块通过export导出,import导入,只有通过export导出的内部变量外部才能访问。
    • ES6导出和导入时,可以通过as对变量进行重命名,也可以通过export default导出默认的变量。

ES6 Decorator装饰器

ES6装饰器是一个函数,可以在不改变类结构的情况下,拓展类的属性和方法。装饰器可以分成两种,分别是类装饰器和类属性装饰器。

  • 类装饰器,更像是将类作为参数传递给装饰器,React高阶组件经常用到。

    @testable
    class MyTestableClass {
      // ...
    }
    
    function testable(target) {
      target.isTestable = true;
    }
    
  • 属性装饰,包含3个参数,分别是target,name,descriptor。可以收集属性信息或修改属性特征。

    function readonly(target, name, descriptor){
      descriptor.writable = false; // 将可写属性设为false
      return descriptor;
    }
    

CSS

盒模型

盒模型是指文档流在布局时,浏览器渲染引擎会将文档表示成一个矩形的盒子,这个盒子包含4个部分。

  • content,指实际内容,文本或者图像
  • border,是指边框,有粗细、样式、颜色三部分组成
  • padding,是指内边距
  • margin,是指外边距

盒模型包含两种

  • 标准的盒模型,盒子宽度=内容的宽度+边框+内边距+外边距,盒子高度=内容的高度+边框+内边距+外边距。
  • IE怪异的盒模型,盒子宽度=内容的宽度+外边距,盒子高度=内容的宽度+外边距,内容的宽高包含了边框和内边距。

我们可以通过box-sizing来设置盒模型的方式

  • content-box,默认行为,宽度和高度不包含border和padding,也就是标准盒模型
  • border-box, 元素的宽度和高度包含padding和border,也就是怪异盒模型
  • inherit,从父元素继承

选择器

分类

  • id选择器(#box),选择id为box的元素

  • 类选择器(.one),选择类名为one的所有元素

  • 标签选择器(div),选择标签为div的所有元素

  • 后代选择器(#box div),选择id为box元素内部所有的div元素

  • 子选择器(.one>one_1),选择父元素为.one的所有.one_1的元素

  • 相邻同胞选择器(.one+.two),选择紧接在.one之后的所有.two元素

  • 群组选择器(div,p),选择div、p的所有元素

  • 伪类选择器

    :link :选择未被访问的链接
    :visited:选取已被访问的链接
    :active:选择活动链接
    :hover :鼠标指针浮动在上面的元素
    :focus :选择具有焦点的
    :first-child:父元素的首个子元素
    
  • 伪元素选择器

    :first-letter :用于选取指定选择器的首字母
    :first-line :选取指定选择器的首行
    :before : 选择器在被选元素的内容前面插入内容
    :after : 选择器在被选元素的内容后面插入内容
    
  • 属性选择器

优先级

我们将样式分成四大类,分别是

  • 内联样式
  • ID选择器
  • 类选择器
  • 标签选择器

他们的优先级顺序是

内联 > ID选择器 > 类选择器 > 标签选择器

如果某个元素的同一个样式,被设置了多次,而且是通过子选择或者后代选择器的方式设置,那优先级的计算方式,会根据各大选择器类别出现的次数进行计算。

  • 首先比较样式设置中,ID选择器出现次数,会采用次数多的那个样式,如果相同。
  • 再次比较类选择器出现的次数
  • 最后比较标签选择器出现的次数
  • 如果还相同,那就采用最后设置的那个样式
    // ID(1次),类(1次),标签(3次)
    #nav-global > ul > li > a .nav-link
    

可继承继承

  • 字体系列属性
    • font:组合字体
    • font-family:规定元素的字体系列
    • font-weight:设置字体的粗细
    • font-size:设置字体的尺寸
    • font-style:定义字体的风格
    • font-variant:偏大或偏小的字体
  • 文本系列属性
    • text-indent:文本缩进
    • text-align:文本水平对刘
    • line-height:行高
    • word-spacing:增加或减少单词间的空白
    • letter-spacing:增加或减少字符间的空白
    • text-transform:控制文本大小写
    • direction:规定文本的书写方向
    • color:文本颜色
  • 元素可见性
    • visibility
  • 表格布局属性
    • caption-side:定位表格标题位置
    • border-collapse:合并表格边框
    • border-spacing:设置相邻单元格的边框间的距离
    • empty-cells:单元格的边框的出现与消失
    • table-layout:表格的宽度由什么决定
  • 列表属性
    • list-style-type:文字前面的小点点样式
    • list-style-position:小点点位置
    • list-style:以上的属性可通过这属性集合
  • 引用
    • quotes:设置嵌套引用的引号类型
  • 光标属性
    • cursor:箭头可以变成需要的形状 不可继承的属性
  • display
  • 文本属性:vertical-align、text-decoration
  • 盒子模型的属性:宽度、高度、内外边距、边框等
  • 背景属性:背景图片、颜色、位置等
  • 定位属性:浮动、清除浮动、定位position等
  • 生成内容属性:content、counter-reset、counter-increment
  • 轮廓样式属性:outline-style、outline-width、outline-color、outline
  • 页面样式属性:size、page-break-before、page-break-after