面试总结1024

                                                                 面试题目录


  1. ES6、ES7新特性;H5、CSS3新特性?es5与es6对比,语法有何不同?
  2. react/vue生命周期;优缺点;react16新特性?react中的keys的作用是什么?redux?高阶组件
  3. 手机适配?
  4. 前端工程化工具、webpack作用、配置webpack、包括哪些配置项;webpack打包文件太大怎么办;webpack与gulp区别?
  5. 继承、闭包、原型链的优缺点、作用、方式、注意;面向对象的理解?
  6. 数组、对象常用方法?
  7. 如何阻止事件冒泡或默认行为?
  8. 跨域解决方法?
  9. http协议?
  10. cookie/setStorage/localStorage 区别、优缺点;浏览器的缓存作用?
  11. setState与props区别、setState后发生了什么、第二个参数作用?
  12. 如何选取一个类?
  13. 声明提升?
  14. 移动端点击事件的延迟、解决办法、为何会出现这个问题?
  15. 事件委托/代理、变量、作用域、作用域链、事件监听、事件处理函数、方法、优缺点?
  16. react-router原理?两种实现方式?
  17. url加载页面发生了什么?
  18. ajax原理、过程、优缺点、定义?ajax、axios、fetch优缺点?
  19. 垂直居中问题、弹性和?
  20. git/svn?
  21. 前端性能优化(资源接口优化、构建优化、渲染优化、网络优化)?
  22. ref是什么?受控和非受控组件区别?有/无状态组件?
  23. 声明组件的方式?react组件的划分?调用super(props)的目的是什么?
  24. 算法?
  25. 内存泄漏的几种情况?
  26. 前端兼容性问题?
  27. 项目中遇到的问题?
  28. 冒泡和捕获,有什么区别?有哪些事件是不会冒泡的?
  29. 页面刷新?
  30. link 与@import区别?
  31. 内核?
  32. 开发环境、测试环境、预发环境、正式环境的理解?
  33. class继承?
  34. prototype与_proto_区别?
  35. 线程与进程的区别及联系?
  36. 节流、防抖、回流、重绘?
  37. 轮播、懒加载、上拉加载工作原理?
  38. 网络安全、单元测试,mock、node?
  39. 正向代理与反向代理的区别?

1、ES6、ES7新特性;H5、CSS3新特性?es5与es6对比,语法有何不同?

  • ES6:let、const块级作用域、箭头函数、模板字符串、类class、模块化(import、export)、数组对象的解构复制(延展操作符…{})、promise、async(函数返回的是promise对象,await命令的参数先执行,如果是promise对象,就返回对象的结果,如果不是返回对应的值)、Object.values()/.keys()/.assign();
  • ES7:[].includes()方法与indexOf的区别:前者返回boolean后者返回数值、前者可判断null、指数运算符**;

ES6新特性:

  • let/const/class/import (var/function)(变量声明方式)
  • async/promise/module/
  • 对象Object.assign() /.keys() /.values();
  • 数组Array.from() /find() / Symbol/Set/Map/对象的解构赋值
  • let: 块级作用域,不允许重复声明,没有变量提升;
  • const: 赋值后无法改变;
  • 数组的展开赋值;
  • 箭头函数: 好处:解决了this指向问题 转为真正数组的方法:
  • Array.from(object)  object: 类似数组的对象及可遍历的对象
  • 将一组值转为数组: Array.of() 不建议说
  • Symbol 作用:解决命名冲突; ES^提供了新的数据结构:  (ES6 新增的原始数据类型)
  • class 定义一个类;类的数组类型就是function,类的所有方法都是定义在类的prototype属性上;不存在变量提升; 静态属性 static: 该方法不会被实例继承;指的是Class本身的属性,而不是定义在实例对象上的属性 class继承: extends

       Set的实例属性及方法:

  • 属性: Set.size : 实例的元素总数;            constructor: 构造函数;
  • 方法: Set.add(x)/delete(x)/has(x)/clear()  增/删/有/清;
  • 遍历: Set.keys()/values()/entries()/forEach()  键名/键值/键值对/遍历;
  • 数组的结构赋值也可以用于Set结构;

H5新特性:

  • 离线存储:基于新建的Appache文件的缓存机制;通过它的解析清单离线存储资源,在网络离线时,浏览器会利用这些离线存储的数据展示页面:
  • 用于绘画的canvas;
  • 视频音频video/audio;
  • 新的表单控件calendar/date/time/email/url/search;
  • 语义化标签: header、nav、section、footer ;

ES6数组去重的两种方法:

  • 循环遍历两层;
  • instanceOf filter()
  • Array.from()
  • new Set()

null 与undefined区别:             

  • Null有值,值为空,undefined值未定义;             

Typeof(null) => object 特殊的对象类型 ;

判断一个变量是空对象:

  • Object.keys(object) => []
  • For in循环
  • hasOwnProperty(“属性”)

CSS选择符:

  • id, 类,标签,相邻,子,后代,通配符,属性,伪类;

CSS3新特性:

  • 1、阴影:

       text-shadow: 5px 5px 5px rgba(0, 0, 0, .6);

       box-shadow: 5px 5px 5px rgba(0, 0, 0, .6)

  • 2、背景:

        background-size: 100px 100% /auto/cover/contain; auto: 背景真实大小; cover: 等比缩放完全覆盖容器,可超出容器; contain: 等比缩放与容器高度或宽度相等,在容器中;

        background-origin: padding-box/border-box/content-box背景原点;

  • 3、圆角与边框:

       border-radius: 圆角  

       border-image:边框图片

       - source/slice/width/outset/repeat/

  • 4、变形 transform

       transform: translate/translatex/translate

       rotate:旋转

       scale: 缩放

       skew 斜切

       transform-origin: center center; 原点

       translate: 平移

  • 5、渐变 background: linear-gradient
  • 6、透明 opacity: 0.5; 透明
  • 7、动画 transition 过渡动画 keyframes 帧动画
  • 8、伪元素:before/after/清除浮动;

清除浮动的方法:

  • box:after{ clear: both; overflow: hidden; }
  • box:before, box:after { content: “”; display: table; }
  • box { *zoom: 1; } 旧版本IE缩放大小,触发haslayout (类似BFC)
  • box:after { content: “”; display: table; clear: both; }

        父: float  / heihgt / display: table /  overflow:hidden/auto  

        父 :   after{display:block;clear:both;content:"";visibility:hidden;height:0}

        结尾加空标签: clear: both

Promise异步:

  • 三种状态: pending(进行中)、fulfilled(已成功)、rejected(已失败)
  • .then() 方法直接定义在原型对象上,返回一个新的Promise实例
  • .catch() 发生错误时的回调
  • .finally() 不管结果如何,都会执行的回调
  • async 函数,异步操作,Generator 的语法糖
  • 使用await 后,等到异步返回后,再继续执行后面的语句

es5与es6对比,语法有何不同:

  • require与import;
  • module.exports 与export default; 
  • React.createClass({ render: function }) 与class extends React.Component;
  • props: propTypes 与直接使用;
  • getInitailState 与this.state;

深拷贝与浅拷贝:

浅拷贝定义:

  • 创建一个新对象,这个对象跟原有对象有相同的属性和方法;基本类型,拷贝的就是基本类型的值,引用类型,拷贝的是内存地址,两个对象变化互相影响;

浅拷贝方法:

  • Object.assign({}, x);
  • {...obj}对象展开;
  • arr.slice(), arr.concat();

深拷贝定义:

  • 拷贝所有属性和方法,两个对象变化互不影响;速度慢;

深拷贝方法:

  • JSON.parse(JSON.stringify(obj));
  • lodash.cloneDeep(obj);

 

2、react/vue生命周期;优缺点;react16新特性?react中的keys的作用是什么?Redux?高阶组件?

react:

生命周期:

 

 

  • getDefaultProps:初始化属性;
  • getInitialState:初始化状态;
  • componentWillMount:组件挂载之前,全局只调用一次,可以ajax, setState,会触发重渲染,render后可以看到更新后的state, (React v16.3后该周期被废弃,可以在constructor中设置state);
  • render: 首次渲染dom
  • componentDidMount:组件挂载完成后,全局只调用一次,可以发送ajax,setState,会触发重渲染,可以获取到真实dom,
  • componentWillReceiveProps(nextProps ): props即将变化之前,props变化及父组件重新渲染都会触发该周期,可以setState, (React v16.3后废弃该生命周期,可以用新的周期 static getDerivedStateFromProps 代替)
  • shouldComponentUpdate(nextProps, nextState) : 是否重新渲染,组件挂载后,每次调用setState,都会调用该周期,判断是否需要重新渲染组件,默认返回true,false返回则不渲染;
  • componentWillUpdate(nextProps, nextState): shouldComponentUpdate返回true或者调用forceUpdate之后,该周期被调用,不能setState, 会触发重复循环;(React v16.3后废弃该生命周期,可以用新的周期 getSnapshotBeforeUpdate )
  • render: 重渲染
  • componentDidUpdate: 完成组件渲染,除了首次render后调用componentDidMount,其它render结束之后都是调用componentDidUpdate, setState有可能会触发重复渲染,需要自行判断,否则会死循环;
  • componentWillUnmount: 组件即将被卸载,在componentDidMount注册的事件需要在这里删除;

