5 迅速搞定 开发环境 运行环境 真题模拟(SY)

目录

1 常用 git 命令:

2  Chrome调试工具

3 移动端h5 抓包

4 webpack

5 ES6 模块化规范是什么

 6 前端用到的 linux 常用命令有哪些

7 网页是如何加载并渲染出来的

8 性能优化

9 手写防抖、节流

 10 常见的Web前端攻击方式有哪些?

面试题实战

1、var 和 let const 的区别

2、typeof 返回哪些类型

3、列举强制类型转换和隐式类型转换

4、手写深度比较,模拟lodash isEqual

5、split() 和 join() 的区别

6、数组的 pop push unshift shift 分别做什么

7、数组 slice 和 splice 的区别

8、[10, 20, 30].map(parseInt) 的返回结果是什么

9、ajax 请求 get 和 post 的区别

10、函数 call 和 apply 的区别

11、事件代理(委托)是什么

12、闭包是什么,有什么特性?有什么负面影响?

13、如何阻止事件冒泡和默认行为?

14、查找、添加、删除、移动 DOM 节点的方法?

15、如何减少 DOM 操作?

16、解释 jsonp 原理,为何它不是真正的 ajax?

17、document load  和 ready 的区别

18、== 和 === 的不同

19、函数声明和函数表达式的区别

20、new Object() 和 Object.create() 的区别

21、字符串 字母开头,后面数字字母下划线,长度 6 - 30

22、手写字符串 trim 方法,保证浏览器兼容性

23、如何获取多个数字中的最大值

24、如何用 class 实现继承

25、如何捕获 JS 程序中的异常?

26、什么是 JSON?

27、获取当前页面的 url 参数

28、将 url 参数解析为 JS 对象

29、手写数组 flatern(拍平),考虑多层级

30、数组去重

31、介绍一下 RAF requestAnimationFrame

32、Map 和 Set / 有序 和 无序 / Map 和 Object 区别/ Set 和 Array 区别

33、WeakMap 和 WeakSet

34 JS中 reduce() 的用法


MAC OS 自带git命令,windows可去官网下载安装

git服务端常见的有github  coding.net(码云)等

1 常用 git 命令:

git add . (点代表把所有改的文件都git上,如果后面是文件名,就是单独提交这个文件)

git checkout xxx (把xxx文件还原到未修改的状态)

git commit -m "xxx" (提交一行记录)

git push orign master (把提交的分支推送到远程服务端)

git pull origin master  (从远程服务端拉取分支)

git branch( 查看项目分支)

git checkout -b xxx / git checkout xxx (切换xxx分支)

git merge xxx (把xxx分支合并到主分支)

git操作

git commit -m "注释注释" 生成一条记录注释
git log 查看提交记录,Initial commit是创建时提交的,不用管
git config user.name 用户名
git config user.email 邮箱
git show id(这个id是git log 提交后commit后面显示的长串的ID,要看哪个就在show后贴哪个) 查看提交内容
git checkout 文件名 撤销某个文件的修改
git checkout . 撤销所有文件修改
checkout要在commit之前才能撤销

MIT License
HTTPS提交时需要提交用户名和密码
SSH需要设置电脑的SSH公匙,window ssh key搜索按步骤添加SSH公匙
安装git
git clone 项目地址
cd 文件夹路径
ll 列出目录列表
clear 清除
cat查看某个文件的内容
git status 查看文件状态
git branch 查看分支 master分支为主分支,默认分支
git diff 查看全部更改的内容(新增的文件不在内)
git diff 具体文件名 查看某个文件的内容
git add 文件名 提交某个文件
git add . 提交所有文件

2  Chrome调试工具

 

Elements:看DOM结构;

Console:打印一些东西;

Application:查看及操作本地存储,Local Storage、Session Storage、Cookies;

Network:所有资源的加载,查看不同类型资源加载的情况;

Sources:可打断点==debugger,进行调试

3 移动端h5 抓包

抓包工具:charles

4 webpack

