乐趣区

关于前端:前端常考面试题整理

display:none 与 visibility:hidden 的区别

这两个属性都是让元素暗藏,不可见。两者区别如下:

(1)在渲染树中

  • display:none会让元素齐全从渲染树中隐没,渲染时不会占据任何空间;
  • visibility:hidden不会让元素从渲染树中隐没,渲染的元素还会占据相应的空间,只是内容不可见。

(2)是否是继承属性

  • display:none是非继承属性,子孙节点会随着父节点从渲染树隐没,通过批改子孙节点的属性也无奈显示;
  • visibility:hidden是继承属性,子孙节点隐没是因为继承了 hidden,通过设置visibility:visible 能够让子孙节点显示;
    (3)批改惯例文档流中元素的 display 通常会造成文档的重排,然而批改 visibility 属性只会造成本元素的重绘;

(4)如果应用读屏器,设置为 display:none 的内容不会被读取,设置为 visibility:hidden 的内容会被读取。

介绍 plugin

插件零碎是 Webpack 胜利的一个关键性因素。在编译的整个生命周期中,Webpack 会触发许多事件钩子,Plugin 能够监听这些事件,依据需要在相应的工夫点对打包内容进行定向的批改。

一个最简略的 plugin 是这样的:

class Plugin{
      // 注册插件时,会调用 apply 办法
      // apply 办法接管 compiler 对象
      // 通过 compiler 上提供的 Api,能够对事件进行监听,执行相应的操作
      apply(compiler){
          // compilation 是监听每次编译循环
          // 每次文件变动,都会生成新的 compilation 对象并触发该事件
        compiler.plugin('compilation',function(compilation) {})
      }
}

注册插件:

// webpack.config.js
module.export = {
    plugins:[new Plugin(options),
    ]
}

事件流机制:

Webpack 就像工厂中的一条产品流水线。原材料通过 Loader 与 Plugin 的一道道解决,最初输入后果。

  • 通过链式调用,按程序串起一个个 Loader;
  • 通过事件流机制,让 Plugin 能够插入到整个生产过程中的每个步骤中;

Webpack 事件流编程范式的外围是根底类 Tapable,是一种 观察者模式 的实现事件的订阅与播送:

const {SyncHook} = require("tapable")

const hook = new SyncHook(['arg'])

// 订阅
hook.tap('event', (arg) => {
    // 'event-hook'
    console.log(arg)
})

// 播送
hook.call('event-hook')

Webpack 中两个最重要的类 CompilerCompilation 便是继承于 Tapable,也领有这样的事件流机制。

  • Compiler : 能够简略的了解为 Webpack 实例,它蕴含了以后 Webpack 中的所有配置信息,如 options,loaders, plugins 等信息,全局惟一,只在启动时实现初始化创立,随着生命周期逐个传递;
  • Compilation: 能够称为 编译实例。当监听到文件产生扭转时,Webpack 会创立一个新的 Compilation 对象,开始一次新的编译。它蕴含了以后的输出资源,输入资源,变动的文件等,同时通过它提供的 api,能够监听每次编译过程中触发的事件钩子;
  • 区别:

    • Compiler 全局惟一,且从启动生存到完结;
    • Compilation对应每次编译,每轮编译循环均会从新创立;
  • 罕用 Plugin:

    • UglifyJsPlugin: 压缩、混同代码;
    • CommonsChunkPlugin: 代码宰割;
    • ProvidePlugin: 主动加载模块;
    • html-webpack-plugin: 加载 html 文件,并引入 css / js 文件;
    • extract-text-webpack-plugin / mini-css-extract-plugin: 抽离款式,生成 css 文件;DefinePlugin: 定义全局变量;
    • optimize-css-assets-webpack-plugin: CSS 代码去重;
    • webpack-bundle-analyzer: 代码剖析;
    • compression-webpack-plugin: 应用 gzip 压缩 js 和 css;
    • happypack: 应用多过程,减速代码构建;
    • EnvironmentPlugin: 定义环境变量;
  • 调用插件 apply 函数传入 compiler 对象
  • 通过 compiler 对象监听事件

