前端面经(1)

我心飞翔 分类:vue

HTML、CSS相关

HTML5新特性

input新增了一些属性:color-调色板、tel-电话、number-数字、date-年月日

video、aideo视音频标签

语义化标签

语义化

语义化标签 : header、nav、main、footer

语义化的优点有:

(一)代码结构清晰,易于阅读,利于开发和维护

(二)方便设备解析根据语义渲染网页

(三)有利于(SEO)搜索引擎优化

(四)在浏览器css失效时,页面依然可读

如何语义化:不用纯样式标签(b、i、u)、少用无语义标签(div、span)、使用语义化标签

盒模型

所有HTML元素都可以看做是一个作盒子,在CSS中,"box model"这一术语是用来设计和布局时使用。

W3C盒子模型(标准盒子模型):宽=内部宽度(content)+border+padding+margin

IE盒子模型(怪异盒子模型):宽=内部宽度(content+border+padding)+margin

互换模型格式:

box-sizing:content-box;//变为标准盒模型(大部分浏览器默认)

box-sizing:border-box;//变为怪异盒子模型

行内元素、块级元素、空元素有哪些?区别?

1、行内元素:span、a、em、img、input

2、块级元素:div、ol、ul、form

3、空元素:br、hr、img、input

区别:

行内元素不换行、块级元素换行

正常情况下是块级元素包含行内元素,鲜少有行内元素包含块级元素

没有内容的标签称之为空元素,空元素是在开始标签中关闭的。

离线缓存与传统浏览器缓存的区别

离线缓存是整个应用,传统浏览器缓存是单个文件

离线缓存断网后依然可以打开页面,传统浏览器缓存不可以

离线缓断在有网络情况下优先使用缓存,传统浏览器缓存会通知网络更新缓存

能不能说一说浏览器的本地存储?各自优劣如何?

浏览器的本地存储主要分为Cookie、WebStorage, 其中WebStorage又可以分为localStorage和sessionStorage。

共同点: 都会在浏览器端保存,有大小和同源限制

不同点:

一、cookie数据始终在同源的http请求中携带,即cookie在浏览器和服务器间来回传递。sessionStorage和localStorage不会自动把数据发送给服务器,仅在本地保存。

二、存储大小限制也不同:cookie数据不能超过4K,sessionStorage和localStorage可以达到5M或者更多

三、作用域不同:sessionStorage:仅在当前浏览器窗口关闭之前有效;localstorage:数据始终有效,窗口或浏览器关闭也一直保存,除非删除数据;cookie:在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭

CSS样式优先级

!important>style>id>class

BFC

BFC 即块格式化上下文。BFC内的元素不会影响外面的元素。

创建:

1.float不为none

2.position为absolute或fixed

3.overflow不为visible

4.display为inline-block、flex、inline-flex等

应用:

1. 防止margin重叠

2. 清除内部浮动

3. 自适应多栏布局

三栏布局

绝对定位法:中间栏目使用margin/padding空出左右位置,左右使用绝对定位

浮动法:中间栏目使用margin/padding空出左右位置,左右使用浮动定位

Flex:flex:1

Grid:父元素:display:grid 子元素:grid-template-columns:100px auto 20px

CSS选择器

标签选择器

ID选择器

类选择器

组选择器

通配符选择器

后代选择器

子元素选择器

伪类选择器

Flex:1是什么

经常用于自适应布局。也就是flex-grow、flex-shrink、flex-basis的缩写

Display:flex的常用属性

flex-drection:设置主轴方向

Justify-content:设置主轴排列方式

Flex-wrap:设置是否换行

Align-content/align-item:侧轴排列(多行/单行)

预处理器less、sass

是css中一种抽象层。好处:

1.结构清晰、便于扩展

2.方便屏蔽浏览器的语法差异

3.多重继承

DOM、BOM对象

BOM是指浏览器对象模型,可以对浏览器窗口进行访问和操作。使用 BOM,开发者可以移动窗口、改变状态栏中的文本以及执行其他与页面内容不直接相关的动作。

DOM 是指文档对象模型,通过它,可以访问HTML文档的所有元素。 DOM 是 W3C的标准。

浏览器渲染机制

网页生成过程:

1.HTML被HTML解析器解析成DOM 树

2.css则被css解析器解析成CSSOM 树

3.结合DOM树和CSSOM树,生成一棵渲染树(Render Tree)

4.生成布局(flow),即将所有渲染树的所有节点进行平面合成

5.将布局绘制(paint)在屏幕上

重排(也称回流)

当DOM的变化影响了元素的几何信息(DOM对象的位置和尺寸大小),浏览器需要重新计算元素的几何属性,将其安放在界面中的正确位置,这个过程叫做重排。 触发:添加或者删除可见的DOM元素、元素尺寸改变——边距、填充、边框、宽度和高度

重绘

当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程,叫做重绘。 触发:改变元素的color、background、box-shadow等属性

重排重绘优化建议

1.样式表越简单,重排和重绘就越快。尽量用class,少用style一条条改变样式

2.重排和重绘的DOM元素层级越高,成本就越高。如果可以灵活用display,absolute,flex等重排开销会比较小,或不会影响其他元素的重排。

3.使用虚拟DOM的脚本库。

JS相关

js数据类型、typeof、instanceof

1) string、number、boolean、null、undefined、object(function、array)、symbol

2) typeof 主要用来判断数据类型

3) instanceof 判断该对象是谁的实例。

ES6

1. 新增symbol类型 表示独一无二的值,用来定义独一无二的对象属性名;

2. const/let 都是用来声明变量,不可重复声明,具有块级作用域。存在暂时性死区,也就是不存在变量提升。(const一般用于声明常量);