基本使用 | 尚硅谷 Web 前端之 Webpack5 教程

5 ES6 模块化规范是什么

 

模块化,就是一个导出export,一个导入import的过程;

import解构赋值

import { fn, name , obj } from './a.js'

※如果只导出一个,并且不是通过解构赋值的方式来获取,就需要default -> export default xxx;

※如果到处多个,可以用多个export,并通过解构赋值的方式获取

 6 前端用到的 linux 常用命令有哪些

 

使用场景:

  • 公司的线上机器一般都是 linux(参考阿里云)

  • 测试机也需要保持一致,用 linux

  • 测试机或者线上机出了问题,本地又不能复现,需要去排查

常用命令:

  • ssh root@192.168.10.21 - 登录 linux 线上机器

  • ls / ll - 平铺/列表形式查看文件夹(隐藏文件看不到,linux 中 .开头的文件都是隐藏文件)

  • ls / ll -a - 平铺/列表形式查看全部文件夹

  • clear - 清屏

  • mkdir 文件夹名 - 创建文件夹

  • rm -rf 文件夹名 - 删除文件夹(r 递归删除,f 强制删除,不使用-rf 每删一个文件都会询问是否删除)

  • rm 文件名 - 删除单个文件

  • cd 文件夹名 - 进入文件夹

  • mv 文件名 新文件名 - 修改文件名(mv 后输入文件名可以按tab健 会自动填充)

  • mv 文件名 路径/文件名 - 移动文件(../ 表示上一层目录)

  • cp 文件名 新文件名 - 拷贝文件

  • touch 文件名 - 新建文件

  • vi 文件名 - 新建文件并打开(进入 vim 编辑器)

  • cat 文件名 - 查看文件全部内容

  • head 文件名 - 查看文件头部内容

  • tail 文件名 - 查看文件底部内容

  • grep 关键字 文件名 - 查看文件含有关键字的内容

vim编辑器:

  • 按 i键 - 启动INSERT(编辑)模式

  • 按 esc键 - 退出INSERT模式

  • :w - 保存写入

  • :q - 退出编辑器

  • :q! - 强制退出编辑器

网页是如何加载并渲染出来的

页面加载/渲染过程

加载资源的类型:

  • html 代码

  • 媒体文件,如图片、视频等

  • javascript、css

加载过程:

  • DNS 解析:域名 -> IP地址

    • IP地址很难记,域名更好记

    • IP地址在不同区域内可能是不同的(如大型网站如百度、淘宝等,对IP地址做了分区域的均衡和代理)

    • 基于前面两点,所以使用域名更好。既然使用域名,那么就需要DNS解析域名获取IP地址发送请求

  • 浏览器根据IP地址向服务器发起http请求

  • 浏览器处理http请求,并返回结果给浏览器

渲染过程:

  1. 根据 HTML代码 生成 DOM Tree

  2. 根据 CSS代码 生成 CSSOM (css对象模型)

  3. 将 DOM Tree 和 CSSOM 整合形成 Render Tree

  4. 根据 Render Tree 渲染页面

  5. 遇到 <script> 则暂停渲染,优先加载并执行 JS 代码,完成在继续

  6. 直至把Render Tree 渲染完成

  • 为何建议把 css 放在 <head> 中?

    html生成DOM Tree时,根据浏览器默认及现有CSS生成Render Tree来渲染页面,当遇到新的CSS的时候需要下载并结合现有CSS重新生成Render Tree

    但是如果把所有CSS都放到页面顶部,这样就没有重新渲染的过程了

    简而言之,就是为了避免重新渲染页面

  • 为何建议把 js 放在 body 最后?

    js可能会阻断渲染进程,使得页面渲染时间过长,从而影响页面加载速度

  • 为何 img 加载不会暂停渲染过程?

    因为img不会改变DOM结构,等加载完成根据图片尺寸大小,最多重排一下

  • window.onload 和 window.DOMContentLoaded的区别

    window.onload - 页面全部资源加载完才执行,包括图片、视频等

    DOMContentLoaded - DOM 渲染完即可执行,此时图片、视频可能没有加载完

