八股文(二)
一、 实现深拷贝和浅拷贝
1.深拷贝
function checkType(any) {return Object.prototype.toString.call(any).slice(8, -1)
}//判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝
//如果获得的数据是可遍历的,就拿到对应的value,实现深拷贝
function clone(any){if(checkType(any) === 'Object') { // 拷贝对象let o = {};//遍历for(let key in any) {o[key] = clone(any[key])}return o;} else if(checkType(any) === 'Array') { // 拷贝数组var arr = []//遍历for(let i = 0,leng = any.length;i<leng;i++) {arr[i] = clone(any[i])}return arr;} else if(checkType(any) === 'Function') { // 拷贝函数return new Function('return '+any.toString()).call(this)} else if(checkType(any) === 'Date') { // 拷贝日期return new Date(any.valueOf())} else if(checkType(any) === 'RegExp') { // 拷贝正则return new RegExp(any)} else if(checkType(any) === 'Map') { // 拷贝Map 集合let m = new Map()any.forEach((v,k)=>{m.set(k, clone(v))})return m} else if(checkType(any) === 'Set') { // 拷贝Set 集合let s = new Set()for(let val of any.values()) {s.add(clone(val))}return s}return any;
}
2.浅拷贝
function shallowCopy(src) {var dst = {};for (var prop in src) {//只要还没读完就继续读,读到的话就直接把属性名返回就行,没有进入深层//hasOwnProperty:是用来判断一个对象是否有你给出的名称的属性或对象。有则返回true,没有返回false,不过需要注意的是,此方法无法检查该对象的原型链中是否具有该属性,该属性必须是对象本身的一个成员。if (src.hasOwnProperty(prop)) {dst[prop] = src[prop];}}return dst;
}
二、 讲一下event loop
事件循环是js引擎执行js的机制,用来实现js的异步特性。事件循环的过程为:当执行栈空的时候,就会从任务队列中,取任务来执行。共分3步:
-
取一个宏任务来执行。执行完毕后,下一步。
-
取一个微任务来执行,执行完毕后,再取一个微任务来执行。直到微任务队列为空,执行下一步。
-
更新UI渲染。
1.EventLoop概念
Event Loop即事件循环,是指浏览器或Node的一种解决javaScript单线程运行时不会阻塞的一种机制,也就是我们经常使用异步的原理。
因为JavaScript就是单线程,也就是说,同一个时间只能做一件事。单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。
所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)
2.同步任务和异步任务
同步任务:函数返回—>拿到预期结果 异步任务:函数返回—>拿不到预期结果,还要通过一定的手段获得结果 简单点说 : 同步任务:会立即执行的任务 异步任务:不会立即执行的任务(异步任务又分为宏任务与微任务)
在异步任务中,任务被分为两种,一种宏任务(MacroTask)也叫Task,一种叫微任务(MicroTask)。
宏任务:由宿主对象发起的任务(setTimeout)。宏任务(定时器)包括 script, setTimeout,setInterval,setImmediate(Node.js),I/O,postMessage, MessageChannel,UI rendering(即I/O、定时器、事件绑定、ajax)
微任务:由js引擎发起的任务(promise)。微任务包括 process.nextTick(Node.js),promise.then(),promise.catch(),MutationObserver。(即Promise的then、catch、finally和process的nextTick)
注意:Promise的then等方法是微任务,而Promise中的代码是同步任务,并且,process的nextTick的执行顺序优先于Promise的then等方法,因为process.nextTick是直接告诉浏览器说要尽快执行,而不是放入队列
3.同步任务
当有多个同步任务时,这些同步任务会依次入栈出栈,如下图
同步任务1先入栈,执行完之后,出栈,接着同步任务2入栈,依此类推
4.异步任务
异步任务会在同步任务执行之后再去执行,那么如果异步任务代码在同步任务代码之前呢?在js机制里,存在一个队列,叫做任务队列,专门用来存放异步任务。也就是说,当异步任务出现的时候,会先将异步任务存放在任务队列中,当执行完所有的同步任务之后,再去调用任务队列中的异步任务
例如下图,现在存在两个同步任务,两个异步任务
js会先将同步任务1提至主线程,然后发现异步任务1和2,则将异步任务1和2依次放入任务队列
然后同步任务1执行完之后出栈,又将同步任务2入栈执行
当同步任务2执行完之后,再从任务队列中提取异步任务执行
5.总结
js中,微任务总是先于宏任务执行,也就是说,这三种任务的执行顺序是:同步任务>微任务>宏任务
6.案例
<script>console.log(1);setTimeout(function(){console.log(2)},0)new Promise((resolve,reject)=>{console.log(3)resolve()console.log(4)}).then(()=>{console.log(5)})console.log(6)
</script>
三、 js如何判断一个变量是数组
判断变量的类型是最经常使用的方法,但是判断的方式有很多
1.typeof
var ary = [1,2,3,4];
console.log(typeof ary); // 输出‘object’
很明显,typeof只能检测基本数据类型,并不能检测出来是否为数组。
2.instanceof
var ary = [1,2,3,4];
console.log(ary instanceof Array); //输出true
看起来挺好使的,实际上也确实挺好使的,但是要求变量必须在当前页面声明。
3.原型链
var ary = [1,2,3,4];
console.log(ary.__proto__.constructor==Array); //输出true
console.log(ary.constructor==Array) //输出true
两种方法都一样,但是在IE中“proto”没有定义。这种方法也存在和“instanceof”一样的问题,必须先声明变量。
4.isArray
let a = [2,543,32];
console.log(Array.isArray(a));//true
必须先声明变量
5.完美方法
var arr = [1,2,3,4];
console.log(Object.prototype.toString.call(arr)) //输出"[object Array]"
为了使用简便,我们可以封装成一个函数。
var ary = [1,2,3,4];
function isArray(o){
return Object.prototype.toString.call(o)=='[object Array]';
}
console.log(isArray(ary));
当然,这种方法不仅仅可以用来判断是否为数组,其他的也同样适用。
console.log(Object.prototype.toString.call(123)) //[object Number]
console.log(Object.prototype.toString.call('123')) //[object String]
console.log(Object.prototype.toString.call(undefined)) //[object Undefined]
console.log(Object.prototype.toString.call(true)) //[object Boolean]
console.log(Object.prototype.toString.call({})) //[object Object]
console.log(Object.prototype.toString.call([])) //[object Array]
console.log(Object.prototype.toString.call(function(){})) //[object Function]
四、 JavaScript数据类型
JavaScript共有八种数据类型,分别是 Undefined、Null、Boolean、Number、String、Object、Symbol、BigInt
其中 Symbol 和 BigInt 是ES6 中新增的数据类型:
Symbol 代表创建后独一无二且不可变的数据类型,它主要是为了解决可能出现的全局变量冲突的问题。 BigInt 是一种数字类型的数据,它可以表示任意精度格式的整数,使用 BigInt 可以安全地存储和操作大整数,即使这个数已经超出了 Number 能够表示的安全整数范围。 这些数据可以分为原始数据类型和引用数据类型:
栈:原始数据类型(Undefined、Null、Boolean、Number、String) 堆:引用数据类型(对象、数组和函数)
五、 柯里化
1. 什么是函数柯里化
函数柯里化就是我们给一个函数传入一部分参数,此时就会返回一个函数来接收剩余的参数。 柯里化是一种函数的转换。是指将一个函数从可调用的 f(a, b, c)
转换为 f(a)(b)(c)
2. 简单的柯里化的实现
没有柯里化的实现
将其转化为柯里化的案例
上述代码可简写为
3.函数柯里化的好处
我们希望处理函数时,希望函数功能尽可能单一。如下面代码所示,我们希望第一个参数+2
,第二个参数*2
,第三个参数** 2
,最后再相加,此时我们可以使用函数的柯里化
function makeAdder(count) {return function(num) {return count + num}
}
// 在之后使用返回的函数时,我们不需要再继续传入count 了
var adder5 = makeAdder(5)
adder5(10)
adder5(14)
adder5(1100)
adder5(555)
4.柯里化的优点
柯里化是使函数变得更具体些,即作用范围更小
5.传入函数的柯里化执行
function currying(fn, ...rest) {return function(...args) {//...rest=3,4//...args=1,2return fn(...rest, ...args);}
}
function sum(a, b, c, d) {console.log(a + b + c + d)
}
//传入sum,即currying(fn,...rest)解析成sum,1,2
//add是接收currying返回的函数
const add = currying(sum, 1, 2);
//add(3,4)即function(3,4),这个function是sum(3,4),所以add(3,4)就会执行最后那个sum四个数相加的函数
add(3, 4);
// 执行结果
10
function add(a, b, c, d) {console.log(a + b + c + d);
}
const curriedAdd = currying(add);
//接收curry()()()()
curriedAdd(1)(2)(3)(4); // 10
curriedAdd(1, 2, 3)(4); // 10
curriedAdd(1, 2, 3, 4); // 10
function currying(fn) {
//一开始,curriedAdd传入一个参数1,len=add参数长度4const len = fn.length;
//_args=[]let _args = [];const curry = () => {
//...args=1return function (...args) {
//_args.length=0,args.length=1,小于len=4// 如果参数攒够了就执行if (_args.length + args.length >= len) {const result = fn(..._args, ...args);// 执行完重置_args_args = [];return result;}// 参数不够就继续攒else {//_args=[..._args,...args]=[1]_args = [..._args, ...args];//curriedAdd(1)返回值是一个curry函数,以此类推return curry();}}}return curry();
}
六、 如何理解闭包,为什么有这种特性?为什么需要闭包?闭包的缺点?
(1)什么是闭包?
闭包就是能够读取其他函数内部变量的函数。
由于在javascript中,只有函数内部的子函数才能读取局部变量,所以说,闭包可以简单理解成“定义在一个函数内部的函数“。
所以,在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
(2)如何生成闭包?
函数嵌套 + 内部函数被引用。
function outer() {var a = 1;function inner() {console.log(a);}return inner;
}
//这里的闭包就是返回的inner函数
var b = outer();
(3)闭包作用?
-
可以让内部的函数访问到外部函数的变量,避免变量在全局作用域中存在被修改的风险
-
可以读取函数内部的变量
-
让这些变量的值始终保持在内存中,不会在f1调用后被自动清除
(4)使用闭包的注意事项?
不用的时候解除引用,避免不必要的内存占用。
为什么有闭包的这种特性:如果形成闭包,外部函数执行完后,其中的局部变量可能被内部函数使用,所以不能销毁,因此内部函数能一致访问到这些局部变量,直到引用解除。
(5)闭包的优点?
-
隐藏变量,避免放在全局有被篡改的风险。
-
方便调用上下文的局部变量
(6)闭包的缺点?
-
使用时候不注意的话,容易产生内存泄漏。
-
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除
相关文章:
八股文(二)
一、 实现深拷贝和浅拷贝 1.深拷贝 function checkType(any) {return Object.prototype.toString.call(any).slice(8, -1) }//判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝 //如果获得的数据是可遍历的&#…...
在CANoe/CANalyzer中观察CAN Message报文的周期Cycle
案例背景: 该篇博文将告诉您,如何直观的,图示化的,查看CAN网络中各CAN Message报文的周期变化。 优质博文推荐阅读(单击下方链接,即可跳转): Vector工具链 CAN Matrix DBC CAN M…...
Linux命令·ls
ls命令是linux下最常用的命令。ls命令就是list的缩写缺省下ls用来打印出当前目录的清单如果ls指定其他目录那么就会显示指定目录里的文件及文件夹清单。 通过ls 命令不仅可以查看linux文件夹包含的文件而且可以查看文件权限(包括目录、文件夹、文件权限)查看目录信息…...
Mysql InnoDB 存储引擎笔记
1 存储引擎 简介 Mysql 存储引擎有多种:包括 MyISAM、InnoDB 和 Memory。 其中MyISAM 和 INNODB 的区别: 事务安全(MyISAM不支持事务,INNODB支持事务);外键 MyISAM 不支持外键, INNODB支持外…...
智慧工地AI视频分析系统 opencv
智慧工地AI视频分析系统通过pythonopencv网络模型图像识别技术,智慧工地AI视频分析算法自动识别现场人员穿戴是否合规。本算法模型中用到opencv技术,OpenCV基于C实现,同时提供python, Ruby, Matlab等语言的接口。OpenCV-Python是OpenCV的Pyth…...
小红书「高效达人筛选攻略」
三八女神节降临,诸多品牌纷纷开启铺垫预热,在各大平台借势宣传。而聚集庞大年轻女性消费群体的小红书,对“她营销”的重要性不言而喻。节点序幕拉开,面对海量达人信息,如何提前积草屯粮、高效备战? 本期千瓜…...
大话数据结构-线性表
1 定义 线性表是零个或多个数据元素的有限序列。 2 抽象数据类型 ADT 线性表(List)Data:线性表的数据对象集合为{al,a2,a3,....an},每个元素的类型均为DataType。其中,除第一个元素a1外,每一个元素有且只有一个直接前驱元素&…...
分布式缓存 Memcached Linux 系统安装
1.Memcached简介 Memcached是一个开源、高性能,将数据分布于内存中并使用key-value存储结构的缓存系统。它通过在内存中缓存数据来减少向数据库的频繁访问连接的次数,可以提高动态、数据库驱动之类网站的运行速度。 Memcached在使用是比较简单的&#…...
【数据结构】链表:看我如何顺藤摸瓜
👑专栏内容:数据结构⛪个人主页:子夜的星的主页💕座右铭:日拱一卒,功不唐捐 文章目录一、前言二、链表1、定义2、单链表Ⅰ、新建一个节点Ⅱ、内存泄漏Ⅲ、插入一个节点Ⅳ、销毁所有节点Ⅴ、反转一个链表3、…...
linux shell 入门学习笔记18 函数开发
概念 函数就是将你需要执行的shell命令组合起来,组成一个函数体。一个完整的函数包括函数头和函数体,其中函数名就是函数的名字。 优点 将相同的程序,定义,封装为一个函数,能减少程序的代码数量,提高开发…...
如何最巧妙回答HR面试“送命题”:你为什么离开上家公司?
一 HR面试存在“送命题”? 一个资深HR朋友聊到,他最近pass掉一个名校高材生。 其实洽谈过程还比较愉悦,小姑娘名校毕业,落落大方,薪酬要求比较合理,各方面都比较符合,最后就在决定要录用时,HR朋友随口问了句 “你为什么离开上家公司?”,小姑娘也是随口说了句“我不喜…...
注意力机制详解系列(五):分支与时间注意力机制
👨💻作者简介: 大数据专业硕士在读,CSDN人工智能领域博客专家,阿里云专家博主,专注大数据与人工智能知识分享,公众号:GoAI的学习小屋,免费分享书籍、简历、导图等资料&…...
创宇盾重保经验分享,看政府、央企如何防护?
三月重保已经迫近,留给我们的准备时间越来越少,综合近两年三月重保经验及数据总结,知道创宇用实际案例的防护效果说话,深入解析为何创宇盾可以在历次重保中保持“零事故”成绩,受到众多部委、政府、央企/国企客户的青睐…...
软件测试面试汇总
在浏览器中输入 URL,回车后发生了什么? 在浏览器中输入URL并按下回车键后,大致流程如下: 1、浏览器解析 URL,提取出协议(例如HTTP、HTTPS)、主机名和路径等信息。 2、浏览器查找该URL的缓存记录࿰…...
空指针,野指针
空指针在C/C中,空指针(null pointer)是指向内存地址0的指针变量。NULL在C/C中的定义为:#ifndef NULL#ifdef __cplusplus#define NULL 0#else#define NULL ((void *)0)#endif #endif从上面的代码定义中,我们可以发现在C…...
Mysql Nested-Loop Join算法和MRR
MySQL8之前仅支持一种join 算法—— nested loop,在 MySQL8 中推出了一种新的算法 hash join,比 nested loop 更加高效。(后面有时间介绍这种join算法) 1、mysql驱动表与被驱动表及join优化 先了解在join连接时哪个表是驱动表&a…...
Spark 广播/累加
Spark 广播/累加广播变量普通变量广播分布式数据集广播克制 Shuffle强制广播配置项Join Hintsbroadcast累加器Spark 提供了两类共享变量:广播变量(Broadcast variables)/累加器(Accumulators) 广播变量 创建广播变量…...
飞天云动,站在下一个商业时代的门口
ChatGPT的爆火让AIGC再度成为热词,随之而来的是对其商业化的畅想——不是ChatGPT自身如何盈利,而是它乃至整个AIGC能给现在的商业环境带来多大改变。 这不由得令人想起另一个同样旨在改变世界的概念,元宇宙。不同的是,元宇宙更侧…...
上海分时电价机制调整对储能项目的影响分析
安科瑞 耿敏花 2022年12月16日,上海市发改委发布《关于进一步完善我市分时电价机制有关事项的通知》(沪发改价管〔2022〕50号)。通知明确上海分时电价机制,一般工商业及其他两部制、大工业两部制用电夏季(7、8、9月)和冬季&#x…...
产品新人如何快速上手工作
三百六十行,行行出产品经理:上至封神的乔布斯,下至卖鸡蛋罐饼的阿姨,他们对如何打造自己的产品都会有一套完整的产品思路,这也是为什么说“人人都是产品经理”。这个看似光鲜的“经理”有时也会被戏称产品汪࿰…...
Linux: ARM GIC仅中断CPU 0问题分析
文章目录1. 前言2. 分析背景3. 问题4. 分析4.1 ARM GIC 中断芯片简介4.1.1 中断类型和分布4.1.2 拓扑结构4.2 问题根因4.2.1 设置GIC SPI中断的CPU亲和性4.2.2 GIC初始化:缺省的CPU亲和性4.2.2.1 boot CPU亲和性初始化流程4.2.2.1 其它非 boot CPU亲和性初始化流程5…...
第20篇:Java运算符全面总结(系列二)
目录 4、逻辑运算符 4.1 逻辑运算符 4.2 代码示例 5、赋值运算符 5.1 赋值运算符...
OpenCV4.x图像处理实例-OpenCV两小时快速入门(基于Python)
OpenCV两小时快速入门(基于Python) 文章目录 OpenCV两小时快速入门(基于Python)1、OpenCV环境安装2、图像读取与显示3、图像像素访问、操作与ROI4、图像缩放5、几何变换5.1 平移5.2 旋转6、基本绘图6.1 绘制直线6.2 绘制圆6.3 绘制矩形6.4 绘制文本7、剪裁图像8、图像平滑与…...
【Git】Mac忽略.DS_Store文件
我们在github上经常看到某些仓库里面包含了.DS_Store文件,或者某些sdk的压缩包里面可以看到,这都是由于随着git的提交把这类文件也提交到仓库,压缩也是一样,压缩这个先留着后面处理。 Mac上的.DS_Store文件 .DS_Store 文件&#…...
12.2 基于Django的服务器信息查看应用(CPU信息)
文章目录CPU信息展示图表展示-视图函数设计图表展示-前端界面设计折线图和饼图展示饼图测试折线图celery和Django配合实现定时任务Windows安装redis根据数据库中的数据绘制CPU折线图CPU信息展示 图表展示-视图函数设计 host/views.py def cpu(request):logical_core_num ps…...
【软件测试】接口测试总结
本文主要分为两个部分: 第一部分:主要从问题出发,引入接口测试的相关内容并与前端测试进行简单对比,总结两者之前的区别与联系。但该部分只交代了怎么做和如何做?并没有解释为什么要做? 第二部分࿱…...
代码随想录算法训练营第52天 || 300.最长递增子序列 || 674. 最长连续递增序列 || 718. 最长重复子数组
代码随想录算法训练营第52天 || 300.最长递增子序列 || 674. 最长连续递增序列 || 718. 最长重复子数组 300.最长递增子序列 题目介绍 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列,删除(或…...
gitblit 安装使用
1 安装服务端 简而言之:需要安装 java,gitblit, git 三个软件 Windows 10环境使用Gitblit搭建局域网Git服务器 前言 安装Java并配置环境安装gitblit并配置启动gitblit为windows服务使用gitblit创建repository并管理用户 1.1 安装Java并配…...
使用 TensorFlow、Keras-OCR 和 OpenCV 从技术图纸中获取信息
简单介绍输入是技术绘图图像。对象检测模型获取图像后对其进行分类,找到边界框,分配维度,计算属性。示例图像(输入)分类后,找到“IPN”部分。之后,它计算属性,例如惯性矩。它适用于不…...
ESP32设备驱动-GUVA-S12SD紫外线检测传感器驱动
GUVA-S12SD紫外线检测传感器驱动 文章目录 GUVA-S12SD紫外线检测传感器驱动1、GUVA-S12SD介绍2、硬件准备3、软件准备4、驱动实现1、GUVA-S12SD介绍 GUVA-S12SD 紫外线传感器芯片适用于检测太阳光中的紫外线辐射。 它可用于任何需要监控紫外线量的应用,并且可以简单地连接到任…...
电商运营主要做什么工作/网站运营推广选择乐云seo
51nod 1244 莫比乌斯函数之和 莫比乌斯函数,由德国数学家和天文学家莫比乌斯提出。梅滕斯(Mertens)首先使用μ(n)(miu(n))作为莫比乌斯函数的记号。具体定义如下: 如果一个数包含平方因子,那么miu(n) 0。例如…...
织梦cms 做视频网站/深圳产品网络推广
项目引入vue-i18n实现国际化多语言,vue-i18n包 自行下载,放到libs目录下,在main.js中引入 //main.js import Vue from vue import App from ./App //多语言引入 import VueI18n from ./libs/vue-i18n import en from ./common/js/en.js//英文…...
wordpress 访问限制/域名批量查询工具
下面有这样一个场景: 数据库的某些字段是自增产生的(比如说mysql,他就有自增的功能) 我在插入数据的时候就没插入自增的那一段数据,但在插入数据后,我想看看自增的这条数据是什么(回写操作&…...
网站内容与模板设计/阐述网络营销策略的内容
例如:easy_install -m tornado...
大鹏网站建设公司/网页制作平台有哪些
1). 在面向对象的方法中,一个对象请求另一个对象为其服务的方式是通过发送A.调用语句B.命令C.口令D.消息正确答案:D2). 下列的( )原始类型在使用流时可以互换。A.byte和booleanB.char和intC.byte和charD.String和char正确答案:B答案解析&…...
上海市做网站的公司/营销推广内容
输出为两行。第一行为金额为x的美元、欧元、日元兑换成人民币的金额,用空格分开。 第二行为金额为y的人民币兑换成美元、欧元、日元的金额,用空格分开。 所有金额精确到小数点后两位。 Sample Input668.5200 908.0685 7.9852 1500 1500Sample Output1002…...