React v16.3删除一下三个生命周期:

 

  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate

新增两个生命周期:

   static getDerivedStateFromProps(nextProps, prevState): 

  • 触发时间: 在组件构建之后(虚拟dom之后,实际dom挂载之前), updating的时候;
  • 每次接收新的props之后都会返回一个对象作为新的state,返回null则说明不需要更新state;
  • 配合componentDidUpdate,可以覆盖componentWillReceiveProps的所有用法;

   getSnapshotBeforeUpdate(prevProps, prevState):

  • 触发时间:在render之后,dom元素还没有被更新之前执行;
  • 返回一个值snapshot,作为componentDidUpdate的第三个参数;
  • 配合componentDidUpdate,覆盖componentWillUpdate的所有用法;

componentWillMount 和 componentDidMount中发送ajax有什么区别?

  • 跟服务端渲染有关系,如果在componentWillMount里获取数据,fetch data会执行两次,一次在服务端一次在客户端,使用componentDidMount则没有这个问题;
  • 很重要的 一点是React16.3后将会被废弃掉componentWillMount, componentWillReceiveProps, componentWillUpdate周期,直到React17前还可以使用,不过会有一个警告;

优点:

  • 速度快:运用了虚拟DOM,不需要直接操作DOM
  • 跨浏览器兼容: 虚拟DOM的原因
  • 组件化: 代码模块化、复用率高、可维护性高
  • 单向数据流:父传子、子通过props获取
  • 兼容性好: 纯粹的、同构的JavaScript

缺点:

  • react是实现了V层,不是一个完整的框架,如果大型项目,基本都需要加上ReactRouter和redux;

虚拟DOM概念:

  • js与真实DOM加缓存,利用diff算法避免没必要的DOM操作,用js对象表示DOM结构,用这个虚拟的对象真正创建一个DOM树,插入到文档中,若有状态更新,重新复制一个新的DOM树,将新旧对比,差异部分应用到真正的DOM树种,视图更新

diff算法概念:

  • 把树形结构按照层级分解,只比较同级元素。
  • 给列表结构的每个单元添加唯一的 key 属性,方便比较。
  • React 只会匹配相同 class 的 component(这里面的 class 指的是组件的名字)
  • 合并操作,调用 component 的 setState 方法的时候, React 将其标记为 dirty.到每一个事件循环结束, React 检查所有标记 dirty 的 component 重新绘制.
  • 选择性子树渲染。开发人员可以重写 shouldComponentUpdate 提高 diff 的性能。

react中的keys的作用是什么?

  • keys是用户追踪哪些列表中的元素被修改,被添加,或者被移除的辅助标识;
  • 开发中,需要保证某个元素的key在统计元素中唯一,在diff算法中react会借助key值来判断该元素是新建还是被移动来的元素,从而减少不必要的diff算法对比去让元素重渲染;
  • react还需要借助key值来判断元素与本地状态的关联关系;
  • 对元素或组件判断是否存在key值,组件不存在key值,直接采用diff算法比较;组件存在key值,key值是否一致,不一致,组件销毁,新建;组件一致,属性是否发生变化,没变化,不改变,变化,就更新;

面试总结1024_第1张图片

React16特性:

  • Fragments:render可以return array/string
  • Error boundaries:是一种特殊的React组件,之前是一旦某个组件有错误,整个组件都会被从根节点unmount下来,现在Error Boundary 捕获到错误,并对错误做处理,使用Error Boundary提供的内容替代错误组件,新增了componentDidCatch生命周期函数,可以捕获自身及子树上的错误并对错误做处理,报错上报错误日志、展示错误日志、而不是卸载整个组件树。 注:它并不能捕获runtime所有的组件,比如组件回调时间里的错误
  • Portals:用ReactDOM.createPortal(child,container) Child:任何可渲染的React子元素,元素、字符串或片段; Container:DOM元素,render中return到DOM中;
  • custom DOM attributes:
  • improved server-side rendering:提升服务端渲染性能,是一种流模式Streaming,可以更快的渲染字节到客户端,SSR被完全重写,新的实现特别快;

Redux:

  • Store.dispatch()将action传到store,分发action;
  • Action: 把数据从应用传到store的,本质上是一个js普通对象;
  • Reducer: 纯函数,接收state,action,返回新的state; Store: createStore()第二个参数可选,用于设置state初始状态; CombineReducers:把一个由多个不同的reducer函数作为value的object,合并成一个最终的reducer函数,然后调用createStore,合并后的reducer可以调用各个子reducer,把结果合并成一个state对象,state对象的结构由传入的多个reducer的key决定;
  • Connetct():mapStateToProps 函数制定如何把当前的store state映射到组件的props中; mapDispatchToProps函数分发action,接收dispatch()返回组件的props中的回调方法; 中间件: Redux-thunk:让store.dispatch函数不仅能传递对象,还可以传递函数 applpyMiddleWare高阶函数; redux-saga: redux-pack:

3、手机适配

手机适配技术方案:

  • 媒体查询: CSS3的meida queries:

       优点:调整屏幕宽度的时候不用刷新页面就可以响应式展示;图片便于修改,只需要修改css文件

       缺点:代码量比较大,维护不方便;为了兼顾大屏幕和高清设备,会造成其他设备资源浪费,特别是加载图片资源;

  • flex布局
  • rem+viewport 缩放
  • rem布局:rem相对于根字号的大小;

      设备像素比:设备像素比=物料像素/设备独立像素(px像素)

meta标签的属性:

  • width: viewport宽度,一般设置为=设备宽度,即“device-width”
  • initial-scale:页面初始缩放值,为一个数字,可带小数,一般为1
  • minimum/maximum-scale:允许用户的最小/最大缩放值,为一个数字,可带小数,一般为1
  • height:viewport高度,很少使用
  • user-scalable:是否允许用户进行缩放,值为“no”或“yes”,不允许/允许amd/cmd

4、前端工程化工具、webpack作用、配置webpack、包括哪些配置项;webpack打包文件太大怎么办;webpack与gulp区别

作用: 模块化开发、打包

配置:入口文件、输入文件、各种loader处理各种文件、plugin合并输入为css/js,webpack-dev-sever组件热替换,启动服务等;

webpack打包文件太大:

  • 去除不必要的插件、代码压缩、代码分隔
  • 提取第三方库; 在入口、出口配置不同的入口出口文件、区分开文件、库
  • 设置缓存

区别:

  • webpack:模块管理与打包、按需加载、启动本地server、sass/less预编译
  • gulp:模块开发、文件压缩打包

优化:

  • 1、插件及优化: Html-webpack-plugin:生成html文件; clean-webpack-plugin:清空打包文件; Webpack打包文件太大:
  • 2、修改mode,分为development和product,即生成环境和开发环境还有base三个文件;
  • 3、babel-plugin-import:Base文件中把antd等库按需加载;
  • 4、uglifyjs-webpack-plugin、optimize-css-assets-webpack-plugin:Base文件在optimization(与module/plugins同级)的minimizer[]中利用uglifyjs-webpack-plugin 压缩js,optimize-css-assets-webpack-plugin压缩css;
  • 5、babel-plugin-syntax-dynamic-import:Base文件中React-router利用react-loadable与其动态加载
  • 6、splitChunks:Base文件中将antd之类的第三方库分离出来;
  • 7、mini-css-extract-plugin:Prod文件中提取css从js中分离出来;
  • 1、entry:入口文件;
  • 2、output:出口文件;
  • 3、module(loader):模块;
  • 4、resolve:路径目录;
  • 5、resolveLoader:loader的路径目录解析;
  • 6、mode:模式;
  • 7、optimization:优化;
  • 8、plugins:插件;
  • 9、devtool:类型;
  • 10、devServer:webpack-dev-server;
  • 11、target:构建目标;
  • 12、watch:是否开启观察模式;
  • 13、watchOPtions:
  • 14、externals:
  • 15、node:
  • 16、performance:性能;
