「面试」-面试题复习ing

163 阅读15分钟

最近在结合自己整理一些面试会考的题目(猜测),也算是对自己知识的一个总结和整理,想起来某些方面会更新进来~

CSS相关

选择器

css目前有标签选择器、类选择器、id选择器、伪类选择器等等 css3还增加了子代选择器、兄弟选择器等等。

参考MDN伪类列表

:link、:active、:hover、:focus、:first-child、:nth-child、:nth-last-child、:nth-of-type、:first-of-type、:last-of-type、:target、:checked、:enabled、:disabled

伪类和伪元素的区别

伪类是一个以冒号:作为前缀,被添加到一个选择器末尾的关键字,当你希望样式在特定状态下才被呈现到指定的元素时,可以往元素的选择器后面加上对应的伪类。

伪元素用于创建一些不在文档中的元素,并为其添加样式。比如说,可以通过::before来在一个元素前添加一些文本,并为这些文本添加样式。虽然用户可以看到这些文本,但是这些文本实际上不在文档树中。

选择器权重

css选择器的优先级是:内联 > ID选择器 > 类选择器 > 标签选择器

ID选择器权重可以看为1000

类选择器权重可以看为100

标签选择器权重可以看为10

盒模型

盒模型由content(内容)、padding(内边距)、border(边框)、margin(外边距)组成。

标准盒模型和怪异盒模型的区别?

在W3C标准下,我们定义元素的width值即为盒模型中的content的宽度值,height值即为盒模型中的content的高度值。

因此,标准盒模型:

元素的宽度 = margin-left + border-left + padding-left + width + padding-right + border-right + margin-right

怪异盒模型(IE盒模型)width的宽度并不是content的宽度,而是border-left + padding-left + content的宽度值 +padding-right + border-right之和,height同理。

因此,怪异盒模型:

元素占据的宽度 = margin-left + width + margin-right

虽然现代浏览器默认使用W3C的标准盒模型,但是不少情况下怪异盒模型更好用,于是W3C在css3中加入box-sizing

box-sizing: content-box // 标准盒模型
box-sizing: border-box // 怪异盒模型
box-sizing: padding-box // 火狐的私有模型,没人用

水平垂直居中

  • 定位
  • flex布局
  • grid

详情参考我的另一篇整理 juejin.cn/post/693565…

有哪些方式可以隐藏页面元素?

  • opacity:0。本质上是将元素的透明度为0,视觉上看起来隐藏了,但是依然在文档流中且可以互相交互。
  • visibility:hidden。与上一个方法类似的效果,依然占据空间,但是不可以交互了。
  • overflow:hidden。这个只隐藏元素溢出来的部分,跟visibility一样。占据空间,但是不可以交互。
  • display:none。这个是彻底隐藏了元素,元素从文档流中消失,既不占据空间也不可以交互,对布局也没有影响。
  • z-index:-9999。原理是将层级放到了底部,这样就被覆盖了,看起来隐藏了。
  • transform:scale(0,0):平面变换。将元素缩放为0,但是依然占据空间,但是不可以交互。

还有一些靠绝对定位把元素移动到可视区外。

BFC

书面解释:BFC(Block Formatting Context)

一块独立的区域,让处于BFC内部的元素与外部的元素互相隔离。

如何生成?

BFC触发条件:

  • 根元素
  • position:fixed/absolute
  • float不为none
  • overflow不为visible
  • display为inline-block、table-cell、table-caption

作用?

  • 防止margin重叠
  • 防止元素塌陷
  • 两栏布局,防止文字环绕

em/px/rem区别?

  • px:绝对单位,页面按精确像素展示。
  • em:相对单位,基准点为父节点字体的大小,如果自身定义了font-size按自身来计算(浏览器默认字体是16px)整个页面内1rem不是一个固定的值。
  • rem:相对单位,可理解为“root em”,相对根节点html的字体大小来计算,CSS3新加属性。

