面试集锦(二)

面试集锦(二)

1.React相关知识

1.1 react生命周期

react生命周期分为三个阶段:装载过程(Mount)、更新过程(update)、卸载过程(unmount)。

参考:https://blog.csdn.net/mafan121/article/details/77965379

1.2 react父子组件传参

父组件向子组件传参:props。

在父组件中向子组件添加属性,子组件通过this.props获取。

子组件向父组件传参:回调函数。

在父组件向子组件添加事件,子组件调用父组件事件并将参数带回。

1.3 react高阶组件HOC

HOC是一个函数,其接收一个组件作为参数,返回一个增强的组件。

高阶组件主要被用于:代码模块化、代码复用、修改props、劫持渲染(操作state)。

常用的实现方式有:

  • 属性代理(Props Proxy):高阶组件操控传递给 WrappedComponent 的 props。
  • 反向继承(Inheritance Inversion)高阶组件继承(extends)WrappedComponent。

示例:

import React, { Component } from 'react'

const withStorage = WrappedComponent => {
  return class extends Component{
    componentWillMount() {
      let data = localStorage.getItem('data')
      this.setState({ data })
    }

    render() {
      return <WrappedComponent data={this.state.data} {...this.props} /> 
    }
  }
}

export default withStorage

这里采用属性代理的方式定义了一个高阶组件,其每个传入组件加载前都将去拿取localStoragedata数据,避免了在每个组件中写componentWillMount,提高了代码复用率。

1.4 react的children嵌套

react中任何组件都有一个children属性。他表示当前组件下的子元素,有点类似于innerHTML属性

this.props.children的值有3种类型:undefined(无子节点)、object(一个子节点)、Array(多个子节点)。

常用的方法:

  • React.Children.count(object children) :返回子节点个数
  • React.Children.map(object children, function fn [, object context]):遍历children子元素,执行fn,并返回结果集。
  • React.Children.forEach(object children, function fn [, object context]):仅仅遍历子元素执行fn,无结果返回。
  • React.Children.only(object children):返回children中仅有的子级,否则跑出异常。

1.5 父子组件如何事件互调

父组件调用子组件事件:refs。

为子组件绑定ref属性,在需要用到的时候通过this.props.refs属性获取到子组件,然后子组件就可以调用自己的事件了。

子组件调用父组件事件:props。

在父组件为子组件绑定事件,在子组件中通过this.props.事件名调用。

1.6 react diff算法原理

react diff算法分为3大策略,简化了比较的复杂度。

  1. Tree diff :通过updateDepthVirtual DOM树进行层级控制,两棵树只进行同层节点比较,这样只需一次遍历即可完成整颗树的比较

  2. component diff:依旧根据层级比较,同类型的组件可通过shouldComponentUpdate判断是否更新,不同类型组件直接替换。

  3. element diff:对同层的节点,可根据key值进行删除、插入、移动。

    通过这三大策略,所有的比较可操作均在同一层级完成,大大节省了比较重绘时间。

2.redux相关知识

2.1 redux原理

redux:component --> dispatch(action) --> reducer --> subscribe --> getState --> component

参考:https://blog.csdn.net/mafan121/article/details/72673815

react-redux:component --> actionCreator(data) --> reducer --> component

connect(state => state, action)(Component);

参考:https://blog.csdn.net/mafan121/article/details/72830491

2.2 redux 优缺点

  • 一个组件的所有数据都必须从父组件传递过来,不能像flux,从store中直接获取。

  • 当一个组件相关的数据更新时,即使父组件不需要用到这个组件,父组件依旧需要重新render,这将导致渲染效率降低,需要通过shouldComponentUpdate来优化。

  • redux将数据流规范了,所有数据均在store中管理,避免了父子组件不易传参的问题。

  • redux将流程规范了,减少了手动编码量。

3.css布局

3.1 水平居中

内联元素:text-align:center;

块级元素:margin:0 auto; 或者绝对定位。

flex居中:display: flex; justify-content: center;

参考:https://blog.csdn.net/mafan121/article/details/53925555

3.2 垂直居中

单行元素:line-height:行高;

多行元素:绝对定位

flex居中:display: flex; align-items: center;

参考:https://blog.csdn.net/mafan121/article/details/53925555

3.3 左右布局

  • flex居中:flex:1;

  • calc计算:calc(100%-200px);

  • 浮动布局:float:left;

  • 定位布局:position:absolute;

参考:https://blog.csdn.net/mafan121/article/details/100057888

3.4 属性冲突

animation与display不兼容等。

参考:https://blog.csdn.net/mafan121/article/details/87795065

当然还有很多兼容性的属性,这里并没有列举,例如透明度:opacity等

3.5 盒子模型

盒子模式=外边距+边框+内边距+组件大小

box-sizing可以改变盒子模型。

参考:https://blog.csdn.net/mafan121/article/details/51548222

3.6 样式优先级

!important > 行内样式 > ID选择器 > 类选择器 > 元素 > 通配符 > 继承 > 浏览器默认属性

参考:https://blog.csdn.net/mafan121/article/details/48158001

3.7 CSS中link 和@import的区别

linkhtml标签,只能存放于html源码中,既可以加载css文件,也能设置rss、rel等连接属性。在页面加载的时候同时被加载。可以通过dom操作插入。

