自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(149)
  • 收藏
  • 关注

原创 模拟实现构造函数new的过程 js

用new操作符创建对象时发生的事情:(1)创建一个新对象;(2)将构造函数的作用域赋给新对象(因此this就指向了这个新对象);(3)执行构造函数中的代码(为这个新对象添加属性和方法);(4)返回新对象;function myNew(constructor, params) { var args = [].slice.call(arguments); //将具有length属性的arguments转换为数组 var constructor = args.shift()

2020-11-27 18:13:02 7

原创 使用原生的JavaScript实现ajax请求(ajax实现原理)

Ajax 是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。XMLHttpRequest 对象XMLHttpRequest对象是ajax的基础,XMLHttpRequest 用于在后台与服务器交换数据。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。目前所有浏览器都支持XMLHttpRequest。var xhr = new XMLHttpRequest()

2020-11-27 16:10:08 7

原创 嵌套数组指定层次展开 flat扁平化 js

数组的扁平化即为将一个嵌套多层的数组转换为只有一层的数组。[1, [2]] => [1,2][[1, 2], [3, 4]] => [1, 2, 3, 4][1, 2, [3, 4, [5, 6]]] => [1, 2, 3, 4, 5, 6]方法一:递归思路:通过遍历最外层数组的每一个元素,看看是否还是数组,如果是的话,继续递归执行,不是的话,放到最后的结果数组当中。// 1. 普通方法 递归function flattenMd1() { let.

2020-11-23 21:59:37 15

原创 模拟实现函数节流(throttling)、防抖(debounce) js

防抖(debounce)所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。效果:如果短时间内大量触发同一事件,只会执行一次函数。实现:既然前面都提到了计时,那实现的关键就在于这个函数,由于还需要一个变量来保存计时,考虑维护全局纯净,可以借助闭包来实现:function debounce(fn, delay) {//防抖 // 定义一个定时器timer,用来记录当前执行函数状态(借助闭包) let timer = null

2020-11-23 15:09:20 12

原创 DP 斐波那契数列js NC68

斐波那契数指的是这样一个数列:0、1、1、2、3、5、8、13、21、…… 用数学公式表示为:简单的来说就是 后一项是前两项之和。方法一:递归时间复杂度:O(n^2),空间复杂度:O(n)// 递归法function Fibonacci(n) { if (n < 2) { return n; } else { return Fibonacci(n - 1) + Fibonacci(n - 2); }}由.

2020-11-20 09:54:37 12

原创 二叉树中是否存在节点和为指定值的路径 NC9

给定一个二叉树和一个值\ sumsum,判断是否有从根节点到叶子节点的节点值之和等于\ sumsum的路径,例如:给出如下的二叉树,sum=22返回true,因为存在一条路径5→4→11→2 的节点值之和为 22。思路分成三种情况,(1)节点不存在,返回false(2)节点只有一个的时候,判定是否左子和右子均为空,且sum值等于该节点值(3)递归的具体操作,递归左子和右子,同时更新sum的值,且结果为或的关系var hasPathSum = function (root, s...

2020-11-18 16:07:59 12

原创 二叉树(最大)深度js NC13

最大深度是指树的根结点到最远叶子结点的最长路径上结点的数量。树的深度 = 左子树的深度和右子树深度中最大者 + 1function TreeDepth(pRoot) { //树的深度=左子树的深度和右子树深度中最大者+1 if (pRoot === null) return 0; var leftDep = TreeDepth(pRoot.left); var rightDep = TreeDepth(pRoot.right); return

2020-11-18 14:58:42 12

原创 二叉树各种遍历(前中后序遍历,递归非递归,DFS,BFS)js

树的中序遍历(非递归)思路:先将p入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为p,出栈,访问p.val,再中序遍历p的右子树。

2020-11-18 14:26:14 60

原创 两个链表的第一个公共节点 NC66

方法一:双指针假设两个链表公共长度为C,不公共的长度分别为A、B。则两个链表长度分别为A+C,B+C。设两个指针,让第一个链表走完之后,跳到第二个链表开始走,共A+C+X1距离;同理第二个链表走完后调到第一个链表开始走,走B+C+X2距离。那么两个指针相遇时,由 A+C+X1 = B+C+X2,距离不为负,得X1=B,X2=A,所以最后两个指针走的距离都是A+B+C,刚好在第一个公共点相遇。复杂度分析时间复杂度 : O(m+n)空间复杂度 : O(1)//双指针var ge..

2020-11-11 17:02:29 18

原创 环形链表第一个入环节点 NC3

思路:1)首先判断是否有环,有环时,返回相遇的节点,无环,返回null2)有环的情况下, 求链表的入环节点 fast再次从头出发,每次走一步, slow从相遇点出发,每次走一步, 再次相遇即为环入口点。证明:快指针与慢指针均从X出发,在Z相遇。此时,慢指针行使距离为a+b,快指针为a+b+n(b+c)。所以2*(a+b)=a+b+n*(b+c),推出a=(n-1)*b+n*c=(n-1)(b+c)+c;得到,将此时两指针分别放在起始位置和相遇位置,...

2020-11-10 20:06:09 44

原创 判断链表是否有环 NC4

思路:快慢指针用一快一慢指针,开始两个指针都指向链表头部。慢指针每次向前走一步,快指针每次向前走两步。如果有环,则两个指针最终一定会相遇。这种方法无须额外的空间。//给定一个链表,判断链表中是否有环。var hasCycle = function(head) { if(!head || !head.next) return false let slow = head let fast = head.next while(slow != fas

2020-11-10 10:44:25 16

原创 判断链表是否为回文链表 NC96

方法一:利用数组(栈)遍历链表,用数组把数据存下来,然后再进行一次遍历,同时用数组反向地与之比较,这样就可以判断是否回文。这个方法时间复杂度是O(n)pop() 移除数组的最后一项,返回移除的项 shift() 移除数组的第一项,返回移除项var isPalindrome = function (head) { let nums = []; while (head) { nums.push(head.val); head = head.ne...

2020-11-09 13:56:38 17

原创 寻找链表倒数第K个节点 (NC69)/ 删除链表倒数第N个节点(NC53)

第一种方法是先循环一遍链表确定结点个数n,则倒数第k个结点就是就是正数的第n+1-k个,然后在遍历一次链表就可以找到指定结点了,但显然需要遍历两遍链表。第二种方法可以使用两个指针,第一个指针先走k-1步,然后第二个指针开始走。当第一个指针移动到最后时,第二个指针正好指向倒数第k个结点,只需要遍历一遍链表,显然更高效。...

2020-11-08 14:25:14 12

原创 划分链表(Partition List)

对于一个链表,我们需要用一个特定阈值完成对它的分化,使得小于等于这个值的结点移到前面,大于该值的结点在后面,同时保证两类结点内部的位置关系不变。思路:采用双指针思想,维护node1指针作为前面的插入指针,node2作为后面的删除指针。此时分为两种情况:若链表首节点值大于或等于给定值,首先找到其后第一个小于给定值的节点删除并插入到 node2 之前作为头节点,并令 node1 指向它,然后将 node2 指向原删除节点的下一个节点 若链表首节点值小于给定值,那么首先找到从左往右第一个大于或等于给

2020-11-07 16:10:04 28

原创 单链表删除节点

//给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。//返回删除后的链表的头节点。

2020-11-07 11:09:50 35

原创 链表去重(删除重复元素)

未排序链表去重 O(n^2)思路:第一重循环从链表的头节点开始,枚举一个保留的节点,这是因为我们保留的是「最开始出现的节点」。第二重循环是枚举「最开始出现的节点」的下一个结点,到链表的末尾结束,将所有与保留节点相同的节点全部移除。//移除未排序链表中的重复节点。保留最开始出现的节点。(两层循环)//输入:[1, 2, 3, 3, 2, 1]//输出:[1, 2, 3]var removeDuplicateNodes = function (head) { var slow =

2020-11-03 18:26:23 48

转载 反转单链表

现在有一个单向链表如下图所示:反转后如下所示:/** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; * } *//** * @param {ListNode} head * @return {ListNode} */var reverseList = function(head) { //le

2020-11-03 13:48:16 26

原创 数组去重(至少两种方法)js

方法1:普通版,利用indexOf去重新建一个数组,遍历去要重的数组,当值不在新数组的时候(indexOf为-1)就加入该新数组中。indexOf() 方法:返回某个指定的字符串值在字符串中首次出现的位置。如果要检索的字符串值没有出现,则该方法返回 -1。//方法1:普通版,利用indexOf去重function arrayUnique(arr){ var len = arr.length; var res = []; for(var i = 0; i < len

2020-11-02 22:37:11 20

原创 数组乱序(打乱数组,至少两种方法)js

数组随机排序(shuffle)方法1:时间复杂度 O(n^2)// 方法2:随机抽取法, 时间复杂度 O(n^2)function randomSortArray(arr) { let backArr = []; while (arr.length) { //Math.random():返回 [0,1) 之间的一个随机数 let index = parseInt(Math.random() * arr.length); // 利用数组长度生成随机

2020-11-02 13:47:27 106 1

原创 字符串逆序(翻转整数字符串)js

11

2020-11-02 10:09:56 14

原创 二分查找(非递归/递归)js

二分查找(折半查找),是一种在有序数组中查找特定元素的搜索算法。查找过程可以分为以下步骤:(1)首先,从有序数组的中间的元素开始搜索,如果该元素正好是目标元素(即要查找的元素),则搜索过程结束,否则进行下一步。(2)如果目标元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半区域查找,然后重复第一步的操作。(3)如果某一步数组为空,则表示找不到目标元素。非递归算法:// 非递归算法function binary_search1(nums, target) { var

2020-11-01 22:03:28 11

原创 js排序算法:冒泡、选择、插入、快排★★★ 归并★

一、冒泡排序算法描述如下: 1.比较相邻的两个元素,如果前一个比后一个大,则交换位置。2.第一轮的时候最后一个元素应该是最大的一个。3.按照步骤一的方法进行相邻两个元素的比较,这个时候由于最后一个元素已经是最大的了,所以最后一个元素不用比较。算法实现:/*** @Author spring* @DateTime 2020-10-29* @param {arr} 待数组* @return {arr} 排好序的数组* @description 这是一个冒泡排序算..

2020-11-01 12:15:51 15

原创 圣杯布局和双飞翼布局

圣杯布局<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>圣杯布局</title> <style> body {

2020-10-01 16:20:23 56

转载 Vue的样式绑定

一、绑定class1. 第一种:样式和数据的绑定,通过对象方式{ }v-bind:class设置一个对象。当isActivated为true的时候,div上会增加一个class属性,属性名称为activated,如果再在css里加上activated类的样式,则会有CSS效果了;如果isActivated为false,则没有class属性。在函数中使当前状态取反做到来回切换。2.第二种方式:通过数组方式,v-bind:class设置一个数组。class里面存放的是一个数组,我们最开始在da.

2020-09-22 19:36:46 20

原创 Vue中watch、computed和methods的区别

watch和computed的区别watch和computed都是对数据的监听只有数据发生变化时才会触发,但是他们擅长的领域不一样watch更擅长一对多:就是主要监听一个可以影响多个数据的数据computed擅长多对一:主要监听多个数据影响一个数据的数据,一定要return组合出的那个数据会自动定义不用在data中再次定义,当然也可以使用watch来监听组成computed所监听数据的每一个数据,但是这样代码的重复率过高### watchvar vm = new Vue({ el: '

2020-09-22 15:51:30 32

转载 将Vue页面导出为pdf格式并进行下载

1.使用npm下载两个插件a.将html页面转换成图片npm install --save html2canvas b.将图片生成pdfnpm install jspdf --save2.在utils文件夹中创建一个名字叫个htmlToPdf.js的文件,内容如下:// 导出页面为PDF格式import html2Canvas from 'html2canvas'import JsPDF from 'jspdf'export default{ install (Vue, o

2020-08-19 17:01:15 218

原创 Less和Sass的区别

背景CSS(层叠样式表)是一门非程序式语言,入门学习使用非常直观方便,但是对于一些比较复杂或者重用性比较强的项目来说,因为CSS没有变量、函数、SCOPE(作用域),需要书写大量看似没有逻辑的代码,不方便维护及扩展,不利于复用,尤其对于非前端开发工程师来讲,往往会因为缺少CSS编写经验而很难写出组织良好且易于维护的CSS代码。为了方便前端开发的工作量,出现了Sass和 Less。简介SASS(英文全称:Syntactically Awesome Stylesheets),使用R...

2020-08-17 17:00:13 80

原创 浏览器解析渲染页面过程

答案: 解析HTML,生成DOM树 解析CSS,生成CSSOM树 将DOM树和CSSOM树关联,生成渲染树(Render Tree) 布局render树(Layout/reflow),负责各元素尺寸、位置的计算 绘制render树(paint),绘制页面像素信息 将像素发送给GPU,展示在页面上。(Display) ...

2020-06-22 11:13:48 105

转载 前后端分离与前后端不分离的区别

前后端不分离 在前后端不分离的应用模式中,前端页面看到的效果都是由后端控制,由后端渲染页面或重定向,也就是后端需要控制前端的展示,前端与后端的耦合度很高。请求的数据交互如下图:前后端分离在前后端分离的应用模式中,后端仅返回前端所需的数据,不再渲染HTML页面,不再控制前端的效果。至于前端用户看到什么效果,从后端请求的数据如何加载到前端中,都由前端自己决定,网页有网页的处理方式,App有App的处理方式,但无论哪种前端,所需的数据基本相同,后端仅需开发一套逻辑对外提供数据即可。...

2020-05-26 22:32:56 268

原创 for in与for of用法及区别

for in遍历的是数组的索引(即键名),而for of遍历的是数组元素值。for-in总是得到对象的key或数组、字符串的下标。for-of总是得到对象的value或数组、字符串的值,另外还可以用于遍历Map和Set。var arr=[{name:'张三'},{name:'李四'}];for (var i in arr){ console.log(i)}for (var i of arr){ console.log(i)}结果:...

2020-05-26 19:18:47 266

原创 EventLoop

答案:了解几个概念:调用栈、同步/异步任务、宏任务/微任务JavaScript本身是单线程,也就是同一时刻只能干一件事,JS任务包含了同步任务和异步任务,遇到执行函数会将其放入调用栈(先进后出)中,遇到setTimeout/setInterval等异步任务时,会把它放入到消息队列中,等主线程的任务执行完成以后,再回过头执行消息队列中的异步任务,如果异步任务中仍然有异步任务,会继续放入消息队列,以此类推,便形成了一个事件循环。异步任务: setTimeout setInterv

2020-05-22 09:10:41 132

转载 观察者和发布订阅者区别

答案:他们都属于观察者模式,只不过有不同的实现方法。发布订阅相比于观察者多了一个调度中心,发布者通过调度中心向订阅者发布消息。观察者模式中目标和观察者相互依赖,观察者订阅目标主题,当目标发生变化后,会通知对应观察者。详细解析:设计模式的定义是:在面向对象软件设计过程中针对特定问题的一种解决方案。设计模式并不直接用来完成代码的编写,而是描述在各种不同情况下,要怎么解决问题的一种方案,他不是一个死的机制,他是一种思想,一种写代码的形式。观察者模式(Observer Pattern).

2020-05-20 10:39:20 204

原创 call/apply/bind作用和区别

答案:他们都可以改变函数的作用域。 call/apply 可以直接执行该函数,而 bind 不会立刻执行 fucntion.bind(thisArg, arg1, arg2, ...) call/apply 作用类似,都可以改变指针和执行函数,区别在于传参不同,call 需要单个传参,apply 通过数组传参 function.call(thisArg, arg1, arg2, ...)function.apply(thisArg, [arg1, arg2, ...]).

2020-05-19 14:06:29 242 1

转载 DOM节点创建和修改有哪些常用API

答案:创建节点 createElement createTextNode createDocumentFragment(临时节点) 修改节点 appendChildparent.appendChild(child) insertBeforeparentNode.insertBefore(newNode,refNode); removeChildparent.removeChild(node) replaceChild 详细...

2020-05-18 11:10:08 136

原创 slice和splice区别

答案:slice表示截取,slice(start,end),不改变原数组,返回新数组。splice表示删除,splice(start,length,item),会改变原数组,从某个位置开始删除多个元素,并可以插入新的元素。详细解析:slice():从已有的数组中返回你选择的某段数组元素语法:arrayObject.slice(start,end)①:start表示从何处开始选取,end表示从何处开始结束选取,表示一个选取的范围②:start可以为负数,此时它规定从数组尾部开.

2020-05-17 13:24:14 154

原创 数组有哪些常用方法

答案: push 末尾添加 pop 末尾删除 shift 首部删除 unshift 首部添加 concat 数组合并 join 数组元素 通过连接符 连接 reverse 数组反转 sort 数组排序 map/forEach/filter/indexOf/includes/slice/splice 详细解析:1. Array.push(),向数组的末尾添加一个或多个元素,并返回新的数组长度。原数组改变。.

2020-05-17 11:30:52 165

原创 如何准确判断一个对象是数组

答案:Object.prototype.toString.call([]) 返回 "[object Array]"扩展答案 [].slice (能力判断 ) [] instanceof Array(类型判断) [].proto=== Array.prototype Array.isArray([]) 存在兼容问题 数组也是引用类型,通过 typeof 依然返回 object详细解析:背景 —— typeof {}和typeof []的结果都是o..

2020-05-16 11:17:46 118

原创 什么是深/浅拷贝,有哪些实现方式

答案:JS数据类型分为基本数据类型和引用数据类型,基本数据类型保存的是值,引用类型保存的是引用地址(this指针)。浅拷贝共用一个引用地址,深拷贝会创建新的内存地址。浅拷贝方法 直接对象复制 Object.assign 深拷贝 JSON.stringify转为字符串再JSON.parse 深度递归遍历 详细解析:基本数据类型:string、number、boolean、undefined、null引用数据类型:object、array、funct.

2020-05-15 14:41:18 106

原创 js继承有哪些方法

答案: 原型继承 构造继承 实例继承 call/apply继承(组合继承) ES6 使用class extends继承 详细解析:父类Animal//父类function Animal(name){ this.name = name; this.sum = function() { alert(this.name); }}Parent.prototype.age = 10; //给原型对象添加属.

2020-05-14 14:09:30 46

原创 如何理解JS中的闭包及其优缺点

答案:简单理解就是函数中嵌套函数。我们都知道局部变量我们是无法访问的,但是通过闭包可以做到。// 正常访问var lan = 'zh';function hello(){ var name = '前端';}console.log(name) //很明显'undefined'// 换成闭包function hello(){ var name = '前端'; function demo(){ console.log(name) //打印:前端 }

2020-05-13 14:13:53 106

空空如也

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人 TA的粉丝

提示
确定要删除当前文章?
取消 删除