flex(自我认为这个可以解决所有)

web应用有不同设备尺寸和分辨率,这时需要响应式界面设计来满足复杂的布局需求,Flex弹性盒模型的优势在于开发人员只是声明布局应该具有的行为,而不需要给出具体的实现方式,浏览器负责完成实际布局,当布局涉及到不定宽度,分布对⻬的场景时,就要优先考虑弹性盒布局。

动画、过渡等

animation、transition

css有几种定位方式?

  • static:正常文档流定位,此时top、right、bottom、left和z-index无效,块级元素从上往下纵向排布,行级元素从左向右排列。
  • relative:相对定位,此时的「相对」是相对于正常文档流的位置。
  • absolute:相对于最近的非static定位祖先元素的偏移,比如一个绝对定位元素它的父级、和祖父级都为relative,它会相对他的父级产生偏移。
  • fixed:指定元素相对于屏幕视口的位置来指定元素位置。元素的位置在屏幕滚动时不会改变,比如那种回到顶部的按钮一般都是采用这种定位方式。
  • sticky:粘性定位,特性近似于relative和fixed的合体,其在实际应用中的近似效果就是ios通讯录滚动的时候的「顶屁股」。

如何理解z-index

css中的z-index属性控制重叠元素的垂直叠加顺序,默认元素的z-index为0,可以修改z-index来控制元素的图层位置,而且z-index只能影响设置来position的元素。

JS相关

变量提升

JavaScript引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量声明语句,都会被提升到代码头部,这就叫做变量提升。函数的提升优于变量的提升。

console.log(a); // undefined

var a = 33;

function b() {
  console.log(a);
}
b(); // 1

数据类型

分为原始数据类型引用数据类型

原始数据类型按值存储,引用数据类型按地址存储。前者存在栈内,后者存在堆内。

原始数据类型:null、undefined、string、boolean、number、symbol、bigInt

引用数据类型:object

判断类型

typeof

typeof 可以判断基本数据类型,null除外

null严格意义上来说是一个空对象指针,判断为object。

Array.isArray

判断数组可以用isArray来判断是否是一个数组

let testArr = [1,2,3,4];
Array.isArray(testArr); // true

toString.call()

也可以用Object.prototype.toString.call() 来进行判断。每一个继承 Object 的对象都有 toString 方法,如果 toString 方法没有重写的话,会返回 [Object type],其中 type 为对象的类型。

instanceof

instanceof 运算符也可以用来判断某个构造函数的 prototype 属性所指向的對象是否存在于另外一个要检测对象的原型链上。因为数组的构造函数是 Array,所以可以通过以下判断。注意:因为数组也是对象,所以 数组 instanceof Object 也为 true

ES2020新增??和?.

可以参考我的这篇文章

blog.csdn.net/weixin_4625…

为什么会有BigInt?

WHAT

BigInt是一种内置对象,它提供了一种方法来表示大于2的53次方-1的整数。这个原本是JavaScript中可以用Number表示的最大数字。BigInt可以表示任意大的整数。

WHY

在JS中,所有的数字都以双精度64位浮点格式表示,这导致JS中的Number无法精确表示非常大的整数,它会将非常大的整数四舍五入,确切地说,JS中的Number类型只能安全地表示-9007199254740991(-(2^53-1))和9007199254740991((2^53-1)),任何超出此范围的整数值都可能失去精度。

HOW

要创建BigInt,只需要在数字末尾追加n即可。另一种方式是BigInt()构造函数。BigInt和number不是严格相等的,是宽松相等。

this指向相关

this的指向不是在编写的时候确定的,而是在执行的时候确定的,同时,this不同的指向在于遵循来一定的规则。在哪里调用,this指向哪里。

  • 首先,在默认情况下,this是指向全局对象的,比如在浏览器就是指向window。

  • 其次,如果函数被调用的位置存在上下文对象时,那么函数是被隐式绑定的。

  • 当new一个实例,this会指向new出来的新对象。

  • 对于箭头函数,箭头函数本身是没有this指向的,所以箭头函数也不能改变this指向,详情看下一题。