loader 和 plugin 有什么区别?

webapck 默认只能打包 JS 和 JOSN 模块,要打包其它模块,须要借助 loader,loader 就能够让模块中的内容转化成 webpack 或其它 laoder 能够辨认的内容。

  • loader就是模块转换化,或叫加载器。不同的文件,须要不同的 loader 来解决。
  • plugin是插件,能够参加到整个 webpack 打包的流程中,不同的插件,在适合的机会,能够做不同的事件。

webpack 中都有哪些插件,这些插件有什么作用?

  • html-webpack-plugin 主动创立一个 HTML 文件,并把打包好的 JS 插入到 HTML 文件中
  • clean-webpack-plugin 在每一次打包之前,删除整个输入文件夹下所有的内容
  • mini-css-extrcat-plugin 抽离 CSS 代码,放到一个独自的文件中
  • optimize-css-assets-plugin 压缩 css

::before 和 :after 的双冒号和单冒号有什么区别?

(1)冒号 (:) 用于 CSS3 伪类,双冒号 (::) 用于 CSS3 伪元素。
(2)::before就是以一个子元素的存在,定义在元素主体内容之前的一个伪元素。并不存在于 dom 之中,只存在在页面之中。

留神: :before:after 这两个伪元素,是在 CSS2.1 里新呈现的。起初,伪元素的前缀应用的是单冒号语法,但随着 Web 的进化,在 CSS3 的标准里,伪元素的语法被批改成应用双冒号,成为::before::after

Sass、Less 是什么?为什么要应用他们?

他们都是 CSS 预处理器,是 CSS 上的一种形象层。他们是一种非凡的语法 / 语言编译成 CSS。例如 Less 是一种动静款式语言,将 CSS 赋予了动静语言的个性,如变量,继承,运算,函数,LESS 既能够在客户端上运行 (反对 IE 6+, Webkit, Firefox),也能够在服务端运行 (借助 Node.js)。

为什么要应用它们?

  • 构造清晰,便于扩大。能够不便地屏蔽浏览器公有语法差别。封装对浏览器语法差别的反复解决,缩小无意义的机械劳动。
  • 能够轻松实现多重继承。齐全兼容 CSS 代码,能够不便地利用到老我的项目中。LESS 只是在 CSS 语法上做了扩大,所以老的 CSS 代码也能够与 LESS 代码一起编译。

文档申明(Doctype)和 <!Doctype html> 有何作用? 严格模式与混淆模式如何辨别?它们有何意义?

文档申明的作用: 文档申明是为了通知浏览器,以后 HTML 文档应用什么版本的 HTML 来写的,这样浏览器能力依照申明的版本来正确的解析。

的作用:<!doctype html> 的作用就是让浏览器进入规范模式,应用最新的 HTML5 规范来解析渲染页面;如果不写,浏览器就会进入混淆模式,咱们须要防止此类情况产生。

严格模式与混淆模式的辨别:

  • 严格模式 :又称为规范模式,指浏览器依照W3C 规范解析代码;
  • 混淆模式:又称怪异模式、兼容模式,是指浏览器用本人的形式解析代码。混淆模式通常模仿老式浏览器的行为,以避免老站点无奈工作;

辨别 :网页中的DTD,间接影响到应用的是严格模式还是浏览模式,能够说DTD 的应用与这两种形式的区别非亲非故。

  • 如果文档蕴含严格的 DOCTYPE,那么它个别以严格模式出现( 严格 DTD ——严格模式);
  • 蕴含过渡 DTDURIDOCTYPE,也以严格模式出现,但有过渡 DTD 而没有 URI(对立资源标识符,就是申明最初的地址)会导致页面以混淆模式出现(有 URI 的过渡 DTD ——严格模式;没有 URI 的过渡 DTD ——混淆模式);
  • DOCTYPE 不存在或模式不正确会导致文档以混淆模式出现(DTD 不存在或者格局不正确——混淆模式);
  • HTML5 没有 DTD,因而也就没有严格模式与混淆模式的区别,HTML5 有绝对宽松的 法,实现时,曾经尽可能大的实现了向后兼容(HTML5 没有严格和混淆之分)。

