基础面试题 72
1. 说说你对盒子模型的理解
是一个浏览器渲染引擎的规范,css 基础盒模型,每个元素都是一个矩形盒子,
目前常用的两种规范是
w3c 标准的 标准盒子模型
content padding border margin 四部分构成
ie 的怪异盒子模型
width,height 包括 content padding borer 另一部分是 margin
box-sizing 语法 可以定义该盒子的属性
content-box 标准盒子模型
border-box 怪异盒子模型
inherit (继承) 从父元素继承
2. css 选择器有哪些?优先级?哪些属性可以继承?
常用选择器有
class 类选择器
id 选择器
div 标签选择器
伪类选择器 :hover 等等
#box div 后代选择器 选择 id 为 box 下内部所有
#box >div 子代选择器 选择父元素 id 为 box 下的所有 div
p,span 群组选择器 选择所有 p,span 标签
!important > 行内样式>id>class >标签选择器>
可继承属性:
字体系列属性
文本系列属性
元素可见性
表格布局属性
列表属性
光标属性
3.元素水平垂直居中的方法有哪些?如果元素不定宽高呢?
实现元素水平垂直居中的方式:
- 利用定位+margin:auto
父级使用 relative 相对定位,子级使用 position 绝对定位
子级 left:0;top:0;right:0;botton:0;如果子级没有定宽高,就会被拉伸到跟父级一样的宽高,
这时候定号宽高,给 margin:auto; 实现垂直居中,虚拟定位已经占满整个父级
- 利用定位+margin:负值
同样,利用父相子绝,子级设置 top:50%,left:50, margin-left: 自身宽度的一半,margin-top:自身宽度的一半;
- 利用定位+transform
将 上面的方法使用 transform 代替,不需要知道自身宽高
- table 布局
将父级变为 display: table-cell 使用
vertical-align:middle; text-align:center;
子级变为 display :inline-block;行内样式
- flex 布局 (暴力)
1 | display: flex; |
- grid 布局
1 | display: grid; |
4.怎么理解回流跟重绘?什么场景下会触发?
在 html,我们可以把每个标签理解为一个个盒子
- 解析 HTML,生成 DOM 树,解析 CSS,生成 CSSDOM 树
- 将 DOM 树和 CSSOM 树结合,生成渲染树(Render Tree)
- Layout(回流):根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小)
Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
Display:将像素发送给 GPU,展示在页面上
回流:布局引擎会根据各种样式来计算每个盒子在页面上的大小和位置.
重绘:计算好盒模型大小,位置后,根据每个盒子的特性进行绘制
当我们对 DOM
的修改导致了样式的变化(color
或background-color
),却并未影响其几何属性时,浏览器不需重新计算元素的几何属性、直接为该元素绘制新的样式,
回流这一阶段主要是计算节点的位置和几何信息,那么当页面布局和几何信息发生变化的时候,就需要回流
触发回流一定会触发重绘
- 颜色的修改
- 文本方向的修改
- 阴影的修改
5.什么是响应式设计?响应式设计的基本原理是什么?如何做?
响应式设计就是网站可以兼容多个终端,而不是为某一个终端设置特定的版本
基本原理是通过媒体查询检测不同设备的尺寸做处理,
通过 media 标签媒体查询 百分比 vm/vh % 创建流式布局的弹性 UI
6.如果要做优化,CSS 提高性能的方法有哪些?
可以使用内联样式加载首屏 css
异步加载 css
压缩 css 文件
合理使用选择器
少使用 css 表达式
最好使用 link 标签 不要使用@import
7.对前端工程师这个职位是怎么样理解的?它的前景会怎么样
8.说说 JavaScript 中的数据类型?存储上的差别?
基本数据类型,引用数据类型,
String number bool symbol undefined null 存储在栈
声明 a=赋值 创建 b=a 修改 b 打印 a a 不会改变
虽然变量值相等,但是保存到了不同的内存地址
Array object function 存储到堆
同样 声明 obj1={} 创建 obj2=obj1 修改 obj2 obj1 的值会改变
因为实际上是栈内存的引用地址在堆内存地址赋值了一份 obj2,实际两个 obj 共同指向一个堆内存对象,
9.typeof 与 instanceof 区别
typeof 返回类型字符串,对 null,object,array 类型返回 object
那么 instanceof 就可以判断 一个变量是否是某个对象的实例
判断左边的对象的原型链里是否存在右边对象的原型对象
10.说说你对闭包的理解?闭包使用场景
闭包可以在内层函数访问到外部函数的作用域
\1. 创建私有函数,
\2. 延长变量生命周期
一般函数在函数的词法环境返回就会被销毁,但是闭包会保存创建时存在的词法环境,
在创建时上下文被销毁,但创建的词法环境依然存在
使用计数器,延迟调用
11.bind、call、apply 区别?如何实现一个 bind?
都可以改变 this 指向,
apply 第一个参数传递要指向的对象,如果为 null 或者 undefined,默认指向全局 window
都可以传参,apply 传递的是数组,call 传递的是参数列表 ,这两个都是一次性传参,bind 可以多次传参,
bind 返回的改变指向后的函数,apply 和 call 是立即执行
实现bind
的步骤,我们可以分解成为三部分:
- 修改
this
指向 - 动态传递参数
1 | // 方式一:只在bind中传递函数参数 |
12.说说你对事件循环的理解
事件循环用来实现单线程的非阻塞
在 js 当中,所有的任务分为异步,和同步,
同步:立即执行,直接进入主线程中执行,
异步,异步执行,比如 ajax 请求,定时器