8 性能优化

让加载更快:

  • 减少资源体积:压缩代码、压缩图片、(服务器GZIP压缩)

  • 减少访问次数:合并代码、SSR 服务器端渲染、http缓存

  • 使用更快的网络:CDN (CDN根据区域来做服务器处理)

让渲染更快:

  • CSS 放在 head ,JS 放在 body 最下面

  • 尽早开始执行 JS,用 DOMContentLoaded 触发

  • 懒加载(图片懒加载,上滑加载更多)

  • 对 DOM 查询进行缓存

  • 频繁 DOM 操作,合并到一起插入 DOM 解构

  • 节流 throttle、防抖 debounce

9 手写防抖、节流

概念:

  • 防抖:事件触发n秒后再执行回调,若在n秒内事件又被触发,则重新计时

  • 节流:在指定时间内,只能有一次触发事件的回调执行,若在单位时间内重复触发则不生效

应用场景:

  • 防抖:输入框输入(input)...

  • 节流:浏览器窗口变化(resize)、页面滚动(scroll)、拖拽(drag)...

防抖:        

function debounce(fn, delay) {
  let timer = null;
  return function () {
    if(timer) clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, arguments);
      timer = null;
    }, delay)
  }
}

节流:

function throttle(fn, delay) {
  let timer = null;
  return function () {
    if(timer) return;
    timer = setTimeout(() => {
      fn.apply(this, arguments);
      timer = null;
    }, delay)
  }
}

 10 常见的Web前端攻击方式有哪些?

 

1、XSS 跨站请求攻击;

 

就用 js 替换就行,例如:

const val = $input.val()

const newVal = val.replaceAll('<', '&lt;')

或者直接用工具https://www.npmjs.com/package/xss 

2、 XSRF跨站请求伪造;

XSRF 预防:

  • 使用 post 接口

  • 增加验证,例如:密码、短信验证码、指纹等

面试题总结 :

 

面试题实战

1、var 和 let const 的区别

var 是 ES5 语法,let const 是 ES6 语法
var 有变量提升,let const 没有
var 没有块级作用域,let const 有
var let 是变量且值可以修改,const 是常量且值不可以修改(值为引用类型另说)

2、typeof 返回哪些类型

值类型:string、number、boolean、undefined、symbol、bigInt
引用类型:object(typeof null === 'object', 原因:设计时二进制开头2位相同导致)
函数:function

3、列举强制类型转换和隐式类型转换

强制:Number、String、Boolean、parseInt、parseFloat、toString等
隐式:if、==、+(拼接字符/转为数字)、!、逻辑运算等

4、手写深度比较,模拟lodash isEqual

function isObject(obj) {return typeof obj === 'object' && obj !== null};
function isEqual(obj_1, obj_2) {
  if(!isObject(obj_1) || !isObject(obj_2)) return obj_1 === obj_2;
  if(obj_1 === obj_2) return true;
  
  const keys_1_len = Object.keys(obj_1).length;
  const keys_2_len = Object.keys(obj_2).length;
  if(keys_1_len !== keys_2_len) return false;
  
  for(let key in obj_1) {
    const res = isEqual(obj_1[key], obj_2[key])
    if(!res) return false;
  }
  
  return true;
}

5、split() 和 join() 的区别

split 为字符串方法,join 为数组方法
split 将字符串转为数组,join 将数组转为字符串

6、数组的 pop push unshift shift 分别做什么

pop - 删除最后一个元素,返回删除的元素
push - 在数组末尾添加元素,返回新数组长度
unshift - 在数组开头添加元素,返回新数组长度
shift - 删除第一个元素,返回删除的元素

pop、push、unshift、shift都会改变原数组

// 纯函数:1、不改变原数组(没有副作用)2、返回一个数组
// 如:concat、map、filter、slice

7、数组 slice 和 splice 的区别