总之,严格模式让各个浏览器对立执行一套标准兼容模式保障了旧网站的失常运行。

isNaN 和 Number.isNaN 函数的区别?

  • 函数 isNaN 接管参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因而非数字值传入也会返回 true,会影响 NaN 的判断。
  • 函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再持续判断是否为 NaN,不会进行数据类型的转换,这种办法对于 NaN 的判断更为精确。

参考 前端进阶面试题具体解答

元素的层叠程序

层叠程序,英文称作 stacking order,示意元素产生层叠时有着特定的垂直显示程序。上面是盒模型的层叠规定:

(1)背景和边框:建设以后层叠上下文元素的背景和边框。
(2)负的 z -index:以后层叠上下文中,z-index 属性值为负的元素。
(3)块级盒:文档流内非行内级非定位后辈元素。
(4)浮动盒:非定位浮动元素。
(5)行内盒:文档流外行内级非定位后辈元素。
(6)z-index:0:层叠级数为 0 的定位元素。
(7)正 z -index:z-index 属性值为正的定位元素。

留神: 当定位元素 z -index:auto,生成盒在以后层叠上下文中的层级为 0,不会建设新的层叠上下文,除非是根元素。

对盒模型的了解

CSS3 中的盒模型有以下两种:规范盒子模型、IE 盒子模型 盒模型都是由四个局部组成的,别离是 margin、border、padding 和 content。

规范盒模型和 IE 盒模型的区别在于设置 width 和 height 时,所对应的范畴不同:

  • 规范盒模型的 width 和 height 属性的范畴只蕴含了 content,
  • IE 盒模型的 width 和 height 属性的范畴蕴含了 border、padding 和 content。

能够通过批改元素的 box-sizing 属性来扭转元素的盒模型:

  • box-sizeing: content-box示意规范盒模型(默认值)
  • box-sizeing: border-box示意 IE 盒模型(怪异盒模型)

响应式设计的概念及基本原理

响应式网站设计(Responsive Web design)是一个网站可能兼容多个终端,而不是为每一个终端做一个特定的版本。

对于原理:基本原理是通过媒体查问 (@media) 查问检测不同的设施屏幕尺寸做解决。
对于兼容:页面头部必须有 mate 申明的viewport

<meta name="’viewport’" content="”width=device-width," initial-scale="1." maximum-scale="1,user-scalable=no”"/>

CSS 预处理器 / 后处理器是什么?为什么要应用它们?

预处理器, 如:lesssassstylus,用来预编译 sass 或者 less,减少了css 代码的复用性。层级,mixin,变量,循环,函数等对编写以及开发 UI 组件都极为不便。

后处理器, 如:postCss,通常是在实现的样式表中依据 css 标准解决 css,让其更加无效。目前最常做的是给css 属性增加浏览器公有前缀,实现跨浏览器兼容性的问题。

css预处理器为 css 减少一些编程个性,无需思考浏览器的兼容问题,能够在 CSS 中应用变量,简略的逻辑程序,函数等在编程语言中的一些根本的性能,能够让 css 更加的简洁,减少适应性以及可读性,可维护性等。

其它 css 预处理器语言:Sass(Scss), Less, Stylus, Turbine, Swithch css, CSS Cacheer, DT Css

应用起因:

  • 构造清晰,便于扩大
  • 能够很不便的屏蔽浏览器公有语法的差别
  • 能够轻松实现多重继承
  • 完满的兼容了 CSS 代码,能够利用到老我的项目中

intanceof 操作符的实现原理及实现