同步任务进入主线程执行,异步任务进入任务队列,当主线程的任务执行完毕为空,会去任务队列读取任务,推入主线程,不断重复这个过程
异步任务又分为 微任务,宏任务,
常见的微任务
- promise.then 等
常见宏任务
- 定时器,等
执行机制为:
执行一个宏任务,如果遇到微任务就将它放到微任务事件队列,宏任务执行完,查看微任务队列,将里面的微任务队列执行完
async 相当于声明异步方法,await 用来等待异步方法执行,
正常情况下 await
后面是一个 promise 对象, 返回该对象的结果,如果不是 promise 对象,直接返回对应值
当不管后面是什么,都会阻塞后面代码 (加入微服务队列)
先执行 async 外面的同步代码,同步代码执行完,再回到 async 函数中,执行之前阻塞的代码
13.DOM 常见的操作有哪些
为 html 和 xml 提供 API,定义了一种方式可以访问该 dom 树,
来改变文档结构,样式,内容
14.说说你对 BOM 的理解,常见的 BOM 对象你了解哪些?
BOM Browser object model 浏览器对象模型,能够与浏览器进行交互的对象,
比如 window 是浏览器的接口,也是全局对象, 可以对窗口进行控制,大小,
或者使用 window.open(url)打开一个新页面,
location 用来获取 url 上的信息,location.reload()可以重新刷新当前页面,如果页面在上一次请求中没有改变过,就会从浏览器缓存中加载,强制从服务器加载需要加上 true
navigator 可以获取浏览器属性,
screen 获取用户屏幕信息
history 可以对浏览器 url 历史进行操作 forward back go length
15.Javascript 本地存储的方式有哪些?区别及应用场景?
- cookie
- sessionStorage
- localStorage
- indexedDB
存储大小:cookie 数据大小不超过 4k ,sessionStorage,localStorage 存储大小比 cookie 更大,可以达到 5m,暴怒同浏览器会有不同
有效时间:localstorage 存储持久数据,浏览器关闭后数据不丢失,除非主动删除,sessionstorage 在浏览器窗口关闭后自动删除,cooike 会设置过期事件,无论是浏览器或是窗口关闭
交互方式,cookie 的数据会⾃动的传递到服务器,服务器端也可以写 cookie 到客户端;sessionStorage 和 localStorage 不会⾃动把数据发给服务器,仅在本地保存
16.什么是防抖和节流?有什么区别?如何实现?
防抖和节流都是用来优化前端资源,提高性能的方式,
节流:n 秒内只运行一次,若在 n 秒内重复触发,也只执行一次
防抖:n 秒后执行该事件,若在 n 秒内重新触发,重新计时
防抖是一定时间连续触发的事件,只执行一次
节流是一段时间内只执行一次
可以采用定时器,时间戳的写法
17.如何通过 JS 判断一个数组
isArray()数组自带的判断方法
a instanceof Array 通过 instanceof 判断
object.prototype.toString.apply(a).Indexof(‘Array’)
18.说说你对作用域链的理解
变量起作用的范围
- 全局作用域
- 函数作用域
- 块级作用域
全局作用域
任何不在函数中或是大括号中声明的变量,都是在全局作用域下,全局作用域下声明的变量可以在程序的任意位置访问
函数作用域
函数作用域也叫局部作用域,如果一个变量是在函数内部声明的它就在一个函数作用域下面。这些变量只能在函数内部访问,不能在函数以外去访问
块级作用域
ES6 引入了let
和const
关键字,和var
关键字不同,在大括号中使用let
和const
声明的变量存在于块级作用域中。在大括号之外不能访问这些变量
当在
Javascript
中使用一个变量的时候,首先Javascript
引擎会尝试在当前作用域下去寻找该变量,如果没找到,再到它的上层作用域寻找,以此类推直到找到该变量或是已经到了全局作用域
19.JavaScript 原型,原型链 ? 有什么特点?
每个对象都会在其内部初始化一个属性,就是 prototype(原型)
当我们去访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去 prototype 里面找这个属性,这个属性 prototype 就会有自己的 prototype。
就这样一层一层的寻找,也就是我们平时所说的原型链的概念。JavaScript 对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承改变后的属性。
当我们需要一个属性时,JavaScript 引擎会先去找当前对象中是否有这个属性,如果没有的话,就会查找他的 prototype 对象中是否有这个属性,这样递推下去,一直找到 Object 内键对象。
函数可以有属性。 每个函数都有一个特殊的属性叫作原型prototype
/_代码基本架构 1.每个函数 function 都有一个 prototype,即显示原型(属性) 2.每个通过函数实例出来的对象都有一个proto,可称为隐式原型(属性) 3.对象的隐式原型的值为其对应构造函数的显示原型的值
_/
//显示原型与隐式原型
function Fn(){ // 内部语句:this.prototype = {}
}
//1.每个函数 function 都有一个 prototype 即显式原型(属性),默认指向一个空的 object 对象
console.log(Fn.prototype )
//2. 每个实例对象都有一个proto,可称为隐式原型(属性)
var fn = new Fn() //内部语句: this.proto = Fn.prototype
console.log(fn.proto)
//3.对象的隐式原型的值为其对应构造函数的显示原型的值
console.log(Fn.prototype === fn.proto)
原型的作用: 1.数据共享 节约内存内存空间 2.实现继承
20.请解释什么是事件代理
又叫事件委托,可以把需要绑定的事件委托给父元素,父元素担当事件监听事务,
事件代理的原理时 dom 元素的事件冒泡,可以提高性能,节省内存
适合事件委托的事件 click,mousedown mouseup keydown 等等
focus、blur 没有事件冒泡机制,无法进行委托绑定事件
21.谈谈 This 对象的理解
this 关键字是函数运行时自动生成的内部对象,
普通函数的 this 指向 全局 window;
事件处理函数的 this 指向事件源;
对象的成员方法 this 指向 宿主对象;
构造函数的 this 指向 new 实例化对象;
回调函数的 this 指向 全局 window;
22.new 操作符具体干了什么
new 操作符用于创建一个给定构造函数的实例对象
通过出来的实例可以访问到构造函数的属性,
new 操作符用来创建一个实例对象,这个对象是给定的构造函数
通过创造出来的实例可以访问到构造函数的属性
- 创建一个新的对象
obj
- 将对象与构建函数通过原型链连接起来
- 将构建函数中的
this
绑定到新建的对象obj
上 - 根据构建函数返回类型作判断,如果是原始值则被忽略,如果是返回对象,需要正常处理
23.null,undefined 的区别
数据类型不一样
undefined 表示不存在这个值,或者说变量未被定义,但是没有赋值,某个地方应该又
null 表示该对象被定义,值为 null 是一个空对象,没有任何属性和方法
null==undefind 返回 true ===返回 false
24.javascript 代码中的”use strict”;是什么意思
是一个字面量, 指定代码运行在严格模式下, 有很多限制:
变量在使用前必须声明,防止无意使用了未声明的变量
函数的中的 this 不再引用全局对象 而是 undefined 让代码变得更严谨
25. 同步和异步的区别
同步:所有操作都做完,才返回给用户,用户可以看到界面在刷新,等刷新完成,再进行下一步
异步,当客服端发送给服务端请求时,在等待服务端响应,客户端可以做其他事情,节约时间,提高效率
26.谈一谈箭头函数与普通函数的区别
箭头函数是匿名函数,不能作为构造函数,不能使用 new ,因为箭头函数没有 prototype,而 construct 在 prototype 里面
也可以说箭头函数本身没有 this,但是它在声明时可以捕获其所在上下文的 this 供自己使用。
不能使用 yield 命令
箭头函数不绑定 arguments,取而代之用 rest 参数…解决
27.JS 数组和对象的遍历方式,以及几种方式的比较
数组:for 循环
1 | var arr = ["a", "b", "c"]; |
还有 while 循环 do/while 循环
for 循环预先知道循环次数, while 不知道循环次数 do/while 至少循环次数
for of 它直接遍历值,而不是数组下标(或对象属性)。
for-of 语句不仅可以循环遍历数组对象。 还可以迭代 Array、Map、Set、String 等对象。
for-of 的工作原理是,向循环对象请求一个迭代器对象,然后通过迭代器对象的 next()方法来获得返回值。
1 | var arr = ["a", "b", "c"]; |
数组方法 forEach() map some() every() filter() reduce()
对象的遍历,一种是直接使用 for-in 循环;另一方式,是将对象转换成数组,再进行遍历
1 | var obj = { a: 2, b: 4, c: 6 }; |
Object.keys() 和 Object.getOwnPropertyNames()
28.如何解决跨域问题
跨域指浏览器不能执行其他网站的脚本,因为浏览器的同源策略,浏览器的安全策略
浏览器执行 js 脚本时,会检查这个页面属于哪个脚本,如果不是同源页面,不会执行
cors :服务端在响应头中加入字段:Access-control-allow-origion:Origion
jsonp: 动态创建 script 使用
- 本文作者: 不想
- 本文链接: https://evacat.top/2020/08/01/基础面试题72/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!