slice 截取数组,但不会改变原数组,splice 增\删\改数组,会改变原数组
slice 参数可以为负值,splice 参数不能为负值
slice 返回截取的数组, splice 返回被删除元素数组

8、[10, 20, 30].map(parseInt) 的返回结果是什么

拆解:
  [10, 20, 30].map((item, index) => parseInt(item, index))
流程:
  [parseInt(10, 0), parseInt(20, 1), parseInt(30, 2)]
结果:
  [10, NaN, NaN] // parseInt 第二参数为进制为,传0则默认10转为10进制,1,2进制不存在返回NaN

9、ajax 请求 get 和 post 的区别

get 一般用于查询操作,post 一般用户提交操作
get 参数拼接在 url 后面,post 放在请求体内(数据体积可更大)
* 安全性:post 易于防止 CSRF

10、函数 call 和 apply 的区别

都是改变函数 this 指向,且会执行函数
call 传入多个参数,apply 第二参数接受一个参数数组或者类数组

11、事件代理(委托)是什么

基于事件冒泡,指定一个事件处理程序,就可以管理某一类型的所有事件,从而减少DOM交互提高性能

12、闭包是什么,有什么特性?有什么负面影响?

闭包:可以访问另一个函数作用域的函数
场景:函数作为参数被传递,函数作为返回值被返回
特性:函数引用的自由变量(不在函数里定义的变量)不会被销毁 // 自由变量查找在函数定义的地方,而不是调用的地方
影响:变量会常驻内存,得不到释放

13、如何阻止事件冒泡和默认行为?

阻止事件冒泡:event.stopPropagation()
阻止默认行为:event.preventDefault()

14、查找、添加、删除、移动 DOM 节点的方法?

查找(常用):
  document.getElementById()
  document.getElementsTagName()
  document.getElementsClassName()
  document.querySelector()
  document.querySelectorAll()
  
  element.parentElement
  element.children
  element.firstElementChild
  element.lastElementChild
  element.previousElementSibling
  element.nextElementSibling
添加:
  element.appendChild()
  element.insertBefore()
删除:
  element.removeChild()

移动

const p1 = document.getElementById('p1')
div2.appendChild(p1)

15、如何减少 DOM 操作?

缓存 DOM 查询结果
频繁插入DOM,使用 createDocumentFragment() , 统一插入DOM

16、解释 jsonp 原理,为何它不是真正的 ajax?

原理:浏览器有同原策略,script标签可以不受同源策略限制,js预先定义好接受函数,只要script请求的地址服务器返回js格式的内容,并在里面执行页面接受函数并将数据通过参数传递即可实现跨于传输数据

jsonp 是通过 script 标签来实现
ajax 是通过 XMLHttpRequest 来实现

17、document load  和 ready 的区别

load: window.onload // 页面全部加载完成才会执行,包括图片、视频等
ready: document.addEventListener('DOMContentLoaded') // DOM渲染完即可执行,此刻图片、视频可能还没加载完

18、== 和 === 的不同

== 类型不同会尝试转换类型再比较
=== 不会转换类型,先比较类型再比较值

19、函数声明和函数表达式的区别

函数声明:function xxx() {}
  可以在函数声明之前调用函数。
  不会报错,因为函数声明会在代码执行前预加载(类似变量提升)
  
函数表达式:xxx = function () {}
  表达式声明之前不能调用函数。
  有变量提升(var 声明),提升时变量初始为undefined, 调用会报错
  没有变量提升(let const 声明),声明前使用会报错

20、new Object() 和 Object.create() 的区别

new Object(value):
  如果value为基本数据类型String、Number、Boolean,则返回对应类型的对象。
  如果value本身为对象,则返回其本身。
  如果省略了value参数,或value为null、undefined,则返回自身无任何属性的Object对象,即返回一个空对象
  
Object.craete(proto,[propertiesObject]):
  创建一个新的对象,第一个参数为新对象的原型,第二参数不为空,则必须是一个对象否则报错
  第一个参数为空或null,则新对象没有原型
  第一个参数为Object.prototype,则等同 {}