context: __dirname,
    // 入口
    // 类型: string | [string] | object { : string | [string] } | (function: () => string | [string] | object { : string | [string] })
    entry: { // 对象语法可以 跟
        app: './src/app.js',
        vendors: './src/vendors.js' 
    }, 
    // 出口
    output:{
        chunkFilename:'bundle.[id].[name].[hash].[chunkhash].js',
        filename: 'bundle.[id].[name].[hash].[chunkhash].js', 
        path: path.join(__dirname, '../dist'), // 对应一个绝对路径,此路径是你希望一次性打包的目录。
        publicPath :'', // 静态文件的
        crossOriginLoading: false | "anonymous" | "use-credentials", 
        devtoolLineToLine: false | {test, include, exclude} | true, 
        library: 'ajax', // 导出的变量名 或者 模块名 
        libraryTarget: "var" | "this" | "commonjs" | "commonjs2" | "amd" | "umd",
        libraryExport: 'default' ,
        auxiliaryComment:'我是注释!', // 在和 output.library 和 output.libraryTarget 一起使用时,此选项允许用户向导出容器(export wrapper)中插入注释。要为 libraryTarget 每种类型都插入相同的注释,将 auxiliaryComment 设置为一个字符串:
    
    },
    // 模块 就是俗称的loader
    module:{
        noParse: (content) => /jquery|lodash/.test(content),
        rules:[
            {
                test: /\.js$/,
                include: [ path.join(__dirname, '../src') ],
                exclude: /node_modules/,
                // loader:'css-loader', Rule.loader 是 Rule.use: [ { loader } ] 的简写
                // Rule.options 和 Rule.query 是 Rule.use: [ { options } ] 的简写
                // resource: {
                    // test: /\.js$/,
                    // include: [ path.join(__dirname, '../src/renderer') ],
                    // exclude: /node_modules/,
                // }
                // import Foo from './foo.css?inline'
                // resourceQuery: /inline/,
                parser:{ // 语法分析器
                    amd: false, // 禁用 AMD
                    commonjs: false, // 禁用 CommonJS
                    system: false, // 禁用 SystemJS
                    harmony: false, // 禁用 ES2015 Harmony import/export
                    requireInclude: false, // 禁用 require.include
                    requireEnsure: false, // 禁用 require.ensure
                    requireContext: false, // 禁用 require.context
                    browserify: false, // 禁用特殊处理的 browserify bundle
                    requireJs: false, // 禁用 requirejs.*
                    node: false, // 禁用 __dirname, __filename, module, require.extensions, require.main 等。
                    node: {} // 在模块级别(module level)上重新配置 node 层(layer)
                },
                // Rule.loader 是 Rule.use: [ { loader } ] 的简写
                use: [
                    {             
                      loader: 'babel-loader',
                      options: { 
                        
                      },
                      
                    }
                ],
            
            }
        ]
    },
    // 路径目录
    resolve:{
        // 创建 import 或 require 的别名
        alias:{
            Utilities: path.join(__dirname, 'src/utilities/'),
            Templates: path.join(__dirname, 'src/templates/') 
        },
        aliasFields: ['browser'],  // 'module', 'main' 这个 browser 必须在被引用的模块的package.json 配置才能生产,并且只对这个模块生效。
        extensions: ['.wasm', '.mjs', '.js', '.json'],

        descriptionFiles:['package.json'], // 用于描述的 JSON 文件
        mainFields: ['browser', 'module', 'main'], // 当 target 属性设置为 webworker, web 或者没有指定,默认值为:['browser', 'module', 'main'] 对于其他任意的 target(包括 node),默认值为:  ['module', 'main'] 
        mainFiles: ['index'], // 解析目录时要使用的文件名。
        modules: ['node_modules'], // 告诉 webpack 解析模块时应该搜索的目录。
        enforceExtension: false,  // 如果配置为  true  所有导入语句都必须要带文件后缀, 例如开启前  import './foo'  能正常工作,开启后就必须写成  import './foo.js' 
        enforceModuleExtension: false, // nforceModuleExtension  和  enforceExtension  作用类似,但  enforceModuleExtension  只对  node_modules  下的模块生效。  enforceModuleExtension  通常搭配  enforceExtension  使用,在  enforceExtension:true  时,因为安装的第三方模块中大多数导入语句没带文件后缀, 所以这时通过配置  enforceModuleExtension:false  来兼容第三方模块。

        unsafeCache: true, // unsafeCache: /src\/utilities/ regex | array | boolean 启用,会主动缓存模块,但并不安全。传递 true 将缓存一切。默认:unsafeCache: true
        plugins:[
            new DirectoryNamedWebpackPlugin() 
        ]
    },
     // loader的路径目录解析
    resolveLoader:{ // 这组选项与上面的 resolve 对象的属性集合相同,但仅用于解析 webpack 的 loader 包。默认:
        modules: ['node_modules'],
        extensions: ['.js', '.json'],
        mainFields: ['loader', 'main'],

        moduleExtensions : ['-loader'], // 解析 loader 时,用到扩展名(extensions)/后缀(suffixes)。从 webpack 2 开始,我们 强烈建议 使用全名,例如 example-loader,以尽可能清晰。然而,如果你确实想省略 -loader,也就是说只使用 example,则可以使用此选项来实现:
    },
    // 模式
    mode:'production', // 可能的值有:none, development 或 production(默认)。提供 mode 配置选项,告知 webpack 使用相应环境的内置优化。
    // 优化
    optimization:{
        minimize: false, // 压缩
        minimizer:[ // 允许你通过提供一个或多个定制过的 TerserPlugin 实例,覆盖默认压缩工具(minimizer)。
            new TerserPlugin({
                cache: true,
                parallel: true,
                sourceMap: true, // Must be set to true if using source-maps in production
                terserOptions: {
                  // https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
                }
              }),
            //   Or, as function:
            //   (compiler) => {
            //     const TerserPlugin = require('terser-webpack-plugin');
            //     new TerserPlugin({ /* your config */ }).apply(compiler);
            //   }
        ],
        splitChunks:{

            // 模块组 缓存组概念
            chunks: 'async', // 默认只作用于异步模块,‘all’时对所有模块生效, ‘initial’对同步模块有效
            minSize: 30000,  // 新产出的vendor-chunk的大小要大于30kb
            minChunks: 2,    //共同引用超过大于等于2次就可以分割成公共模块
            maxAsyncRequsets: 5, // 并行请求vendor-chunk的数量不能超出5个
            maxInitialRequests: 3, // 对于entry-chunk,并行加载的vendor-chunk不能超出3个
            name:true, //神奇的true值将会自动根据切割之前的代码块和缓存组键值(key)自动分配命名,否则就需要传入一个String或者function.
                        // 命名与入口名称相同时,入口将会被移除.
            automaticNameDelimiter:'~',

            cacheGroups:{ // 缓存组默认继承splitChunks的配置项,但是test,priority和reuseExistingChunk只能在缓存组中被配置.
                commons: {
                    name: "commons",
                    chunks: "all", 
                    minChunks: 2,
                    
                    priority: 0,
                    minSize:0,
                },
                vendor: { 
                    name: 'vendor',
                    test: /[\\/]node_modules[\\/]/,
                    chunks: 'all', 
                    priority: 10 
                },
                default:{ // false 来禁用 默认缓存组,
            

                } , 

            }, //end cacheGroups

        }, // end splitChunks

        // runtimeChunk: true,// 或 "multiple" 以下的别名
        // runtimeChunk: {
        //     name: entrypoint => `runtime~${entrypoint.name}`
        // },
        // runtimeChunk: 'single', // 以下的别名 
        runtimeChunk: { 
            name: 'runtime'
        },
        noEmitOnErrors : true, // 在编译出错时,使用 optimization.noEmitOnErrors 来跳过生成阶段(emitting phase)。   
        nodeEnv: "production", // 告知 webpack 将 process.env.NODE_ENV 设置为一个给定字符串。如果 optimization.nodeEnv 不是 false,则会使用 DefinePlugin,optimization.nodeEnv 默认值取决于 mode,如果为 falsy 值,则会回退到 "production"。
        //parent chunk中解决了的chunk会被删除
        removeAvailableModules:true,
        //删除空的chunks
        removeEmptyChunks:true,
        //合并重复的chunk
        mergeDuplicateChunks:true,





    }, //end optimization
    // 插件
    plugins: [
        // mode : 'development'时的插件添加模式后可省略 
        new webpack.NamedModulesPlugin(), // 在热加载时直接返回更新文件名,而不是文件的id。
        new webpack.NamedChunksPlugin(), 
        new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }), 

        // mode : 'production'时的插件添加模式后可省略 
        new TerserPlugin({ test: /\.js(\?.*)?$/i,}), // js压缩优化 用terser-webpack-plugin替换掉uglifyjs-webpack-plugin解决uglifyjs不支持es6语法问题
        // new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }),
        new webpack.optimize.ModuleConcatenationPlugin(), // 将所有模块的作用域连接到一个闭包中,从而使代码在浏览器中具有更快的执行时间。
        new webpack.NoEmitOnErrorsPlugin(), //  在编译出错时,使用 optimization.noEmitOnErrors 来跳过生成阶段(emitting phase)。优化中有


        new CopyWebpackPlugin(),         // 将单个文件或整个目录复制到构建目录
        new webpack.BannerPlugin(options), // 在每个生成的块的顶部添加横幅。
        new HtmlWebpackPlugin(),         // 简单创建 HTML 文件,用于服务器访问
        new webpack.HotModuleReplacementPlugin(options),// 启用模块热替换(Enable Hot Module Replacement - HMR)
        new ExtractTextWebpackPlugin(options),  // 从 bundle 中提取文本(CSS)到单独的文件
        new OptimizeCSSPlugin(options), // 压缩提取的CSS。我们使用这个插件是为了可以消除来自不同组件的重复CSS。
        // new webpack.optimize.CommonsChunkPlugin(options), // 从webpack 4中删除了  提取 chunks 之间共享的通用模块
        // new UglifyjsWebpackPlugin(),     // 优化js的插件可以使用在optimization.minimizer中 可以控制项目中 UglifyJS 的版本 


        new webpack.optimize.AggressiveSplittingPlugin(options), // 将原来的 chunk 分成更小的 chunk
        new webpack.optimize.LimitChunkCountPlugin(options),     // 设置 chunk 的最小/最大限制,以微调和控制 chunk  当你在编写代码时,可能已经添加了许多代码分离点(code split point)来实现按需加载(load stuff on demand)。在编译完之后,你可能会注意到有一些很小的 chunk - 这产生了大量 HTTP 请求开销。LimitChunkCountPlugin 插件可以通过合并的方式,后处理你的 chunk,以减少请求数。
        new webpack.optimize.MinChunkSizePlugin(options),        // 确保 chunk 大小超过指定限制
        
        new webpack.AutomaticPrefetchPlugin(), // AutomaticPrefetchPlugin在观察更改的同时,提前发现以前编译的所有模块,试图改进增量构建时间。与预先发现单个模块的PrefetchPlugin相比。
        new webpack.ContextReplacementPlugin(),  // 重写 require 表达式的推断上下文
        new webpack.DllPlugin(options),                 // 为了极大减少构建时间,进行分离打包
        new webpack.EnvironmentPlugin(['NODE_ENV', 'DEBUG']),   // DefinePlugin 中 process.env 键的简写方式。
        new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),      // 从 bundle 中排除某些模块
        new webpack.LoaderOptionsPlugin(options),       // 用于从 webpack 1 迁移到 webpack 2
        new webpack.NormalModuleReplacementPlugin(resourceRegExp, newResource),// 替换与正则表达式匹配的资源
        new webpack.ProvidePlugin(options),             // 不必通过 import/require 使用模块
        new webpack.SourceMapDevToolPlugin(options),    // 对 source map 进行更细粒度的控制
        new webpack.EvalSourceMapDevToolPlugin(options),// 对 eval source map 进行更细粒度的控制
        
        new CompressionWebpackPlugin(),  // 可以压缩成gzip 预先准备的资源压缩版本,使用 Content-Encoding 提供访问服务
        new ZopfliWebpackPlugin(options),       // 通过 node-zopfli 将资源预先压缩的版本 压缩
        new BabelMinifyWebpackPlugin(minifyOpts, pluginOpts),  // 使用 babel-minify进行压缩
        new I18nWebpackPlugin(languageConfig, optionsObj),         // 为 bundle 增加国际化支持
        new NpmInstallWebpackPlugin(options),   // 在开发时自动安装缺少的依赖
        

    ],
    // devtool 你可以直接使用 SourceMapDevToolPlugin/EvalSourceMapDevToolPlugin 来替代使用 devtool 选项,切勿同时使用 devtool 选项和 SourceMapDevToolPlugin/EvalSourceMapDevToolPlugin 插件。
    // 类型: string false
    devtool:'cheap-eval-source-map',
    // 开发中  影响 webpack-dev-server(简写为:dev-server) 行为的选项。
    devServer: {
        contentBase: path.join(__dirname, 'dist'), // 告诉服务器从哪个目录中提供内容。只有在你想要提供静态文件时才需要。 推荐使用一个绝对路径。
        compress: true, // 一切服务都启用 gzip 压缩:
        port: 9000,  // 端口号
        after: function(app, server) { // 在服务内部的所有其他中间件之后, 提供执行自定义中间件的功能。
        },
        before: function(app, server) { // 在服务内部的所有其他中间件之前, 提供执行自定义中间件的功能。 这可以用来配置自定义处理程序,
            app.get('/some/path', function(req, res) {
                res.json({ custom: 'response' });
            });
        },
        allowedHosts :[ 'host.com', 'host2.com' ], // 此选项允许你添加白名单服务,允许一些开发服务器访问。
        color: true, // 启用/禁用控制台的彩色输出。
        lazy: true,  // lazy mode(惰性模式) 
        filename: 'bundle.js', // 在 lazy mode(惰性模式) 中,只有在请求 /bundle.js 时候,才会编译 bundle。
        headers: { // 在所有响应中添加首部内容:
            'X-Custom-Foo': 'bar'
        },
        historyApiFallback: true, // 使用 HTML5 History API 时,任意的 404 响应都可能需要被替代为 index.html。devServer.historyApiFallback 默认禁用。通过传入以下启用:
        host: '0.0.0.0', // 指定使用一个 host。默认是 localhost。如果你希望服务器外部可访问,指定如下:
        hot: true, // 启用 webpack 的 模块热替换 功能:注意,必须有 webpack.HotModuleReplacementPlugin 才能完全启用 HMR。如果 webpack 或 webpack-dev-server 是通过 --hot 选项启动的,那么这个插件会被自动添加,所以你可能不需要把它添加到 webpack.config.js 中。关于更多信息,请查看 HMR 概念 页面。
        hotOnly: true, // 启用热模块替换(请参阅devserver.hot),而不将页面刷新作为生成失败时的回退。
        // boolean object
        // https: true,  //  默认情况下,dev-server 通过 HTTP 提供服务。也可以选择带有 HTTPS 的 HTTP/2 提供服务:
        https: {
            key: fs.readFileSync('/path/to/server.key'),
            cert: fs.readFileSync('/path/to/server.crt'),
            ca: fs.readFileSync('/path/to/ca.pem'),
        },
        index: 'index.html', // 被作为索引文件的文件名。
        inline: true,  // 推荐使用 模块热替换 的内联模式,
        noInfo: true,  // 告诉 dev-server 隐藏 webpack bundle 信息之类的消息。devServer.noInfo 默认禁用。
        // boolean string
        open:'Google Chrome', // 告诉 dev-server 在 server 启动后打开浏览器。默认禁用。
        openPage: '/different/page', // 指定打开浏览器时的导航页面。
        // boolean object: { boolean errors, boolean warnings }
        overlay: { // 如果想要显示警告和错误:
            warnings: true,
            errors: true
        }, 
        // object [object, function]
        // proxy: { // 请求到 /api/users 现在会被代理到请求 http://localhost:3000/api/users。
        //     '/api': 'http://localhost:3000'
        // },
        // '/api': {  // 如果你不想始终传递 /api ,则需要重写路径:
        //     target: 'http://localhost:3000',
        //     pathRewrite: {'^/api' : ''}
        // },
        // '/api': { // 默认情况下,不接受运行在 HTTPS 上,且使用了无效证书的后端服务器。如果你想要接受,修改配置如下:
        //     target: 'https://other-server.example.com',
        //     secure: false
        // },
        // '/api': { // 有时你不想代理所有的请求。可以基于一个函数的返回值绕过代理。
        //     target: 'http://localhost:3000',
        //     bypass: function(req, res, proxyOptions) {
        //       if (req.headers.accept.indexOf('html') !== -1) {
        //         console.log('Skipping proxy for browser request.');
        //         return '/index.html';
        //       }
        //     }
        // },
        proxy: [{ //如果你想要代理多个路径特定到同一个 target 下,你可以使用由一个或多个「具有 context 属性的对象」构成的数组:
            context: ['/auth', '/api'],
            target: 'http://localhost:3000',
        }],
        // publicPath: '/assets/', // 将 bundle 放在指定目录下:现在可以通过 http://localhost:8080/assets/bundle.js 访问 bundle。
        publicPath: 'http://localhost:8080/assets/',  // 也可以使用一个完整的 URL。这是 模块热替换 所必需的。
        quiet: true, // 启用 devServer.quiet 后,除了初始启动信息之外的任何内容都不会被打印到控制台。这也意味着来自 webpack 的错误或警告在控制台不可见。 
        socket: 'socket', // 用于监听的 Unix socket(而不是 host)。
        staticOptions: { // 这只有在使用 devServer.contentBase 是一个 string 时才有效。 可以用于对 contentBase 路径下提供的静态文件,进行高级选项配置。有关可能的选项,请查看 Express文档。
            redirect: false
        },
        // string: 'none' | 'errors-only' | 'minimal' | 'normal' | 'verbose' object
        stats: 'errors-only', 
        useLocalIp: true, // 此选项允许浏览器使用本地 IP 打开。
        watchContentBase: true, // 告知 dev-server,serve(服务) devServer.contentBase 选项下的文件。开启此选项后,在文件修改之后,会触发一次完整的页面重载。
        watchOptions: { // webpack 使用文件系统(file system)获取文件改动的通知。在某些情况下,不会正常工作。例如,当使用 Network File System (NFS) 时。Vagrant 也有很多问题。在这些情况下,请使用轮询: 如果这对文件系统来说太重了的话,你可以修改间隔时间(以毫秒为单位),将其设置为一个整数。
            poll: true
        },
        // boolean: false function (filePath)
        writeToDisk: (filePath) => {
            return /superman\.css$/.test(filePath);
        },


    },
    // 构建目标 string | function (compiler) 
    // target:'web', // async-node electron-main electron-renderer node node-webkit web  webworker
    target: (compiler) => {
        compiler.apply(
          new webpack.JsonpTemplatePlugin(options.output),
          new webpack.LoaderTargetPlugin('web')
        );
    },
    // boolean: false  是否开启观察模式
    watch:true,
    watchOptions: {
        aggregateTimeout: 300, //当第一个文件更改,会在重新构建前增加延迟。这个选项允许 webpack 将这段时间内进行的任何其他更改都聚合到一次重新构建里。以毫秒为单位:
        poll: 1000, // 每秒检查一次变动
        // ignored: /node_modules/, //对于某些系统,监听大量文件系统会导致大量的 CPU 或内存占用。这个选项可以排除一些巨大的文件夹,例如 node_modules:
        ignored: ['files/**/*.js', 'node_modules'],

    },
    // string object function regex 外部扩展不被webpack打包的模块
    externals : {
        lodash : {
            commonjs: 'lodash',
            amd: 'lodash',
            root: '_' // 指向全局变量
        }
    },
    // 这些选项可以配置是否 polyfill 或 mock 某些 Node.js 全局变量和模块。这可以使最初为 Node.js 环境编写的代码,在其他环境(如浏览器)中运行。
    node: {
        console: false,
        global: true,
        process: true,
        __filename: 'mock',
        __dirname: 'mock',
        Buffer: true,
        setImmediate: true  
        // 更多选项,请查看“其他 Node.js 核心库”。
    },
    // 性能
    performance:{
        hints: false, // false | "error" | "warning"
        maxEntrypointSize: 400000, // 入口起点表示针对指定的入口,对于所有资源,要充分利用初始加载时(initial load time)期间。此选项根据入口起点的最大体积,控制 webpack 何时生成性能提示。默认值是:250000 (bytes)。
        maxAssetSize: 100000, // 资源(asset)是从 webpack 生成的任何文件。此选项根据单个资源体积,控制 webpack 何时生成性能提示。默认值是:250000 (bytes)。
        assetFilter: function(assetFilename) { //此属性允许 webpack 控制用于计算性能提示的文件
            return assetFilename.endsWith('.js');
        },
        // 统计信息(stats)  如果你不希望使用 quiet 或 noInfo 这样的不显示信息,而是又不想得到全部的信息,只是想要获取某部分 bundle 的信息,使用 stats 选项是比较好的折衷方式。
        // 对于 webpack-dev-server,这个属性要放在 devServer 对象里。在使用 Node.js API 时,此选项无效。 
        stats : 'errors-only',
    }

