前端面试题总结

1. html5新特性、语义化

  • html5新特性

    音频video 视频 audio、画布canvas、H5存储localStorage sessionStorage

  • 语义化标签 : header nav main article section aside footer

    语义化意味着顾名思义,HTML5的语义化指的是合理正确的使用语义化的标签来创建页面结构 如 header,footer,nav,从标签上即可以直观的知道这个标签的作用,而不是滥用div。

    语义化的优点:

    对搜索引擎友好,有了良好的结构和语义,网页内容自然容易被搜索引擎抓取。 其他开发者便于阅读代码 结构明确,语义清晰的页面能有更好的用户体验 方便其他设备阅读(如屏幕阅读器,盲人设备和移动设备等)

2. 浏览器渲染机制、重绘、重排

一、网页生成过程:

 

网页的生成过程,大致可以分成五步

  1. HTML 代码转化成 DOM

  2. CSS 代码转化成 CSSOM(CSS Object Model)

  3. 结合 DOM 和 CSSOM,生成一棵渲染树(包含每个节点的视觉信息)

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

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

  这五步里面,第一步到第三步都非常快,耗时的是第四步和第五步。

  "生成布局"(flow)和"绘制"(paint)这两步,合称为"渲染"(render)

 

 二、重排(也称回流)和重绘

  网页生成的时候,至少会渲染一次。用户访问的过程中,还会不断重新渲染。

  以下三种情况,会导致网页重新渲染。

  1. 修改 DOM

  2. 修改样式表

  3. 用户事件(比如鼠标悬停、页面滚动、输入框键入文字、改变窗口大小等等)

  重新渲染,就需要重新生成布局和重新绘制。前者叫做"重排"(reflow),后者叫做"重绘"(repaint)。

  需要注意的是,"重绘"不一定需要"重排",比如改变某个网页元素的颜色,就只会触发"重绘",不会触发"重排",因为布局没有改变。但是,"重排"必然导致"重绘",比如改变一个网页元素的位置,就会同时触发"重排"和"重绘",因为布局改变了。

三、对于性能的影响

  重排和重绘会不断触发,这是不可避免的。但是,它们非常耗费资源,是导致网页性能低下的根本原因。

  提高网页性能,就是要降低"重排"和"重绘"的频率和成本,尽量少触发重新渲染。

  前面提到,DOM 变动和样式变动,都会触发重新渲染。但是,浏览器已经很智能了,会尽量把所有的变动集中在一起,排成一个队列,然后一次性执行,尽量避免多次重新渲染。

div.style.color = 'blue';
div.style.marginTop = '30px';

  上面代码中,div 元素有两个样式变动,但是浏览器只会触发一次重排和重绘。

  如果写得不好,就会触发两次重排和重绘。

div.style.color = 'blue';
var margin = parseInt (div.style.marginTop);
div.style.marginTop = (margin + 10) + 'px';

  上面代码对 div 元素设置背景色以后,第二行要求浏览器给出该元素的位置,所以浏览器不得不立即重排。

  一般来说,样式的写操作之后,如果有下面这些属性的读操作,都会引发浏览器立即重新渲染。

  1. offsetTop/offsetLeft/offsetWidth/offsetHeight

  2. scrollTop/scrollLeft/scrollWidth/scrollHeight

  3. clientTop/clientLeft/clientWidth/clientHeight

  4. getComputedStyle ()

  所以,从性能角度考虑,尽量不要把读操作和写操作,放在一个语句里面。

// bad
div.style.left = div.offsetLeft + 10 + "px";
div.style.top = div.offsetTop + 10 + "px";
​
// good
var left = div.offsetLeft;
var top  = div.offsetTop;
div.style.left = left + 10 + "px";
div.style.top = top + 10 + "px";

  一般的规则是:

  1. 样式表越简单,重排和重绘就越快。

  2. 重排和重绘的 DOM 元素层级越高,成本就越高。

  3. table 元素的重排和重绘成本,要高于 div 元素

3. css盒子模型

CSS 盒模型本质上是一个盒子,盒子包裹着HTML 元素,盒子由四个属性组成,从内到外分别是:content 内容padding 内填充border 边框外边距 margin

两种盒模型的区别

标准盒模型:

width = content-width
height = content-height 

怪异盒模型:

width = content-width + padding-width + border-width
height = content-height + padding-height + border-height

如何在CSS 设置这两个模型

标准盒模型:

box-sizing: content-box

怪异盒模型:

box-sizing: border-box