@import是CSS2.1中的语法,只有导入样式的作用,在页面加载完成后才开始加载。无法通过dom操作导入。

4.js相关知识

4.1 js基础类型

String、number、boolean、null、undefined、symbol

4.2 js原型和原型链

参考:https://blog.csdn.net/mafan121/article/details/48970993

4.3 事件委托

事件委托又称事件代理,是利用事件冒泡原理,将子元素的事件绑定到父元素上,让父元素担当事件的监听者。然后通过特殊的子元素标识来区分目前触发的是哪个子元素事件。例如常见的点击浏览器任意位置关闭弹窗,就是将点击事件委托给了document对象。

优点是:

  • 可以节省大量的内存,减少子元素相同事件的注册。
  • 当新增子元素时无需再次对其进行事件绑定。

示例:

<!DOCTYPE html>
<html> 
<head>
  <meta charset="utf-8">
  <script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
</head>
<body>
  <ul id="myLinks">
    <li id="goSomewhere">Go somewhere</li>
    <li id="doSomething">Do something</li>
    <li id="sayHi">Say hi</li>
  </ul>
 
  <script>
     var ulEle = document.getElementById("myLinks");
      ulEle.addEventListener("click", function (event) {
      var target = event.target;
      switch (target.id) {
        case "doSomething":
          document.title = "事件委托";
          break;
        case "goSomewhere":
          location.href = "http://www.baidu.com";
          break;
        case "sayHi": 
          alert("hi");
          break;
      }
  </script>
</body>
</html>

4.4 防抖和节流

防抖:事件的执行必须间隔一定的时间,如果在指定时间内再次出发,则重新计时。

节流:在一段时间内,事件只能触发一次,时间段内的触发不生效。

参考:https://blog.csdn.net/mafan121/article/details/82115933

4.5 闭包的使用

闭包是函数内部的函数,作用是防止变量污染。

参考:https://blog.csdn.net/mafan121/article/details/48243895

4.6 cookie、localStorage、sessionStorage的区别和优缺点

三者都是将数据缓存在浏览器端,但cookie数据存储量大约在4k左右,而storage存储量为5M左右。

cookie将会随http传递给后端,而storage仅仅是保存在本地,除非用户手动设置,否则不会传递给服务器。

storage:https://blog.csdn.net/mafan121/article/details/60133107

cookie:https://blog.csdn.net/mafan121/article/details/100062220

4.7 CommonJS、AMD、CMD的区别

CommonJS:是服务器端js模块化的规范,一个单独的文件就是一个模块,加载模块使用require方法,该方法读取一个文件并执行,最后返回文件内部的exports对象。NodeJs采用该规范。

AMD:异步模块定义,客户端js模块化的规范,只有一个接口:define(id?,dependencies?,factory);需要在声明模块的时候制定所有的依赖(dep),并且还要当做形参传到factory中。通过define定义,通过require方法加载。RequireJS采用这种规范。

CMD:通用模块定义,客户端js模块化的规范,通过define定义,通过require方法加载。SeaJs采用这种规范。

AMD和CMD的区别

  • 对于依赖的模块,AMD提前执行,而CMD则采用懒加载的方式延迟执行。
  • 对于requireAMD分全局require和局部requireCMD中没有全局require,而是按需加载。
  • CMD推崇依赖就近,AMD推崇依赖前置。

4.8 apply和 call的区别

apply和 call都是以一个对象代替当前对象,调用当前对象的方法,实际上是变更了当前方法的this指向。

区别在于:出第一个参数外,call接收任何类型数据作为参数,且参数可以是多个,而apply只能接收数组作为参数,且只能有一个数组。

参考: https://blog.csdn.net/mafan121/article/details/52922149

5.跨域问题

浏览器同源策略导致了跨域问题,同时也减少了浏览器遭受的XSS、CSFR等攻击。

常见的解决方案:

  • 通过jsonp跨域
  • postMessage跨域
  • nginx跨域
  • 设置document.domain相同
  • 服务端设置Access-Control-Allow-Origin

参考:https://segmentfault.com/a/1190000011145364

6.webpack打包优化

1.代码抽离,提取公共代码,分离css代码。

2.Externals第三方库外部引入。

3.减少loader筛选范围,精确resolve匹配路径,降低打包速度。

4.缓存loader的执行结果(cacheDirectory)

7 git或svn 常用命令

git 常用的命令:

git fetch <远程主机名> <分支名>    //拉取远程分支到本地
git pull  <远程主机名> <远程分支名> //拉取远程分支代码,并将远程分支代码和本地分支代码合并。
git checkout <分支名>						//切换分支
git merge <分支名>								//合并分支到当前分支

git add .												//获取所有修改的文件
git commit -m "描述"						 //提交修改
git push origin <分支名>					//推送代码到远端服务器

git commit --no-verify -m "提交描述"(跳过eslint或tslint校验)

svn常用命令:

svn checkout  								//切换到服务器指定目录
svn add 											//获取需要提交的文件
svn commit -m "描述" 									//提交文件
svn update -r m  							//更新版本
svn lock -m “描述” [--force]  //加/解锁
svn delete  -m “描述” 				//删除文件
svn log   										//显示该文件的修改日志
svn svn merge -r m:n  				//合并2个版本中的指定文件
svn diff  										//比较当前文件和基础版本文件的差异			

你可能感兴趣的:(web前端面试总结)