5、继承、闭包、原型链的优缺点、作用、方式、注意;面向对象的理解;

闭包:

  • 定义:能读取其他函数内部变量的函数
  • 作用:读取函数内部变量的值
  • 缺点: 变量是保存在内存中,内存消耗大,所以会造成网页的性能问题;
  • 解决/注意:在退出函数前,将不适用的变量全部删除;

继承:

  • 定义:子类有父类的所有属性和方法
  • 优点: 抽取重复代码,减少代码冗余
  • 缺点: 代码耦合性太强

   继承方式:

  • 构造函数式:借用call或apply方法,把父类构造函数复制继承到子类上,子类new出的实例,就是把父类构造函数的内容copy到实例中,所以每个实例都是独立的,私有的;

       缺点:只实现属性的私有,没有实现方法共享

  • 原型链式: 借用js对象的特性,对象在寻找自己属性时,先在当前对象上找,没有,再去自己原型链上找,一直向上找直到null

       好处:节省内存

       缺点:属性和方法全部都被共享了

  • 组合式(原型链+构造函数): 基本属性放父类的构造函数里;共享的函数方法放在父类原型上

       优点:实现函数共享,属性私有

  • Object.create()寄生式
  • 寄生组合式

面向对象:

三大特征:

  • 继承;目的: 实现代码复用;注:父类的私有属性private和构造方法不能被继承;子类可以写自己特有属性和方法,实现功能的扩展,子类可以复写父类的方法;protected属性对外界隐藏,允许子类访问;
  • 封装;目的: 增强安全性和简化代码,使用者不需要了解具体实现细节,只要通过外部接口,来使用;
  • 多态;可扩展,增强维护性;