4. css样式优先级

!important>style>id>class

5. 什么是BFC?BFC的布局规则是什么?如何创建BFC?BFC应用?

什么是BFC

BFC(Block formatting context)直译为“块级格式化上下文”。BFC它是一个独立的渲染区域,只有Block-level box(块元素)参与,它规定了内部的Block-level box如何布局,并且与这个区域外部毫不相关。
可以理解成:创建了 BFC的元素就是一个独立的盒子,里面的子元素不会在布局上影响外面的元素(里面怎么布局都不会影响外部),BFC仍属于文档中的普通流
不是所有的元素,模式都能产生BFC。

BFC的布局规则

内部的Box会在垂直方向,一个接一个地放置。
Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。
每个盒子(块盒与行盒)的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
BFC的区域不会与float box重叠。
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
计算BFC的高度时,浮动元素也参与计算。

如何创建BFC

float的值不是none。
position的值不是static或者relative
display的值是inline-block、table-cell、flex、table-caption或者inline-flex
overflow的值不是visible

BFC的作用

利用BFC避免margin重叠
清除浮动的影响
防止文字环绕

6. 盒子水平垂直居中方法

四种方式:

  1. 利用绝对定位,先将元素的左上角通过top:50%和left:50%定位到页面的中心,然后再通过translate来调整元素的中心点到页面的中心。

  2. 利用绝对定位,设置四个方向的值都为0,并将margin设置为auto,由于宽高固定,因此对应方向实现平分,可以实现水平和垂直方向上的居中。该方法适用于盒子有宽高的情况。

  3. 利用绝对定位,先将元素的左上角通过top:50%和left:50%定位到页面的中心,然后再通过margin负值来调整元素的中心点到页面的中心。该方法适用于盒子宽高已知的情况。

  4. 使用flex布局,通过align-items:center和justify-content:center设置容器的垂直和水平方向上为居中对齐,然后它的子元素也可以实现垂直和水平的居中。

代碼如下:

  1. 第一种:给父级设置宽高100%,div设置绝对定位,left,right,top,bottom设置为0,margin:auto即可实现

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * { margin: 0;padding: 0; }
      body, html { width: 100%;height: 100%;position: relative;}
      .div { position: absolute;width: 200px;height: 200px;
        background: salmon;left: 0;right: 0;top: 0;bottom: 0;margin: auto;}
    </style>
  </head>
  <body>
    <div class="div"></div>
  </body>
</html>
​
  1. 第二种:利用绝对定位和tranform(过渡动画)实现,div绝对定位,left: 50%; top: 50%;然后设置 transform: translate3d(-50%,-50%,0);即可

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      body,
      html {
        width: 100%;
        height: 100%;
        position: relative;
      }
      .div {
        position: absolute;
        width: 200px;
        height: 200px;
        background: salmon;
        left: 50%;
        top: 50%;
        transform: translate3d(-50%, -50%, 0);
      }
    </style>
  </head>
  <body>
    <div class="div"></div>
  </body>
</html>
​
  1. 第三种:flex弹性盒布局,给父级div设置display:flex,设置水平和垂直居中 justify-content: center; align-items: center;

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
        html,body{height: 100%;}
      .div {
        width: 100%;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items:center;
      }
      .box {
        width: 200px;
        height: 200px;
        background: sandybrown;
      }
    </style>
  </head>
  <body>
    <div class="div">
      <div class="box"></div>
    </div>
  </body>
</html>
  1. 第四种:div设置绝对定位,left: 50%; top: 50%距离左和上是margin-left:calc(-div自身宽度/2),margin-top:calc(-div自身高度/2),也可以自己计算margin-left和margin-top的值

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      body,
      html {
        width: 100%;
        height: 100%;
        position: relative;
      }
      .div {
        position: absolute;
        width: 200px;
        height: 200px;
        background: salmon;
        left: 50%;
        top: 50%;
        margin-left: calc(-200px / 2);
        margin-top: calc(-200px / 2);
      }
    </style>
  </head>
  <body>
    <div class="div">
      <div class="box"></div>
    </div>
  </body>
</html>

7. 数据类型

8. JavaScript类型判断的四种方法

一、typeof

typeof是一个操作符而不是函数,其右侧跟一个一元表达式,并返回这个表达式的数据类型。

返回的结果用该类型的字符串(全小写字母)

用于判断数据类型,返回值为6个[字符串],分别为stringBooleannumberfunctionobjectundefined