箭头函数this指向

箭头函数不同于传统JavaScript中的函数,箭头函数没有属于自己的this,是继承父级函数的this指向,也就是说箭头函数所谓的this是捕获其所在上下文的this值,作为自己的this值,并且由于没有属于自己的this,所以箭头函数的this是不可改变的。

call、apply、bind区别

call、apply、bind都是改变this指向。

call

当前实例通过原型链查找机制,找到function.prototype上的call方法。

把找到的call方法执行,当call方法执行的时候,内部处理了一些事情。

  1. 首先把要操作的函数中的this关键字变为call方法一个传递的实参。
  2. 把call方法第二个及之后的实参获取到。
  3. 把要操作的函数执行,并且把第二个以后传递进来的实参传递给函数。
fn.call([this],[param]...)

apply

和call基本一致,唯一区别在于传参方式。apply把需要传递给fn的参数放到一个数组(或者类数组)中传递进去,虽然写的是一个数组,但是也相当于给fn一个个的传递。

fn.call(obj, 1, 2);
fn.apply(obj, [1, 2]);

bind

bind,语法跟call一样,但是bind不是立即执行,bind需要手动执行。

fn.call(obj, 1, 2);  // 改变fn中的this,并且把fn立即执行
fn.bind(obj, 1, 2);  // 改变fn中的this,fn并不执行

总结:都是改变this指向,call是一个个传参、apply是以数组的形式传参,bind也是一个个传参,但是bind不会立即执行,需要手动触发。

如何实现上面三个?

blog.csdn.net/weixin_4625…

原型、原型链

原型对象

绝大部分的函数(少数内建函数除外)都有一个prototype属性,这个属性是原型对象用来创建新对象实例,而所有被创建的对象都会共享原型对象,因此这些对象便可以访问原型对象的属性。

原型链

原因是每个对象都有 proto 属性,此属性指向该对象的构造函数的原型。

对象可以通过 proto 与上游的构造函数的原型对象连接起来,而上游的原型对象也有一个 proto ,这样就形成来原型链。

作用域

闭包

闭包其实就是一个可以访问外部函数变量的函数,简单理解为就是一个函数嵌套着另一个函数,内部函数可以访问外部函数的变量和值,避免垃圾回收机制。其实闭包就两个作用,一个是保护,一个是保存。比如jquery就是利用闭包的保护机制,避免jquery自己的方法因为和外面使用者定义的函数名相同而造成全局污染。而保存机制就是,执行一个函数会形成一个私有栈内存,一般来说当函数执行完毕,私有栈内存就会被释放和销毁,但是一旦当前私有栈内存里面的东西被其他的函数所占用了,那么当前私有栈内存就不会被释放和销毁掉。

Promise

blog.csdn.net/weixin_4625…

防抖和节流

blog.csdn.net/weixin_4625…

继承

可以参考我这篇文章

blog.csdn.net/weixin_4625…

0.1+0.2 !== 0.3,为什么

JS的number类型遵循的是IEEE 754标准,使用的是64位固定长度来表示。IEEE 754浮点数由三个域组成,分别为sign bit(符号位)、exponent bias(指数偏移值)和fraction(分数值)。64位中,sign bit占1位,exponent bias占11位,fraction占52位。

当一个数为正书,sign bit为0;当为负数时,sign bit为1。

怎么解决0.1+0.2 !== 0.3

面向对象编程(在我实习面试的时候,总会考到)

blog.csdn.net/weixin_4625…

浏览器相关

浏览器的主要组成部分是什么?

  1. 用户界面
  2. 浏览器引擎
  3. 呈现引擎
  4. 网络
  5. 用户界面后端
  6. JavaScript解释器
  7. 数据存储