instanceof 运算符用于判断构造函数的 prototype 属性是否呈现在对象的原型链中的任何地位。

function myInstanceof(left, right) {
  // 获取对象的原型
  let proto = Object.getPrototypeOf(left)
  // 获取构造函数的 prototype 对象
  let prototype = right.prototype; 

  // 判断构造函数的 prototype 对象是否在对象的原型链上
  while (true) {if (!proto) return false;
    if (proto === prototype) return true;
    // 如果没有找到,就持续从其原型上找,Object.getPrototypeOf 办法用来获取指定对象的原型
    proto = Object.getPrototypeOf(proto);
  }
}

单行、多行文本溢出暗藏

  • 单行文本溢出
overflow: hidden;            // 溢出暗藏
text-overflow: ellipsis;      // 溢出用省略号显示
white-space: nowrap;         // 规定段落中的文本不进行换行
  • 多行文本溢出
overflow: hidden;            // 溢出暗藏
text-overflow: ellipsis;     // 溢出用省略号显示
display:-webkit-box;         // 作为弹性伸缩盒子模型显示。-webkit-box-orient:vertical; // 设置伸缩盒子的子元素排列形式:从上到下垂直排列
-webkit-line-clamp:3;        // 显示的行数

留神:因为下面的三个属性都是 CSS3 的属性,没有浏览器能够兼容,所以要在后面加一个-webkit- 来兼容一部分浏览器。

link 和 @import 的区别

两者都是内部援用 CSS 的形式,它们的区别如下:

  • link 是 XHTML 标签,除了加载 CSS 外,还能够定义 RSS 等其余事务;@import 属于 CSS 领域,只能加载 CSS。
  • link 援用 CSS 时,在页面载入时同时加载;@import 须要页面网页齐全载入当前加载。
  • link 是 XHTML 标签,无兼容问题;@import 是在 CSS2.1 提出的,低版本的浏览器不反对。
  • link 反对应用 Javascript 管制 DOM 去扭转款式;而 @import 不反对。

两栏布局的实现

个别两栏布局指的是 右边一栏宽度固定,左边一栏宽度自适应,两栏布局的具体实现:

  • 利用浮动,将右边元素宽度设置为 200px,并且设置向左浮动。将左边元素的 margin-left 设置为 200px,宽度设置为 auto(默认为 auto,撑满整个父元素)。
.outer {height: 100px;}
.left {
  float: left;
  width: 200px;
  background: tomato;
}
.right {
  margin-left: 200px;
  width: auto;
  background: gold;
}
  • 利用浮动,左侧元素设置固定大小,并左浮动,右侧元素设置 overflow: hidden; 这样左边就触发了 BFC,BFC 的区域不会与浮动元素产生重叠,所以两侧就不会产生重叠。
.left{
     width: 100px;
     height: 200px;
     background: red;
     float: left;
 }
 .right{
     height: 300px;
     background: blue;
     overflow: hidden;
 }
  • 利用 flex 布局,将右边元素设置为固定宽度 200px,将左边的元素设置为 flex:1。
.outer {
  display: flex;
  height: 100px;
}
.left {
  width: 200px;
  background: tomato;
}
.right {
  flex: 1;
  background: gold;
}
  • 利用相对定位,将父级元素设置为绝对定位。右边元素设置为 absolute 定位,并且宽度设置为 200px。将左边元素的 margin-left 的值设置为 200px。
.outer {
  position: relative;
  height: 100px;
}
.left {
  position: absolute;
  width: 200px;
  height: 100px;
  background: tomato;
}
.right {
  margin-left: 200px;
  background: gold;
}
  • 利用相对定位,将父级元素设置为绝对定位。右边元素宽度设置为 200px,左边元素设置为相对定位,右边定位为 200px,其余方向定位为 0。
.outer {
  position: relative;
  height: 100px;
}
.left {
  width: 200px;
  background: tomato;
}
.right {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 200px;
  background: gold;
}