创建对象的方式:

  • 对象字面量:var a={}
  • 用面向对象的方法: var obj=new Object()
  • 构造函数方式 function Abc(){} var c=new Abc() 构造函数首字母大写 优化:把方法放在原型上,,把属性放在构造函数上,把共有属性放在init方法函数中,也在放到原型上,这样避免内存浪费,方法可以共有;

创建对象的模式:

  • 工厂方式
  • 构造函数方式

6、数组、对象常用方法;

  • 判断是否为数组: Array.isArray(x)=>true/false; a instanceof Array =>true/false ;  Object.prototype.toString.call([])
  • 连接数组: arr1.concat(arr2) => []
  • 数组中元素是否通过某函数测试:arr.every(function) => true/false  (.some)
  • 过滤数组中的通过某函数测试的数组: arr1.filter(() => {}) 返回新数组
  • 查找数组中满足某函数的第一个元素: arr.find(() => {})
  • 循环数组:arr.forEach(() => {})               arr.map(() => {})
  • 判断数组是否包含某值: arr.includes(x) => true/false
  • 找到数组中给定元素的第一个索引: arr.indexOf(x, index) => index
  • 将数组拼接: arr.join(); 默认为, ‘’为空 ‘-’为-
  • 数组中删除最后一个元素: arr.pop() =>被删除的元素;改变length
  • 数组中删除第一个元素: arr.shift() => 被删除的元素;改变length
  • 添加数组元素到末尾: arr.push() => 新数组长度
  • 添加数组元素到开头: arr.unshift()
  • 数组中所有元素按照某函数进行累加: arr.reduce(function)
  • 将数组元素颠倒: arr.reverse()
  • 数组排序: arr.sort()
  • 增加或删除数组的元素: arr.splice()
  • 转变为字符串: arr.toString()
  • 判断基本类型: type of()
  • 判断引用类型: instance of

7、如何阻止事件冒泡或默认行为?

  • 事件冒泡:e.stopPropagation()
  • 默认事件:e.preventDefault()

8、跨域解决方法?

跨域:协议、域名、端口号不同

解决方法:

  • jsonp: 原理:通过script标签引入js文件,js文件载入成功后,会执行我们在url参数中指定的函数,并且把我们需要的json数据作为参数传入 缺点:只支持get,不支持post
  • 反向代理:webpack配置,地址指向网络地址
  • cors: 跨域资源共享:只要服务器实现了CORS接口,就可以跨域; IE10以下不兼容;

9、http协议?

超文本传输协议: 从服务器传输HTML页面到本地浏览器的传送协议

http组成部分(请求报文):请求行(包括请求方法、URI、HTTP版本信息)、请求头、请求体;

http(响应报文):状态行(HTTP版本、状态码、状态码原因短语)、响应头,响应体;

http方法有哪些:GET、POST、PUT、DELETE、HEAD、OPTIONS;

http://example.com:一级域名:  .com; 二级域名: example;   子域名: example.com; 父域名: .com;

http无状态协议:当客户端发送完http请求后,再一次发送请求,http不知道客户端是一个老客户,只要在第一次访问的时候携带cookie,再来的时候,带着cookie,服务器就可以知道是老客户了;

影响http网络请求的因素:带宽和延迟(浏览器阻塞、DNS查询、建立连接);

http优化:

  • TCP复用(负载均衡设备):将对个客户端的HTTP请求复用到一个服务器TCP连接上;
  • 内容缓存;
  • 压缩减少带宽;
  • SSL加速;
  • TCP缓冲;

http2与http1相比的好处:

  • 多路复用的单一长链接,减少了SSL握手的开销;
  • 头部压缩,减少数据传输量;
  • 多路复用提高传输效率,不用等待上一个请求的相应;