console.log(typeof undefined) // undefind
console.log(typeof null)   // object
console.log(typeof true)   // boolean
console.log(typeof 43)    // number
console.log(typeof '21')   // string
console.log(typeof {a:1})   // object
console.log(typeof Symbol()) // symbol
console.log(typeof 123n)   // bigint
function a() {}
console.log(typeof a)     // function
var date = new Date()
var error = new Error()
console.log(typeof date)   // object
console.log(typeof error)   // object

二、instanceof

instanceof 是用来判断 A 是否为 B 的实例,表达式为:A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false。 在这里需要特别注意的是:instanceof 检测的是原型

instanceof用来判断对象,代码形式为obj1 instanceof obj2(obj1是否是obj2的实例),obj2必须为对象,否则会报错!其返回值为布尔值

通俗一些讲,instanceof 用来比较一个对象是否为某一个构造函数的实例。注意,instanceof可以准确的判断复杂数据类型,但是不能正确判断基本数据类型

console.log(12 instanceof Number) // false
console.log('22' instanceof String) // false
console.log(true instanceof Boolean) // false
console.log(null instanceof Object) // false
console.log(undefined instanceof Object) // false
 
console.log([] instanceof Array)  // true
console.log({a: 1} instanceof Object) // true
console.log(json instanceof Object) // true
function a() {}
console.log(a instanceof Function) // true
console.log(new Date() instanceof Date) //true
console.log(reg instanceof RegExp) //true
console.log(error instanceof Error) // true
 

三、Object.prototype.toString.call()

toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object Xxx] ,其中 Xxx 就是对象的类型。

对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。

console.log(Object.prototype.toString.call(1))     // [object Number]
console.log(Object.prototype.toString.call(1n))     // [object BigInt]
console.log(Object.prototype.toString.call('123'))   // [object String]
console.log(Object.prototype.toString.call(true))    // [object Boolean]
console.log(Object.prototype.toString.call(undefined)) // [object Undefined]
console.log(Object.prototype.toString.call(null))    // [object Null]
console.log(Object.prototype.toString.call({}))     // [object Object]
console.log(Object.prototype.toString.call([]))     // [object Array]
console.log(Object.prototype.toString.call(function a() {})) // [object Function]
console.log(Object.prototype.toString.call(Symbol()))     // [object Symbol]
console.log(Object.prototype.toString.call(Math))       // [object Math]
console.log(Object.prototype.toString.call(JSON))       // [object JSON]
console.log(Object.prototype.toString.call(new Date()))    // [object Date]
console.log(Object.prototype.toString.call(new RegExp()))   // [object RegExp]
console.log(Object.prototype.toString.call(new Error))    // [object Error]
console.log(Object.prototype.toString.call(window)      // [object Window]
console.log(Object.prototype.toString.call(document)     // [object HTMLDocument]

四、constructor

constructor属性,可以得知某个实例对象,到底是哪一个构造函数产生的。

constructor属性表示原型对象与构造函数之间的关联关系,如果修改了原型对象,一般会同时修改constructor属性,防止引用的时候出错。所以,修改原型对象时,一般要同时修改constructor属性的指向。

console.log('22'.constructor === String)       // true
console.log(true.constructor === Boolean)      // true
console.log([].constructor === Array)        // true
console.log(document.constructor === HTMLDocument)  // true
console.log(window.constructor === Window)      // true
console.log(new Number(22).constructor === Number)  // true
console.log(new Function().constructor === Function) // true
console.log((new Date()).constructor === Date)    // true
console.log(new RegExp().constructor === RegExp)   // true
console.log(new Error().constructor === Error)    // true

注意:

1、null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。

2、函数的 constructor 是不稳定的,这个主要体现在自定义对象上,当开发者重写 prototype 后,原有的 constructor 引用会丢失,constructor 会默认为 Object

9. []==false 和 ![]==false

  • 第一个 []==false 转为数字 0==0

  • 第二个 ![]==false 转为布尔 false==false

js中布尔值为false的六种情况

下面6种值转化为布尔值时为false,其他转化都为true

1、undefined(未定义,找不到值时出现)

2、null(代表空值)

3、false(布尔值的false,字符串"false"布尔值为true)

4、0(数字0,字符串"0"布尔值为true)

5、NaN(无法计算结果时出现,表示"非数值";但是typeof NaN===“number”)

6、""(双引号)或’’(单引号) (空字符串,中间有空格时也是true)

注意空数组空对象,负值转的布尔值时都为true

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值