Javascript基础
1. 箭头函数和普通函数的差异
1.1 不能通过 new 关键字调用, 没有原型
1.2 不可以改变 this 绑定,由外层非箭头函数决定,所以使用 call, apply, bind 也不会影响
- function 函数(优先级按序号从高到低)
- 在调用函数时使用 new 关键字,函数内的 this 是一个全新的对象。
- 如果 apply、call 或 bind 方法用于调用、创建一个函数,函数内的 this 就是作为参数传入这些方法的对象。
- 当函数作为对象里的方法被调用时,函数内的 this 是调用该函数的对象。
- 如果调用函数不符合上述规则,那么 this 的值指向全局对象(global object)。
- 浏览器环境下 this 的值指向 window 对象,但是在严格模式下'use strict',this 的值为 undefined。
- 箭头函数
- 无论如何执行或在何处执行,箭头函数内部的 this 值始终等于离它最近的外部函数的 this 值。换句话说,箭头函数可按词法解析 this,箭头函数没有定义自己的执行上下文。
- 熟悉 React 的同学都知道,之前如果在类里面使用方法我们需要先 bind 一下 this, 但箭头函数都给我们解决了
-
const obj = {
value: 2,
callback: function(arr) {
var self = this // 在嵌套函数里面使用外面的 this 需要先定义变量的情况
function showThis() {
console.log(self.value)
}
showThis()
}
}
const obj2 = {
value: 2,
callback: function(arr) {
showThis = () => {
console.log(this.value)
}
showThis()
}
}
obj.callback() // 2
obj2.callback() // 2
1.3 不支持 arguments,所以根据作用域链,会拿到外层函数的 arguments
- 常规函数
- 有一个arguments 的类数组对象,包含了函数的所有参数
- 经常使用在我们没有具体定义参数的情况下
- 箭头函数
- 箭头函数是不支持arguments 的类数组对象
- 如果你在箭头函数里面使用,按照作用域链的查找规则,会一直查询到最近的非箭头函数,然后实际使用的是非箭头函数里面的 arguments
- 为此,ES6 也提供了这种不定参数情况下的参数的操作,看下面的例子
const add = (...args) => {
return args.reduce((cur, i) => cur + i, 0)
}
add(5, 10, 15)
1.4 不支持重复命名参数
- 无论在严格还是非严格模式下,箭头函数都不支持重复的命名参数,而传统函数只有在严格模式下才不支持重复的命名参数。
var a = (b, b)=>{
b = 100
console.log(this)
console.log(b)
}
1.5 隐式返回
- 函数内部一直都有一个隐藏的返回值,使用
function
如果什么都不定义,其实默认就会返回 undefined
,我理解这是终止函数的执行,用代码来表示
function noReturn() {
console.log('aaa')
return
}
- 箭头函数省了一个 return,适合这种函数体内只有一行代码的情况,多行还是需要写的
2. 数组方法整理
方法名 | 对应版本 | 功能 | 原数组是否改变 |
---|
concat() | ES5- | 合并数组,并返回合并之后的数据 | n |
join() | ES5- | 使用分隔符,将数组转为字符串并返回 | n |
pop() | ES5- | 删除最后一位,并返回删除的数据 | y |
shift() | ES5- | 删除第一位,并返回删除的数据 | y |
unshift() | ES5- | 在第一位新增一或多个数据,返回长度 | y |
push() | ES5- | 在最后一位新增一或多个数据,返回长度 | y |
reverse() | ES5- | 反转数组,返回结果 | y |
slice() | ES5- | 截取指定位置的数组,并返回 | n |
sort() | ES5- | 排序(字符规则),返回结果 | y |
splice() | ES5- | 删除指定位置,并替换,返回删除的数据 | y |
toString() | ES5- | 直接转为字符串,并返回 | n |
valueOf() | ES5- | 返回数组对象的原始值 | n |
indexOf() | ES5 | 查询并返回数据的索引 | n |
lastIndexOf() | ES5 | 反向查询并返回数据的索引 | n |
forEach() | ES5 | 参数为回调函数,会遍历数组所有的项,回调函数接受三个参数,分别为value,index,self;forEach没有返回值 | n |
map() | ES5 | 同forEach,同时回调函数返回数据,组成新数组由map返回 | n |
filter() | ES5 | 同forEach,同时回调函数返回布尔值,为true的数据组成新数组由filter返回 | n |
every() | ES5 | 同forEach,同时回调函数返回布尔值,全部为true,由every返回true | n |
some() | ES5 | 同forEach,同时回调函数返回布尔值,只要由一个为true,由some返回true | n |
reduce() | ES5 | 归并,同forEach,迭代数组的所有项,并构建一个最终值,由reduce返回 | n |
reduceRight() | ES5 | 反向归并,同forEach,迭代数组的所有项,并构建一个最终值,由reduceRight返回 | n |
3. 数组浅拷贝方法
序号 | 方式 | 例子 | 说明 |
---|
1 | concat | let res = arr.concat(); | 连接数组返回一个新数组 |
2 | slice | let res = arr.slice(); | 返回选定的元素默认从0开始到结尾 |
3 | 解构 | let res = [...arr]; | 创建了一个新的数组赋值为当前数组的值 |
4 | 解构2 | let [...res] = arr; | 同上 |
5 | map | let res = arr.map(i=>i); | 遍历数组逐个返回元素给res |
6 | Array.of | let res = Array.of(...arr); | 该方式将一堆数字转化成数组返回 |
2.Webpack
2.1 webpack 性能优化-构建速度
1. 优化babel-loader
module: {
rules: [
{
test: /\.js$/,
use: ['babel-loader?cacheDirectory'],
include: path.resolve(__dirname, 'src')
}
]
}
2. IgnorePlugin 忽略无用文件
- 用IngorePlugin忽略无用文件
例如:moment会支持多语言,如何只引入中文模块?
new webpack.IgnorePlugin(/\.\/locale/, /moment/)
import 'moment/locale/zh-cn'
3. noParse 避免重复打包
module: {
noParse: [/react\.min\.js$/]
}
- IgnorePlugin、noParse区别:
- IgnorePlugin直接不引入,代码中没有
- noParse(类似vue.min.js已经模块化处理过)引入,但不打包
4. happypack 多进程打包工具
- JS 单线程,开启多进程打包
- 提高构建速度(特别是多核CPU)
const HappyPack = require('happypack')
{
test: /\.js$/,
use: ['happypack/loader?id=babel']
}
new HappyPack({
id: 'babel',
loaders: ['babel-loader?cacheDirectory']
})
5. ParalleUglifyPlugin 多进程代码压缩
- webpack 内置 Uglify 工具压缩JS
- JS单线程,开启多进程压缩更快
- 和happyPack 同理,多进程
const ParallelUglifyPlugin = require('ParallelUglifyPlugin')
new ParallelUglifyPlugin({
uglifyJS: {
output: {
beautify: false,
comments: false
},
compress: {
drop_console: true,
collapse_vars: true,
reduce_vars: true
}
}
})
6.自动刷新
- 自动刷新:整个网页都刷新,速度较慢
- 自动刷新:状态会丢失(表单内数据会丢失)
7. 热更新
- 热更新:新代码生效,网页不刷新,状态不丢失
- HotModuleReplacementPlugin插件在webpack/lib下
index: [
'webpack-dev-server/client?http://localhost:8080/',
'webpack/hot/dev-server',
path.join(srcPath, 'index.js')
]
在plugins中new HotModuleReplacementPlugin()
在devServer加hot: true
业务中加module.hot来确定哪些范围需要触发热更新
8. DllPlugin 动态链接库插件
- 使用原因
- 前端框架Vue、React 体积大 构建慢
- 较稳定,不常升级版本
- 同一个版本只构建一次即可,不用每次都重新构建
- webpack已经内置DllPlugin支持
- DllPlugin - 打包出dll文件
- DllReferencePlugin - 使用dll文件
- 使用方式
const path = require('path')
const DllPlugin = require('webpack/lib/DllPlugin')
const { srcPath, distPath } = require('./paths')
module.exports = {
mode: 'development',
entry: {
react: ['react', 'react-dom']
},
output: {
filename: '[name].dll.js',
path: distPath,
library: '_dll_[name]',
},
plugins: [
new DllPlugin({
name: '_dll_[name]',
path: path.join(distPath, '[name].manifest.json'),
}),
],
}
- DllReferencePlugin(记得 rules 中忽略打包的node_modules这个dll 代码)
plugins: [
new webpack.DefinePlugin({
ENV: JSON.stringify('development')
}),
new DllReferencePlugin({
manifest: require(path.join(distPath, 'react.manifest.json')),
}),
],
2.2 webpack性能优化-产出代码
作用
- 打包出的体积更小
- 合理分包,不重复加载
- 速度更快,内存使用更少
优化方式
- 小图片base64编码(对图片使url-loader配置options.limit)
- bundle加hash值([name].[contentHash:8].js)
- contentHash:8 是根据内容算出的 8位hash值
- 懒加载()=>import('')
- 提取公共代码splitChunks:公共代码和三方代码
- IgnorePlugin: 忽略文件不引入打包
- 用cdn加速:
- 在output中加publicPath
- 在url-loader中的options中也加入publicPath , 设置图片
- 使用production
- Scope Hosting
- 开启 gzip