http与https区别:

  • 通信使用明文不加密,内容可被窃听;
  • 不验证通信方身份,可能遭到伪装;
  • 无法验证报文完整性,可能被篡改;

GET、POST区别:

  • get从服务器上获取资源,post是向服务器发送数据;
  • get通过url请求,参数可见,不安全,post通过请求实体发送给服务器,参数不可见,安全性较高;
  • get传输数据量小,效率高,post传输大量数据,上传文件时只能用post方式;
  • get只支持ASCII字符,传中午可能会乱码,post可以传输中文;

http状态码:

  • 1xx:指示信息--表示请求已接收,继续处理;
  • 2xx:成功--请求已被接受;
  • 3xx:重定向--要完成请求必须进行更进一步的操作;
  • 4xx:客户端错误--请求有语法错误或请求无法实现;
  • 5xx:服务端错误--服务器未能实现合法的请求;
  • 200:请求被正常处理;
  • 206:客户端之请求资源一部分,服务器只对请求的部分资源执行GET方法,相应报文通过Content-Range指定范围的资源;
  • 301:永久性重定向;
  • 302:临时重定向;
  • 303:希望客户端在请求一个url的时候,通过get方法重定向到另一个url上;
  • 304:发送附带条件的请求时,条件不满足时返回,与重定向无关;
  • 307:临时重定向,强制使用post方法;
  • 400:请求报文语法错误,服务器无法识别;
  • 401:请求需要验证;
  • 403:请求的对应资源禁止被访问;
  • 404:服务器无法找到对应资源;
  • 500:服务器内部错误;
  • 503:服务器正忙;

常见的首部:

  • 通用首部字段(请求报文与响应报文都会使用的首部字段)
    • Date:创建报文时间
    • Connection:连接的管理
    • Cache-Control:缓存的控制
    • Transfer-Encoding:报文主体的传输编码方式
  • 请求首部字段(请求报文会使用的首部字段)
    • Host:请求资源所在服务器
    • Accept:可处理的媒体类型
    • Accept-Charset:可接收的字符集
    • Accept-Encoding:可接受的内容编码
    • Accept-Language:可接受的自然语言
  • 响应首部字段(响应报文会使用的首部字段)
    • Accept-Ranges:可接受的字节范围
    • Location:令客户端重新定向到的URI
    • Server:HTTP服务器的安装信息
  • 实体首部字段(请求报文与响应报文的的实体部分使用的首部字段)
    • Allow:资源可支持的HTTP方法
    • Content-Type:实体主类的类型
    • Content-Encoding:实体主体适用的编码方式
    • Content-Language:实体主体的自然语言
    • Content-Length:实体主体的的字节数
    • Content-Range:实体主体的位置范围,一般用于发出部分请求时使用

10、cookie/setStorage/localStorage 区别、优缺点;浏览器的缓存作用?

cookie:

  • 指定作用域,不可跨域,有大小限制,每次请求一个新页面cookie被发送;不能大于4k;

浏览器的缓存作用:

  • 为了节约网络资源加速浏览,用户浏览页面,把文档存在本地磁盘上,用户在访问时,浏览器将本地磁盘上数据取出,就不用在服务器取了;  

区别:

  • cookie 始终在同源的http请求中携带(即使不需要),会在浏览器和服务器间来回传递。
  • sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。
  • localStorage 存储持久数据,浏览器关闭后数据不丢失,除非主动删除数据;
  • sessionStorage 数据在当前浏览器窗口关闭后自动删除。
  • cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭

如何实现浏览器内多个标签页之间的通信?

  • WebSocket、SharedWorker;也可以调用localstorge、cookies等本地存储方式;

call和apply的作用是什么?区别是什么?

  • call和apply的功能基本相同,都是实现继承或者转换对象指针的作用;
  • 唯一不通的是前者参数是罗列出来的,后者是存到数组中的;

11、setState与props区别、setState后发生了什么、第二个参数作用?

异步调用的

  • 传入的参数与组件当前状态合并;
  • 重新渲染UI界面,之后React自动计算新老树节点差异,去最小化渲染页面,按需更新;
  • 第二个参数是回调函数,作用:setState函数调用完成,组件开始重新渲染时便被调用,用该函数监听是否渲染完成;

12、如何选取一个类?

  • 构造函数法: 内部this指向实例对象
  • Object.create(x): x就是一个对象,不是函数; 缺点:不能实现私有方法及私有属性,实例对象直接不能共享数据;
  • 极简主义法: 用一个对象模拟类,在类里面定义一个构造函数,用来生成实例,实例中可以得到构造函数里的属性和方法; 好处:容易理解,结构清晰

       私有属性/私有方法: 只要不是定义在对象上的方法和属性,定义在构造函数都是私有的;     

       数据共享: 所有实例对象能读取同一项内部数据,需要封装在类对象的里面,构造函数外面;

13、声明提升?

 js的预解析和运行,在预解析阶段,所有变量和函数定义会提前,变量赋值不会提前;

14、移动端点击事件的延迟、解决办法、为何又会?

 click有300ms延迟,为了实现safari的双击事件的设计,浏览器要知道是否双击;

 解决: touch.js的tap事件代替

15、事件委托/代理、变量、作用域、作用域链、事件监听、事件处理函数、方法、优缺点?

事件委托/代理:

  • 利用事件冒泡原理,让自己所触发的事件,让父元素代替执行;

实现原理:

  • event.target监听实际触发元素;避免是期望元素的子节点,需追加parentNode循环判断。

好处:

  • 提高性能、提高事件的处理速度,减少内存占用;
  • 动态添加DOM元素,不要因为元素的改动而修改事件绑定

事件监听:

  • 有三个阶段,捕获、目标、冒泡;
  • 优点:可绑定多个事件,可解除相应的绑定

事件处理函数:

  • 处理用户操作的函数,不同操作,不同名称;

方法:

  • DOM直接绑定,比如onCLick;
  • 在javaScript代码中绑定;
  • 绑定事件监听函数,比如addEventListner()、 attachEvent();

作用域:

  • 全局作用域、函数作用于、eval作用域;没有块级作用域;

作用域链:

  • 当函数被创建,就有了作用域,当被调用,就有了作用域链,当被继承,就有了原型链,当需要获取作用域链或原型链上的变量或值时,就有了闭包;

16、react-router原理 ?两种实现方式?

react-router原理:

  • 在history库的基础上实现了URL与UI的同步
  • 监听url的变化,匹配路由规则,显示相应的页面,而且无需刷新页面跳转;

实现方式:

  • hash模式:www.test.com/#/  就是hash url, #后面哈希值变化时,通过hashchange事件监听url变化,跳转页面;
  • history模式: 使用history.pushState和history.replaceState改变url,不会刷新页面,只会更新浏览器历史记录;

两种对比:

  • history可以通过api添加任意类型的数据到历史记录中,在用户手动输入地址或者刷新页面时会发起url请求,后端需要配置index.html页面用户匹配不到静态资源的时候;
  • hash只能更改哈希值,hash无需后端配置,兼容性好;

React-router原理: 实现URL与UI界面的同步;URL=》location,UI=》component;