21、字符串 字母开头,后面数字字母下划线,长度 6 - 30

const reg = new RegExp('^[a-zA-Z]\\w{5, 29}$');
const reg = /^[a-zA-Z]\w{5, 29}$/;

22、手写字符串 trim 方法,保证浏览器兼容性

String.prototype.trim = function () {
  return this.replace(/^\s+/, '').replace(/\s+$/, '')
}

23、如何获取多个数字中的最大值

一、函数方式
 function getMax() {
   return [...arguments].reduce((prev, item) => prev > item ? prev : item, 0)
 }
 
二、Math方式
 Math.max()

24、如何用 class 实现继承

class 形式:简单,使用 extends 实现
原型 形式:复杂,通过冒充、组合等实现

25、如何捕获 JS 程序中的异常?

try - cathch
  不适合全体使用,适合高风险地方使用
  
window.onerror = function (message, source, lineNum, colNum, error) {}
  适合全体使用,自动捕获异常
  对跨域的 js,如 CDN 不会有详细的报错信息
  对压缩的 js,需配合 sourceMap 反查找到未压缩代码的行、列

26、什么是 JSON?

json 是一种数据格式,本质是一段字符串
json 格式和 js 对象结构一致,对 js 语言更友好

27、获取当前页面的 url 参数

// 使用正则
  function query(key) {
    const search = location.search;
    const reg = new RegExp(`${key}\\=([^\\&\\#]+)`, i); // 括号为组匹配,第几个括号就是第几组
    const res = reg.exec(search); // 找到则返回数组,第一个为匹配字符串,之后为组匹配对应结果
    return res ? res[1] : res; // 第一个组匹配即对应所需值,所以索引为1
  }
  
// 使用URLSearchParams
  function query(key) {
    const search = location.search;
    cont params = new URLSearchParams(search);
    return params.get(key)
  }

28、将 url 参数解析为 JS 对象

// 传统
function queryToObj() {
  const str = location.search.substr(1);
  const res = {};
  res.split('&').forEach(paramStr => {
    const arr = paramStr.split('=');
    const key = arr[0];
    const val = arr[1];
    res[key] = val;
  })
  return res;
}

// 使用URLSearchParams
function queryToObj() {
  const pList = new URLSearchParams(location.search);
  const res = {};
  pList.forEach((val, key) => {
    res[key] = val;
  })
  return res;
}

29、手写数组 flatern(拍平),考虑多层级

arr.some 遍历数组中每个元素,判断其是否满足指定函数的指定条件,返回true或者false

concat是连接一个或多个数组

 返回的是连接后数组的一个副本

apply方法 将数组变成参数列表传参

function flat(arr) {
  const isDeep = arr.some(item => item instanceof Array);
  if(!isDeep) return arr;
  const res = Array.prototype.concat.apply([], arr);
  return flat(res);
}

30、数组去重

一、传统
function unique(arr) {
  const res = [];
  arr.forEach(item => {
    if(res.indexOf(item) < 0) res.push(item)
  })
  return res;
}

二、ES6
function unique(arr) {
  return [...new Set(arr)]
}

31、介绍一下 RAF requestAnimationFrame

使用js实现动画,想要动画流畅,更新频率要 60帧/s,即 16.67ms 更新一次视图(频率小动画不流畅,频率大浪费计算资源,人眼分辨不了)
通过 setTimeout 实现动画,需要手动控制(计算)频率,而 RAF 浏览器会自动控制
后台标签或隐藏 iframe 中,RAF 会暂停,而 setTimeout 依然执行
setTimeout 设计目的是为了异步而不是动画

如:3s 把 宽度 从 100px 变为 640px,即增加 540px
// 总帧数:60帧/s * 3s = 180帧
// 每帧增加长度:540 / 180 = 3px
const div = document.getElementById('div');
let curWidth = 100;
const maxWidth = 640;