title 与 h1 的区别、b 与 strong 的区别、i 与 em 的区别?

  • strong 标签有语义,是起到减轻语气的成果,而 b 标签是没有的,b 标签只是一个简略加粗标签。b 标签之间的字符都设为粗体,strong 标签增强字符的语气都是通过粗体来实现的,而搜索引擎更偏重 strong 标签。
  • title 属性没有明确意义只示意是个题目,H1 则示意档次明确的题目,对页面信息的抓取有很大的影响
  • i 内容展现为斜体,em 示意强调的文本

应用 clear 属性革除浮动的原理?

应用 clear 属性革除浮动,其语法如下:

clear:none|left|right|both

如果单看字面意思,clear:left 是“革除左浮动”,clear:right 是“革除右浮动”,实际上,这种解释是有问题的,因为浮动始终还在,并没有革除。

官网对 clear 属性解释:“元素盒子的边不能和后面的浮动元素相邻”,对元素设置 clear 属性是为了防止浮动元素对该元素的影响,而不是革除掉浮动。

还须要留神 clear 属性指的是元素盒子的边不能和后面的浮动元素相邻,留神这里“后面的”3 个字,也就是 clear 属性对“前面的”浮动元素是充耳不闻的。思考到 float 属性要么是 left,要么是 right,不可能同时存在,同时因为 clear 属性对“前面的”浮动元素充耳不闻,因而,当 clear:left 无效的时候,clear:right 必然有效,也就是此时 clear:left 等同于设置 clear:both;同样地,clear:right 如果无效也是等同于设置 clear:both。由此可见,clear:left 和 clear:right 这两个申明就没有任何应用的价值,至多在 CSS 世界中是如此,间接应用 clear:both 吧。

个别应用伪元素的形式革除浮动:

.clear::after{content:'';  display: block;   clear:both;}

clear 属性只有块级元素才无效的,而::after 等伪元素默认都是内联程度,这就是借助伪元素革除浮动影响时须要设置 display 属性值的起因。

程度垂直居中的实现

  • 利用相对定位,先将元素的左上角通过 top:50% 和 left:50% 定位到页面的核心,而后再通过 translate 来调整元素的中心点到页面的核心。该办法须要 思考浏览器兼容问题。
.parent {position: relative;} .child {position: absolute;    left: 50%;    top: 50%;    transform: translate(-50%,-50%);}
  • 利用相对定位,设置四个方向的值都为 0,并将 margin 设置为 auto,因为宽高固定,因而对应方向实现平分,能够实现程度和垂直方向上的居中。该办法实用于 盒子有宽高 的状况:
.parent {position: relative;}

.child {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}
  • 利用相对定位,先将元素的左上角通过 top:50% 和 left:50% 定位到页面的核心,而后再通过 margin 负值来调整元素的中心点到页面的核心。该办法实用于 盒子宽高已知 的状况
.parent {position: relative;}

.child {
    position: absolute;
    top: 50%;
    left: 50%;
    margin-top: -50px;     /* 本身 height 的一半 */
    margin-left: -50px;    /* 本身 width 的一半 */
}
  • 应用 flex 布局,通过 align-items:center 和 justify-content:center 设置容器的垂直和程度方向上为居中对齐,而后它的子元素也能够实现垂直和程度的居中。该办法要 思考兼容的问题,该办法在挪动端用的较多:
.parent {
    display: flex;
    justify-content:center;
    align-items:center;
}

z-index 属性在什么状况下会生效

通常 z-index 的应用是在有两个重叠的标签,在肯定的状况下管制其中一个在另一个的上方或者下方呈现。z-index 值越大就越是在下层。z-index 元素的 position 属性须要是 relative,absolute 或是 fixed。