简述浏览器是如何渲染UI的?

  1. 浏览器获取HTML文件,然后对文件进行解析,形成DOM Tree。
  2. 与此同时,进行css解析,生成style rules。
  3. 接着将DOM Tree与style rules合成为render tree。
  4. 接着进入布局(layout)阶段,也就是为每一个节点分配一个应出现在屏幕上的确切坐标。
  5. 随后调用GPU进行绘制,遍历render tree的节点,将元素呈现出来

缓存

重绘和重排

  • 重排:部分渲染树需要重新分析并且节点尺寸需要重新计算,表现为重新生成布局,重新排列元素。
  • 重绘:由于节点的几何属性发生改变或者由于样式发生改变,例如元素背景色改变,屏幕上的部分内容需要更新,表现为某些元素的外观被改变。

两者相比,重排的性能影响更大。

「重绘」不一定会出现「重排」,「重排」一定会出现「重绘」。

事件循环机制

JavaScript是一个单线程。单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。为了解决等待问题,JS的任务分为同步任务、异步任务。

所有的同步任务都在主线程执行,形成了一个执行栈。异步任务不进入主线程,而是进入一个「任务队列」。同步任务顺序执行,只有执行栈中的同步任务执行完了,系统才会读取任务中异步任务,才会把异步任务从事件队列中放入执行栈中执行,如此循环,直至所有任务执行完毕。

一般执行顺序如下:

执行同步、异步放到队列中,同步执行完再执行异步。

  • 执行script代码
  • 当有宏任务,放到事件队列的宏任务中
  • 当有微任务,放到事件队列的微任务中
  • 执行完所有的微任务,再去执行所有的宏任务

PS:promise=>这里的函数在当前队列直接执行.then=>放到微任务队列中执行。

常见的微任务:promise、process.nextTick 常见的宏任务:setTimeout、I/O、setInterval

  • 微任务队列优先于宏任务队列执行。
  • 微任务队列上创建的宏任务会被添加到当前宏任务队列的尾端,微任务队列中创建的微任务会被添加到微任务队列的尾端。
  • 只要微任务中还有任务,宏任务就要等待。
// 宏任务队列 1
setTimeout(() => {
  // 宏任务队列 2.1
  console.log('timer_1');
  setTimeout(() => {
    // 宏任务队列 3
    console.log('timer_3')
  }, 0)
  new Promise(resolve => {
    resolve()
    console.log('new promise')
  }).then(() => {
    // 微任务队列 1
    console.log('promise then')
  })
}, 0)
 
setTimeout(() => {
  // 宏任务队列 2.2
  console.log('timer_2')
}, 0)
 
console.log('========== Sync queue ==========')

输入URL到浏览器发生了什么?

简单答:浏览器根据请求的URL交给DNS域名解析,找到真实IP,向服务器发起请求。服务器交给后台处理完成后返回数据,浏览器接收文件(HTML、JS、CSS、图像等)。浏览器对加载到的资源进行语法解析,建立相应的内部数据解构(如HTML的DOM)。载入解析到的资源文件,渲染页面,完成。

PS:其实这里考察的点还是很深入的,有时间的话,大家可以在掘金或者各种博客上搜搜,会有很详细的解说,大家最好理解深入一些。

微信小程序相关

双线程

生命周期

常用API

wx:if和wxml中hidden的区别

vue相关

生命周期

v-if和v-show区别

双向数据绑定

typescript相关

与JavaScript区别

类型

前端工程化

webpack

gulp

Babel的原理是什么?

babel的转译过程也分为三个阶段

  • 解析Parse:将代码解析生成抽象语法树(即AST),即词法分析与语法分析的过程。
  • 转换Transform:对于AST进行变换一系列的操作,babel接受得到AST并通过babel-traverse对其进行遍历,在此过程中进行添加、更新及移除等操作。
  • 生成Generate:将变换后的AST再转换为JS代码,使用到的模块是babel-generator