具体实现:

  • Router与route的区别:
  • Route:是进行url和函数的映射;
  • Router:在接收到一个url后,去路由映射表中查找相应的函数;
  • 客户端路由:路由的映射函数通常进行一些DOM的显示和隐藏操作;基于Hash(#及其后),History API两种方法;
  • History三种形式:browserHistory、hashHistory、createMemoryHistory;

react-router依赖的基础是History,是个独立的第三方js库,兼容在不同浏览器、不同环境下对历史记录的管理,拥有统一的API。具体来说里面的history分为三类:

老浏览器的history:  主要通过hash来实现,对应createHashHistory利用HTML5里面的history  pushState、replaceState 高版本浏览器: 通过html5里面的history,对应createBrowserHistory 通过hash来存储在不同状态下的history信息  location.hash=*** location.replace()

node环境下:  主要存储在memeory里面,对应createMemoryHistory在内存中进行历史记录的存储

17、url加载页面发生了什么?

  • DNS获取URL的IP地址;
  • Socket.Connect 浏览器与服务器建立TCP连接
  • Send Request 发送Http请求
  • Contentdownload 服务器发送响应

1、DNS解析:

目的:寻找哪台计算机上有你需要的资源;

方法:递归查询;迭代查询;

过程:浏览器中的地址其实不是真正意义上的地址,互联网每台计算机都有一个唯一的标识就是IP地址,但是用户都喜欢用方便的网址去寻找其他计算机,也就是网址,所以利用一个网址转换到IP地址,就是DNS解析的过程。

DNS解析细致过程:

  • 客户端输入网址
  • 在本地域名服务器寻找,若未找到,向根域名服务器发送请求;
  • 若跟域名服务器未找到,本地域名服务器向顶级域名服务器发送请求,以此类推;

如何优化DNS解析过程?

  • 设置DNS缓存方式:((以距离浏览器距离排序)浏览器缓存、系统缓存、路由器缓存、IPS服务器缓存、根域名服务器缓存、顶级域名服务器缓存、主域名服务器缓存;

DNS负载均衡,及过程?

  • DNS每次返回的地址有可能一样,有可能不一样,如果是一样,有可能同一台服务器需要承载很多的请求,而用户的眼里,只需要服务器处理它的请求,哪台机器不重要,所以,DNS只有可以返回一个是个的机器IP给用户就可以,可以根据每台机器的负载量、机器距离用户地理位置距离等等,这个过程就是DNS负载均衡;

2、TCP链接:

        三次握手

3、发送HTTP请求:

        将用户输入的地址封装成HTTP Request 请求报文(请求头+请求行+请求体 => 字符串 => 二进制数据)发送给服务器 => 服务器把二进制数据解析成字符,之后,按照HTTP协议规范中定义的格式解析出来;

HTTP报文是放在TCP报文中发送出去的,服务器收到TCP报文解包提取HTTP报文,HTTP是明文,有风险,所以在进入HTTP报文前做加密,HTTPS本质=HTTP+SSL/TLS;

4、服务器根据请求报文中的get/post、url中的查询字符串或者请求体中的数据,去处理用户请求信息;处理完请求后,服务器将结果按照HTTP协议规范封装到HTTP Response相应报文中(响应头、响应字段、响应体 => 字符串转二进制数据),通过Socket(IP地址、端口号)发送给客户端 => 将二进制数据解析;

5、浏览器收到响应后渲染HTML、CSS,解析和执行JavaScript代码;

18、ajax原理、过程、优缺点、定义?ajax、axios、fetch优缺点?

定义: Asynchronous javaScript and XML

优点:不刷新整个页面的情况下与服务器通信保持原有页面状态;异步的

缺点: ajax逻辑会把对客户端的安全扫描技术隐藏起来,允许黑客从远程服务器上建立新的攻击,例如跨站点脚本攻击,SQL注入攻击

$ajax参数:

  • url: 请求地址;  
  • type: 请求类型,
  • get/post;  
  • timeout:设置请求超时的毫秒数;
  • async 为true, 所有请求为异步,false是同步;
  • data: 发送到服务器的数据,参数;

过程:

  • 创建对象,打开浏览器; var xhr = new XMLHttpRequest
  • 输入地址:             xhr.open(‘post’, ‘1.text’, true)
  • 发送请求:              xhr.send()
  • 等待服务器返回内容:    xhr.onreadystatechange = function () { if (xhr.readyState === 4) {        if (xhr.status ===200 ){                alert(xhr.responseText)                                 } else {                                      alert(‘出错了’)                                  }

ajax创建:

  • 异步向服务器发送请求数据;
  • 创建XMLHttpRequest异步调用对象;
  • 创建HTTP请求,指定方法、url及验证信息;
  • 设置响应HTTP请求状态变化的函数;
  • 发送;
  • 获取异步返回数据;
  • 局部刷新;

ajax、axios、fetch优缺点:

fetch:

缺点: 

  • fetch只对网络请求报错,对400500都当做成功的请求,需要封装去处理
  • fetch默认不会带cookie,需要添加配置项。
  • fetch不支持abort中断,不支持超时控制,使用setTimeoutPromise.reject的实现超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费。
  • fetch没有办法原生监测请求的进度,而XHR可以。

优点:

  • 更加底层,提供的API丰富(request, response)
  • 脱离了XHR,是ES规范里新的实现方式
  • 跨域处理(mode为"no-cors")

axios:

优点:

缺点

  • 从浏览器中创建XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF
  • 只持现代代浏览器.

ajax:

优点

对原生XHR的封装,做了兼容处理,简化了使用。 增加了对JSONP的支持,可以简单处理部分跨域。

缺点

  • 如果有多个请求,并且有依赖关系的话,容易形成回调地狱。
  • 本身是针对MVC的编程,不符合现在前端MVVM的浪潮。
  • ajax是jQuery中的一个方法。如果只是要使用ajax却要引入整个jQuery非常的不合理。
     

19、垂直居中问题、弹性和?

盒子垂直居中方法:

  • 1、display:flex;    justify-content:center;    align-items:center;
  • 2、父元素position:relative; 子position: absolute; left: 50%;    top: 50%;   width: 100px;   height: 100px;   ( margin-left: -50px;    margin-top: -50px )或者( transform: translate(-50%, -50%) );

20、git/svn?

21、前端性能优化(资源接口优化、构建优化、渲染优化、网络优化)?

页面内容:

  • 1、减少http请求次数:合并文件把所有脚本放在一个文件中;多张图片放在一张图片上,通过background-image、background-position控制;
  • 2、减少DNS查询;
  • 3、避免重定向;
  • 4、缓存Ajax请求
  • 5、延迟加载:非首屏使用的数据、样式、脚本、图片、用户交互时才会显示的内容
  • 6、预加载:浏览器空闲的时候请求将来用的资源;
  • 7、减少DOM元素数量
  • 8、划分内容到不同域名
  • 9、尽量减少iframe的使用;
  • 10、避免404错误:浪费服务器资源,降低用户体验

服务器:

  • 1、使用CDN
  • 2、Ajax请求使用GET方法
  • 3、避免图标src为空:空的src会向页面本身返送http请求

Cookie:

  • 1、减少Cookie大小
  • 2、静态资源使用无Cookie域名

CSS:

  • 1、样式表放在中
  • 2、不要使用CSS表达式
  • 3、使用《link》代替@import
  • 4、不要使用filter

JS

  • 1、脚本放在页面底部
  • 2、使用外部的JS和css:外部的js/css可以被浏览器缓存,在不同页面中重用
  • 3、压缩js、css:减小文件大小,提高加载速度
  • 4、移除重复脚本
  • 5、减少DOM操作
  • 6、使用高效的事件处理
  • 7、减少回流和重绘

图片:

  • 1、优化图片
  • 2、优化CSS sprite
  • 3、不要在html中缩放图片 使用体积小、可缓存的favicon.ico

移动端:

  • 1、保证所有组件<25k(未压缩)
  • 2、打包内容为分段文档

22、ref是什么?受控和非受控组件区别?有/无状态组件?

ref可以挂在组件或dom元素上,挂在组件上标识对组件实例的引用,挂在dom上是标识具体的dom元素节点;

ref可以设置回调函数,被挂载回调,回调被立即执行,参数为该组件的具体实例;组件被卸载,回调被立即执行,参数为空;

ref可以设置字符串,通过this.refs.xxx获取;

受控和非受控组件:

  • 受控组件指交由react控制并且所有表单数据统一存放的组件,input表单,通过state设置value,setState改变值;
  • 非受控组件指由DOM存放表单数据,并非存放在react组件中,设置input 的ref属性;

有/无状态组件:

  • 无状态组件: 只负责展示的纯组件,不需要管理状态,直接通过props传入;
  • 有状态组件:组件内部包含状态,且会随着事件或外部的消息而改变;通常会带有生命周期,不同时刻触发状态的更新;

23、声明组件的方式?react组件的划分?调用super(props)的目的是什么?

  • 无状态组件,又叫纯组件SFC
  • React.creactClass
  • React.component   ES6 class…extends

ui组件负责ui的呈现,容器组件负责管理数据和逻辑;二者通过react-redux提供的connect方法联系起来;

调用super(props)之前,子类不能使用this, 调用super(props)便于子类在constructor中访问this.prps;

24、算法?

基本排序:

  • 冒泡排序:从头开始,两个两个互相比较,小的放前面;      
  • 选择排序:从头开始,第一个数与后面所有相比,最小的放第一个位置;
  • 插入排序: 第一个放哪里无所谓,接下来比第一张小,放左边,依次进行;

高级排序:

  • 快速排序:采用递归方式,随意找到一个数,小的放前面,大的放后面,分别对前后做相同的操作比较;
  • 希尔排序:插入排序的改良算法,但与其核心概念不同,先从比较远的开始比较,小的放在前面;

25、内存泄漏的几种情况?

  • 闭包return 给window;
  • 未声明的全局变量;
  • 定时器没有及时clear;
  • vue 中在mounted/created 用$on;
  • 给DOM对象添加的属性时一个对象的引用;
  • DOM对象与JS对象相互引用;
  • 反复写同一个属性会造成大量内存占用;

26、前端兼容性问题?

IE相关兼容性:

  • 问题:IE6双倍边距;
  • 现象:margin-left: 10px;被解析成20px;
  • 解决:加display: inline/block明确元素类型;

 

  • 问题:IE6三像素;
  • 现象:元素浮动后,元素与相邻元素之间有3px间隙;若相邻容器没设置高度,间隙在相邻容器内部,设定高度后跑到容器相反侧;
  • 解决:在同一行的元素都加上浮动;

 

  • 问题: IE6空元素的高度bug;
  • 现象: 如果元素没有内容,设置高度为0-19px,此元素高度始终未19px;
  • 解决: 给元素css加overflow: hidden;

 

  • 问题: IE6图片衔接下方有间隙;
  • 现象:图片挨着图片,下方有间隙;
  • 解决: 将img display: block 或 vertical-align对应属性 或将img font-size: 0;

 

  • 问题: 图片默认有间距;
  • 解决: float;

 

  • 问题:min-height
  • 解决: min-height: 50px; height: auto!important; height: 50px; overflow: visible;

 

  • safari中伪元素不支持CSS3动画
  • safari中元素高度为0,直接被忽略,在IE/chrome中都是作为块级看待,有相应的位置
  • IOS系统中,浏览器只支持给原生HTML按钮或《a》标签加js事件
  • Safari中Date.parse()解析时间字符串,格式必须是YYYY/MM/DD HH:MM:SS
  • IOS系统中,H5播放器不支持自动播放
  • 用原生js写粘贴复制到剪贴板的时候,采用了很多方法,比如document.execCommand(‘copy’) 写了很多形式,就是不好使,后来google搜索才知道,不兼容chrome,只支持IE,这个浪费了很多时间,影响开发效率,百度搜索的问题;
  • PropTypes不好用的时候,把import PropTypes from 'react' 写成 import PropTypes from 'prop-types' ,把defaultPropTypes 改成 propTypes
  • 开发过程中,遇到了一个常见的兼容性问题: IOS不识别 ' 2018-12-13 '中的 ' - ',需要转为2018/12/13的形式才可以识别;
  • 开发过程中,写了两个定时器,在两个定时器需要在某个条件下,替换的时候,需要clearInterval清除定时器,要不然会出现,每秒会相继执行两个定时器的现象;
  • 不要在componentWillRecivieProps里使用setState, 如果要使用,需要判断结束条件,不然会出现无限重渲染,导致页面奔溃;
  • 画布节点拖拽卡顿,用的lodash的throttle方法控制节流,减少setState的次数;
  • 前端用的是history跳转的,但是url地址页面一刷新就报错,后来后端那边设置了一判断处理,才可以的;

27、项目中遇到的问题?

  • redux的state更新与页面的state设计如果不够好,容易双向setstate;
  • 用原生js写粘贴复制到剪贴板的时候,采用了很多方法,比如document.execCommand(‘copy’) 写了很多形式,就是不好使,后来google搜索才知道,不兼容chrome,只支持IE,这个浪费了很多时间,影响开发效率,百度搜索的问题;
  • PropTypes不好用的时候,把import PropTypes from 'react' 写成 import PropTypes from 'prop-types' ,把defaultPropTypes 改成 propTypes
  • Antd里的modal嵌套问题,会出现穿透事件;
  • safari中伪元素不支持CSS3动画
  • safari中元素高度为0,直接被忽略,在IE/chrome中都是作为块级看待,有相应的位置
  • IOS系统中,浏览器只支持给原生HTML按钮或《a》标签加js事件
  • Safari中Date.parse()解析时间字符串,格式必须是YYYY/MM/DD HH:MM:SS
  • IOS系统中,H5播放器不支持自动播放

28、冒泡和捕获,有什么区别?有哪些事件是不会冒泡的?

focus、blur、load、unload等事件,不会冒泡。

29、页面刷新?

  • location.reload()
  • location.href=当前URL
  • location.replace(当前URL)

浏览器基础对象有哪几个?

  • Window、Navigator、Screen、History、Location

30、link 与@import区别?

  • link 是xhml标签,无兼容性,可加载css,用于定义Rss,rel链接属性,页面加载时同时加载;
  • @import只用于加载css,页面加载后才加载

31、内核?

  • Trident: IE/360/搜狗浏览器
  • Gecko : Firefox
  • Presto: Opera7及以上
  • Webkit:   Safari,Chrome:

32、开发环境、测试环境、预发环境、正式环境的理解?

  • 开发环境:专门用于开发的服务器,配置比较随意,为了开发调试方便,一般会打开全部错误报告;
  • 测试环境: 项目开发完成,一般克隆一份生产环境的配置,在这个环境做些调试,测试,修改bug;
  • 生产环境: 正式提供对外服务的,一般会关掉错误报告,打开错误日志;

33、class继承?

Constructor构造函数中的suprer关键字作用:

  • 不调用会报错,子类会得不到this;
  • super代表父类的构造函数,返回的是子类的实例,当做函数使用时,super内部this指向子类
  • super当对象使用时,在普通方法中,指向父类的原型,在static方法中使用,指向父类;
  • 判断一个类是否继承了另一个类的方法: Object.getPrototypeOf(子类) === 父类

34、prototype与_proto_区别?

A是父类,B是子类

B._proto_=== A;                  B.prototype._proto_ === A.prototype;  

  • 子类实例: b,_proto_.proto_ === a._proto_
  • 类的name属性指向class后面的名字
  • 类的static方法不会被实例继承

35、线程与进程的区别及联系?

进程: 一个完成的任务;比如,调用数据库

线程: 完成这个任务的诸多子任务之一;比如要从数据库中产生一份统计表,上传到某文件;

一个线程只属于一个进程,一个进程可以有多个进程;

线程好处:提高并发性;

36、节流、防抖、回流、重绘?

回流:

  • dom树种部分或者全部元素的尺寸、结构、或某些属性发生改变时,浏览器重渲染部分或全部,需要计算他们在设备饰扣内的确切位置和大小;

导致原因:

  • 页面首次渲染;浏览器窗口大小改变、元素尺寸、位置、内容改变;增删DOM;

重绘:

  • 元素样式改变并不影响在文档流中的位置(color/background-color),浏览器重新赋予新样式,并且重新绘制;

       重绘节点:将每个节点转换为屏幕上的实际像素;

避免:       

  • Css: 避免使用table布局、尽可能在DOM树的最末端改变class、避免使用多层内联样式;       
  • Js:避免频繁操作样式和DOM

浏览器的渲染过程:

  • 解析html,生成DOM树,解析CSS,生成CSSOM,二者结合,生成渲染树,根据生成的渲染树,进行回流,得到节点的几何信息,根据得到的几何信息,得到节点的绝对像素,将像素发送给GPU,展示在页面上;

生成渲染树:

  • 从DOM树的根节点开始遍历每个可见的节点,找到CSSOM树对应的规则,并应用他们,根据其样式,生成渲染树;

不可见的节点:

  • 一些不会渲染输出的节点,比如script,meta,link,一些通过css隐藏的节点,display:none;

浏览器的优化机制:

  • 每次重排都会造成额外的计算损耗,因此大多数浏览器会通过队列化修改,并批量执行来优化重排过程,浏览器会将修改操作放入到队列里,达到一个阙值,清空队列,当获取布局信息的操作的时候,会强制队列刷新,重发回流和重绘;

防抖:

  • 当函数频繁触发时,在有空闲的时间时,执行一次; debounce(func, time, option) 该函数从上一次被调用,延迟xx毫秒后调用Fn方法;定时器

防抖运用场景:

  • 实时搜索,拖拽,登录用户名密码格式验证等等;

节流:

  • 设定一个函数只有在一定周期内才执行; throttle(func, time, option) xx毫秒内最多执行fn一次函数;时间撮; 节流运用场景:窗口调整、页面滚动、抢购疯狂点击;

区别:

  • 持续触发事件时,防抖设置事件延迟并在空闲时间去触发事件,节流是隔一段时间触发一次;

 

37、轮播、懒加载、上拉加载工作原理?

38、网络安全、单元测试,mock、node?

39、正向代理与反向代理的区别?

面试总结1024_第2张图片

 

正向代理:(发生在客户端)

定义:

  • 位于客户端和原始服务器之间的服务器,为了从原始服务器取得数据,客户端向代理发送一个请求并指定目标服务器,代理向目标服务器转发请求并获得数据给客户端,客户端需要进行设置;

用途:

  • 访问原来无法访问的资源,如google;
  • 对客户端访问授权,上网进行认证;
  • 代理可以记录用户访问记录,对外隐藏用户信息;
  • 可以做缓存,加速访问资源;
  • 黑客隐藏身份;

 

反向代理:(发生在server端)

定义:

  • 指以代理服务器来接受客户端请求,然后转发给内网服务器,将结果返回给客户端;
  • 用户访问a服务器,a就给用户返回了数据,但实际a并没有数据,是从b服务器上取回来,返回客户端的;

用途:

  • 负载均衡,服务器会把请求分发给多个不同服务器,减轻单个服务器处理海量请求的压力;
  • 缓存:数据缓存在代理服务器上,客户端请求的内容如果在缓存中,可以不去访问目标服务器;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(面试总结1024)