z-index 属性在下列状况下会生效:

  • 父元素 position 为 relative 时,子元素的 z -index 生效。解决:父元素 position 改为 absolute 或 static;
  • 元素没有设置 position 属性为非 static 属性。解决:设置该元素的 position 属性为 relative,absolute 或是 fixed 中的一种;
  • 元素在设置 z -index 的同时还设置了 float 浮动。解决:float 去除,改为 display:inline-block;

实现一个扇形

用 CSS 实现扇形的思路和三角形基本一致,就是多了一个圆角的款式,实现一个 90°的扇形:

div{
    border: 100px solid transparent;
    width: 0;
    heigt: 0;
    border-radius: 100px;
    border-top-color: red;
}

代码输入问题

function Parent() {
    this.a = 1;
    this.b = [1, 2, this.a];
    this.c = {demo: 5};
    this.show = function () {console.log(this.a , this.b , this.c.demo);
    }
}

function Child() {
    this.a = 2;
    this.change = function () {this.b.push(this.a);
        this.a = this.b.length;
        this.c.demo = this.a++;
    }
}

Child.prototype = new Parent();
var parent = new Parent();
var child1 = new Child();
var child2 = new Child();
child1.a = 11;
child2.a = 12;
parent.show();
child1.show();
child2.show();
child1.change();
child2.change();
parent.show();
child1.show();
child2.show();

输入后果:

parent.show(); // 1  [1,2,1] 5

child1.show(); // 11 [1,2,1] 5
child2.show(); // 12 [1,2,1] 5

parent.show(); // 1 [1,2,1] 5

child1.show(); // 5 [1,2,1,11,12] 5

child2.show(); // 6 [1,2,1,11,12] 5

这道题目值得神帝,他波及到的知识点很多,例如 this 的指向、原型、原型链、类的继承、数据类型 等。

解析:

  1. parent.show(),能够间接取得所需的值,没啥好说的;
  2. child1.show(),Child的构造函数本来是指向 Child 的,题目显式将 Child 类的原型对象指向了 Parent 类的一个实例,须要留神 Child.prototype 指向的是 Parent 的实例 parent,而不是指向Parent 这个类。
  3. child2.show(),这个也没啥好说的;
  4. parent.show(),parent是一个 Parent 类的实例,Child.prorotype指向的是 Parent 类的另一个实例,两者在堆内存中互不影响,所以上述操作不影响 parent 实例,所以输入后果不变;
  5. child1.show(),child1执行了 change() 办法后,产生了怎么的变动呢?
  6. this.b.push(this.a),因为 this 的动静指向个性,this.b 会指向 Child.prototype 上的 b 数组,this.a 会指向 child1a属性, 所以 Child.prototype.b 变成了[1,2,1,11];
  7. this.a = this.b.length,这条语句中 this.athis.b的指向与上一句统一,故后果为 child1.a 变为4;
  8. this.c.demo = this.a++,因为 child1 本身属性并没有 c 这个属性,所以此处的 this.c 会指向 Child.prototype.cthis.a 值为 4,为原始类型,故赋值操作时会间接赋值,Child.prototype.c.demo 的后果为 4,而this.a 随后自增为5(4 + 1 = 5)。
  9. child2执行了 change() 办法, 而 child2child1均是 Child 类的实例,所以他们的原型链指向同一个原型对象 Child.prototype, 也就是同一个parent 实例,所以 child2.change() 中所有影响到原型对象的语句都会影响 child1 的最终输入后果。
  10. this.b.push(this.a),因为 this 的动静指向个性,this.b 会指向 Child.prototype 上的 b 数组,this.a 会指向 child2a属性, 所以 Child.prototype.b 变成了[1,2,1,11,12];
  11. this.a = this.b.length,这条语句中 this.athis.b的指向与上一句统一,故后果为 child2.a 变为5;
  12. this.c.demo = this.a++,因为 child2 本身属性并没有 c 这个属性,所以此处的 this.c 会指向 Child.prototype.c,故执行后果为Child.prototype.c.demo 的值变为 child2.a 的值 5,而child2.a 最终自增为6(5 + 1 = 6)。
退出移动版