3. 变量的解构赋值(包含数组、对象、字符串、数字及布尔值,函数参数),剩余运算符(...rest);

4. 模板字符串(${data});

5. 扩展运算符(数组、对象);;

6. 箭头函数;

7. Set和Map数据结构;

8. Proxy/Reflect;

9. Promise

ES6里的symble

它的功能类似于一种标识唯一性的ID,每个Symbol实例都是唯一的。 Symbol类型的key是不能通过Object.keys()或者for...in来枚举的, 它未被包含在对象自身的属性名集合(property names)之中。 所以,利用该特性,我们可以把一些不需要对外操作和访问的属性使用Symbol来定义。

ES6里的set和map

  • Map对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。构造函数Map可以接受一个数组作为参数。
  • Set对象允许你存储任何类型的值,无论是原始值或者是对象引用。它类似于数组,但是成员的值都是唯一的,没有重复的值。

vue的key

1.key的作用主要是为了高效的更新虚拟DOM,其原理是vue在patch过程中通过key可以精准判断两个节点是否是同一个,从而避免频繁更新不同元素,使得整个patch过程更加高效,减少DOM操作量,提高性能。

2.另外,若不设置key还可能在列表更新时引发一些隐蔽的bug

3. vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们, 否则vue只会替换其内部属性而不会触发过渡效果。

普通函数和箭头函数的区别

1.箭头函数是匿名函数,不能作为构造函数,不能使用new

2.箭头函数不绑定arguments,取而代之用rest参数...解决

3.箭头函数不绑定this,会捕获其所在的上下文的this值,作为自己的this值

4.箭头函数通过 call() 或 apply() 方法调用一个函数时,只传入了一个参数,对 this 并没有影响。

5.箭头函数不能当做Generator函数,不能使用yield关键字

闭包(高频)

闭包是指有权访问另一个函数作用域中的变量的函数 当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行

  • 闭包用途:

能够访问函数定义时所在的词法作用域(阻止其被回收)

私有化变量

模拟块级作用域

创建模块

  • 闭包缺点:会导致函数的变量一直保存在内存中,过多的闭包可能会导致内存泄漏

原型、原型链(高频)

原型: 对象中固有的__proto__属性,该属性指向对象的prototype原型属性。

原型链: 当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又会有自己的原型,于是就这样一直找下去,也就是原型链的概念。原型链的尽头一般来说都是Object.prototype所以这就是我们新建的对象为什么能够使用toString()等方法的原因。

特点: JavaScript对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变。

this指向

代表的是当前上下文环境对象。在面向对象语言中this表示当前对象的一个引用。但在JavaScript中this是不固定的,它会随着环境的改变而改变。

1) 在方法中,this表示该方法所属的对象

2) 在单独使用的情况下,this代表的是全局对象

3) 在函数中,this表示的是全局对象

4) 在函数中但是在严格模式下,this为未定义(undefined)

5) 在事件中,this表示的是接收事件的元素

类似call、apply等方法可以改变this引用到的对象apply 、 call 和 bind 调用模式,这三个方法都可以显示的指定调用函数的 this 指向。apply接收参数的是数组,call接受参数列表,bind方法传入一个对象。

new关键字

1.首先创建了一个新的空对象

2.设置原型,将对象的原型设置为函数的prototype对象。

3.让函数的this指向这个对象,执行构造函数的代码(为这个新对象添加属性)

4.判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象。

作用域、作用域链

作用域负责收集和维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。(全局作用域、函数作用域、块级作用域)。 作用域链就是从当前作用域开始一层一层向上寻找某个变量,直到找到全局作用域还是没找到,就宣布放弃。这种一层一层的关系,就是作用域链。

继承(含es6)、多种继承方式

(1)第一种是以原型链的方式来实现继承,但是这种实现方式存在的缺点是,在包含有引用类型的数据时,会被所有的实例对象所共享,容易造成修改的混乱。还有就是在创建子类型的时候不能向超类型传递参数。

(2)第二种方式是使用借用构造函数的方式,这种方式是通过在子类型的函数中调用超类型的构造函数来实现的,这一种方法解决了不能向超类型传递参数的缺点,但是它存在的一个问题就是无法实现函数方法的复用,并且超类型原型定义的方法子类型也没有办法访问到。

(3)第三种方式是组合继承,组合继承是将原型链和借用构造函数组合起来使用的一种方式。通过借用构造函数的方式来实现类型的属性的继承,通过将子类型的原型设置为超类型的实例来实现方法的继承。这种方式解决了上面的两种模式单独使用时的问题,但是由于我们是以超类型的实例来作为子类型的原型,所以调用了两次超类的构造函数,造成了子类型的原型中多了很多不必要的属性。

(4)第四种方式是原型式继承,原型式继承的主要思路就是基于已有的对象来创建新的对象,实现的原理是,向函数中传入一个对象,然后返回一个以这个对象为原型的对象。这种继承的思路主要不是为了实现创造一种新的类型,只是对某个对象实现一种简单继承,ES5 中定义的 Object.create() 方法就是原型式继承的实现。缺点与原型链方式相同。

(5)第五种方式是寄生式继承,寄生式继承的思路是创建一个用于封装继承过程的函数,通过传入一个对象,然后复制一个对象的副本,然后对象进行扩展,最后返回这个对象。这个扩展的过程就可以理解是一种继承。这种继承的优点就是对一个简单对象实现继承,如果这个对象不是我们的自定义类型时。缺点是没有办法实现函数的复用。

(6)第六种方式是寄生式组合继承,组合继承的缺点就是使用超类型的实例做为子类型的原型,导致添加了不必要的原型属性。寄生式组合继承的方式是使用超类型的原型的副本来作为子类型的原型,这样就避免了创建不必要的属性。

回复

我来回复
  • 暂无回复内容