// 使用定时器
function animate() {
  curWidth += 3;
  div.style.width = curWidth + 'px';
  if(curWidth < maxWidth) {
    setTimeout(animate, 16.7)
  }
}

// RAF
function animate() {
  curWidth += 3;
  div.style.width = curWidth + 'px';
  if(curWidth < maxWidth) {
    requestAnimationFrame(animate)
  }
}
animate();

32、Map 和 Set / 有序 和 无序 / Map 和 Object 区别/ Set 和 Array 区别

Map:
  有序数据结构,但操作快(核心价值)
  属性:size
  方法:set、get、delete、has、clear
  
Set:
  无序数据结构,不能重复
  属性:size
  方法:add、delete、has、clear
  
有序:操作慢但有序
无序:操作快但无序
两者优点结合:快且有序 - 二叉树、及其变种  

Map 和 Object 区别:
  API 不同
  Map 可以任意类型为 key,Object 只能 String 类型为 key
  Map 是有序结构但操作快,Object 是无序结构操作同样很快

Set 和 Array 区别:
  API 不同
  Set 元素不能重复,Array 元素可以重复
  Set 是无序结构操作很快,Array 是有序结构操作慢

js的Set与Map数据结构___0000z__的博客-CSDN博客一、Set方法是在写leetCode的时候使用了Set(无重复的情况)方便解题这里写目录标题一、Set方法Set的用法Set实例的属性与方法Set对象的遍历方法Set的用法1. Set是ES6提供的新的数据结构,类似于数组,但是值是唯一的,没有重复值。let set = new Set()set.add(1).add(2).add(2) // Set(2) {1, 2}2. Set函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。// 1.数组作为https://blog.csdn.net/qq_34853493/article/details/123795041?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166249021216800182714999%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166249021216800182714999&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-123795041-null-null.142%5Ev47%5Enew_blog_pos_by_title,201%5Ev2%5Econtrol&utm_term=js%20map%20set%20%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84&spm=1018.2226.3001.4187

33、WeakMap 和 WeakSet

都是弱引用,防止内存泄露
WeakMap 只能对象作为 key,
WeakSet 只能对象作为 value(必须为对象,是因为对象随时可能被销毁)
没有 forEach 和 Size(因为不知何时引用的值被销毁),只能用 add、delete、has

// WeakMap
const wMap = new WeakMap();
// const a = {}
function fn() {
  const obj = { name: 'xxx' };
  wMap.set(obj, 'name info'); - 弱引用
  // a.obj = obj; - 强引用
  console.log(wMap); // 有值
}
fn();
console.log(wMap); // 没有值,fn执行完成, wMap 是弱引用,obj 被销毁, 所以wMap其对应值也跟着被销毁
// console.log(a) // 有值,fn执行完成,a.obj 是强引用,obj 不能销毁,所以被保留

// 使用场景 - 需要双方产生关联,但又不想以对方属性的形式存在
const userInfo = { name: 'zs' };
const cityInfo = { city: 'ss' };
// userInfo.city = cityInfo // 导致 userInfo 多出一个属性 city
wMap.set(userInfo, cityInfo) // 建立联系,且两者保持独立
wMap.get(userInfo) // 获取 userInfo 的 city 信息


// WeakSet - 同WeakMap
const wSet = new WeakSet();
function fn() {
  const obj = { name: 'xxx' };
  wSet.add(obj); - 弱引用
  console.log(wSet); // 有值
}
fn();
console.log(wMap); // 没有值

ES6 --- WeakMap、WeakSet(弱映射和弱集合)_wincheshe的博客-CSDN博客_es6 weakmap13日 二月 2022WeakMap and WeakSet(弱映射和弱集合)我们从前面的 垃圾回收 文章中知道,JavaScript 引擎在值“可达”和可能被使用时会将其保持在内存中。例如:let john = { name: "John" };// 该对象能被访问,john 是它的引用// 覆盖引用john = null;// 该对象将会被从内存中清除通常,当对象、数组之类的数据结构在内存中时,它们的子元素,如对象的属性、数组的元素都被认为是可达的。例如,如果把一个对象放入到https://blog.csdn.net/m0_52409770/article/details/123093419?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166249174616782395315899%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=166249174616782395315899&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-4-123093419-null-null.142%5Ev47%5Enew_blog_pos_by_title,201%5Ev2%5Econtrol&utm_term=WeakMap%20%E5%92%8C%20WeakSet&spm=1018.2226.3001.4187

