面试题目录
- ES6、ES7新特性;H5、CSS3新特性?es5与es6对比,语法有何不同?
- react/vue生命周期;优缺点;react16新特性?react中的keys的作用是什么?redux?高阶组件?
- 手机适配?
- 前端工程化工具、webpack作用、配置webpack、包括哪些配置项;webpack打包文件太大怎么办;webpack与gulp区别?
- 继承、闭包、原型链的优缺点、作用、方式、注意;面向对象的理解?
- 数组、对象常用方法?
- 如何阻止事件冒泡或默认行为?
- 跨域解决方法?
- http协议?
- cookie/setStorage/localStorage 区别、优缺点;浏览器的缓存作用?
- setState与props区别、setState后发生了什么、第二个参数作用?
- 如何选取一个类?
- 声明提升?
- 移动端点击事件的延迟、解决办法、为何会出现这个问题?
- 事件委托/代理、变量、作用域、作用域链、事件监听、事件处理函数、方法、优缺点?
- react-router原理?两种实现方式?
- url加载页面发生了什么?
- ajax原理、过程、优缺点、定义?ajax、axios、fetch优缺点?
- 垂直居中问题、弹性和?
- git/svn?
- 前端性能优化(资源接口优化、构建优化、渲染优化、网络优化)?
- ref是什么?受控和非受控组件区别?有/无状态组件?
- 声明组件的方式?react组件的划分?调用super(props)的目的是什么?
- 算法?
- 内存泄漏的几种情况?
- 前端兼容性问题?
- 项目中遇到的问题?
- 冒泡和捕获,有什么区别?有哪些事件是不会冒泡的?
- 页面刷新?
- link 与@import区别?
- 内核?
- 开发环境、测试环境、预发环境、正式环境的理解?
- class继承?
- prototype与_proto_区别?
- 线程与进程的区别及联系?
- 节流、防抖、回流、重绘?
- 轮播、懒加载、上拉加载工作原理?
- 网络安全、单元测试,mock、node?
- 正向代理与反向代理的区别?
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值是否一致,不一致,组件销毁,新建;组件一致,属性是否发生变化,没变化,不改变,变化,就更新;
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 { <key>: string | [string] } | (function: () => string | [string] | object { <key>: 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
只对网络请求报错,对400
,500
都当做成功的请求,需要封装去处理fetch
默认不会带cookie
,需要添加配置项。fetch
不支持abort中断
,不支持超时控制,使用setTimeout
及Promise.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、样式表放在<head>中
- 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、正向代理与反向代理的区别?
正向代理:(发生在客户端)
定义:
- 位于客户端和原始服务器之间的服务器,为了从原始服务器取得数据,客户端向代理发送一个请求并指定目标服务器,代理向目标服务器转发请求并获得数据给客户端,客户端需要进行设置;
用途:
- 访问原来无法访问的资源,如google翻墙;
- 对客户端访问授权,上网进行认证;
- 代理可以记录用户访问记录,对外隐藏用户信息;
- 可以做缓存,加速访问资源;
- 黑客隐藏身份;
反向代理:(发生在server端)
定义:
- 指以代理服务器来接受客户端请求,然后转发给内网服务器,将结果返回给客户端;
- 用户访问a服务器,a就给用户返回了数据,但实际a并没有数据,是从b服务器上取回来,返回客户端的;
用途:
- 负载均衡,服务器会把请求分发给多个不同服务器,减轻单个服务器处理海量请求的压力;
- 缓存:数据缓存在代理服务器上,客户端请求的内容如果在缓存中,可以不去访问目标服务器;