34 JS中 reduce() 的用法

arr.reduce(function(prev,cur,index,arr){
...
}, init);

arr 表示原数组;
prev 表示上一次调用回调时的返回值,或者初始值 init;
cur 表示当前正在处理的数组元素;
index 表示当前正在处理的数组元素的索引,若提供 init 值,则索引为0,否则索引为1;
init 表示初始值。

看上去是不是感觉很复杂?没关系,只是看起来而已,其实常用的参数只有两个:prev 和 cur。接下来我们跟着实例来看看具体用法吧~

1. 求数组项之和

var sum = arr.reduce(function (prev, cur) {
    return prev + cur;
},0);

由于传入了初始值0,所以开始时prev的值为0,cur的值为数组第一项3,相加之后返回值为3作为下一轮回调的prev值,然后再继续与下一个数组项相加,以此类推,直至完成所有数组项的和并返回。

2. 求数组项最大值

var max = arr.reduce(function (prev, cur) {
    return Math.max(prev,cur);
});

由于未传入初始值,所以开始时prev的值为数组第一项3,cur的值为数组第二项9,取两值最大值后继续进入下一轮回调。

3. 数组去重

var newArr = arr.reduce(function (prev, cur) {
    prev.indexOf(cur) === -1 && prev.push(cur);
    return prev;
},[]);

实现的基本原理如下:

① 初始化一个空数组
② 将需要去重处理的数组中的第1项在初始化数组中查找,如果找不到(空数组中肯定找不到),就将该项添加到初始化数组
③ 将需要去重处理的数组中的第2项在初始化数组中查找,如果找不到,就将该项继续添加到初始化数组
④ ……
⑤ 将需要去重处理的数组中的第n项在初始化数组中查找,如果找不到,就将该项继续添加到初始化数组
⑥ 将这个初始化数组返回

重点总结:

reduce() 是数组的归并方法,与forEach()、map()、filter()等迭代方法一样都会对数组每一项进行遍历,但是reduce() 可同时将前面数组项遍历产生的结果与当前遍历项进行运算,这一点是其他迭代方法无法企及的

列举优化网络性能方法

    

优化打包体积

利用一些工具压缩、混淆最终打包代码,减少包体积

多目标打包

利用一些打包插件,针对不同的浏览器打包出不同的兼容性版本,这样一来,每个版本中的兼容性代码就会大大减少,从而减少包体积

压缩

现代浏览器普遍支持压缩格式,因此服务端的各种文件可以压缩后再响应给客户端,只要解压时间小于优化的传输时间,压缩就是可行的

CDN

利用 CDN 可以大幅缩减静态资源的访问时间,特别是对于公共库的访问,可以使用知名的 CDN 资源,这样可以实现跨越站点的缓存

缓存

对于除 HTML 外的所有静态资源均可以开启协商缓存,利用构建工具打包产生的文件 hash 值来置换缓存

http2

开启 http2 后,利用其多路复用、头部压缩等特点,充分利用带宽传递大量的文件数据

雪碧图

对于不使用 HTTP2 的场景,可以将多个图片合并为雪碧图,以达到减少文件的目的

defer、async

通过 defer 和 async 属性,可以让页面尽早加载 js 文件

prefetch、preload

通过 prefetch 属性,可以让页面在空闲时预先下载其他页面可能要用到的资源

通过 preload 属性,可以让页面预先下载本页面可能要用到的资源

多个静态资源域

对于不使用 HTTP2 的场景,将相对独立的静态资源分到多个域中保存,可以让浏览器同时开启多个 TCP 连接,并行下载
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值