前端八股文(js篇 )
目录
二.介绍下Set,Map,WeakSet和WeakMap的区别
三.setTimeout,Promise,Async/Await的区别
九.JavaScript中的数组和函数在内存中是如何存储的?
一.防抖,节流是什么,如何实现?
我们在平时开发的时候,会有很多场景频繁触发事件,比如说搜索框实时发请求,onmousemove,resize,onscroll等,有些时候,我们并不能或者不想频繁触发事件,这时候就应该用到函数防抖和节流。
函数防抖,指的是短时间内多次触发同一事件,只执行最后一次,或者只执行最开始的一次,中间的不执行。
具体实现:
?
//函数防抖
function debounce(func,wait){
//设置变量,记录setTimeout得到的id
let timerId=null;
return function(...args){
if(timerId){
//如果有值,说明正在等待中,清除它
clearTimeout(timerId);
}
//重新开始计时
timerId=setTimeout(()=>{
func(..args);
},wait);
}
}
函数节流,指连续触发事件但是在n秒中只执行一次函数。即2n秒内执行两次。节流如字面意思,会稀释函数的执行频率。
具体实现如下:
//函数节流
function throttle(func,watit){
let context,args;
let provious=0;
return function () {
let now = new Date();
context=this;
args=arguments
if(now-provious>wait){
func.app(contxt,args)
provious=now;
}
}
}
二.介绍下Set,Map,WeakSet和WeakMap的区别
Set:
- 成员唯一,无序且不重复
- 键值与键名是一致的
- 可以遍历,方法有add,delete,has
WeakSet:
- 成员都是对象
- 成员都是弱引用,可以被立即回收机制回收,可以用来保存DOM节点,不容易造成内存泄露
- 不能遍历,方法有add,delete,has
Map:
- 本质上是键值对的集合,类似集合
- 可以遍历,方法很多,可以跟各种数据格式转换
WeakMap:
- 只能接收对象作为键名,不接受其他类型的值作为键名
- 键名是弱引用,键值可以是任意的,键名所指的对象可以被垃圾机制回收,此时键名是无效的
- 不能遍历,方法有get,set,has,delete
三.setTimeout,Promise,Async/Await的区别
事件循环中分为宏任务队列和微任务队列。
其中setTimeout的回调函数放到宏任务队列里,等到执行栈情况以后执行;
promise.then里面的回调函数会放到宏任务的微任务队列里,等宏任务里面的同步代码执行完再执行;
async函数表示函数里面可能会有异步方法,await后面跟一个表达式,async方法执行时,遇到await会立即执行表达式,然后把表达式后面的代码放到微任务队列里,让出执行栈让同步代码先执行。
四.简述同步和异步的区别
同步意味着每一个操作必须等待前一个操作完成后才能执行。
异步意味着操作不需要等待其他操作完成后才开始执行。
在JavaScript中,由于单线程的特性导致所有代码都是同步的。但是,有些异步操作(例如:XMLHtttpRequest或setTimeout)并不是由主线程进行处理的,他们由本机代码所控制,并不属于程序的一部分。但程序中被执行回调部分依旧是同步的。
- JavaScript中的同步任务是指在主线程上排队执行的任务,只有前一个任务执行完成后才能执行后一个任务;异步任务是指进入任务队列(task queue ) 而非主线程的任务,只有当任务队列通知主线程,某个异步任务可以执行了,该任务才会进入主线程中进行执行。
- JavaScript的并发模型是基于"event loop"。
- 像 alert这样的方法回阻主线程,以致用户关闭他后才能继续进行后面的操作。
- JavaScript主要用于和用户互动及操作DOM,多线程的情况和异步操作带来的复杂性相比决定了他单线程的特性。
- Web Worker 虽然允许JavaScript创建多个线程,但子线程完全受到主线程控制,且不能操作DOM。因此他还是保持单线程的特性。
五.怎么添加,移除,复制,创建,和查找节点
1)创建新节点
- createDocumentFragment()//创建一个DOM片段
- createElement() //创建一个具体的元素
- createTextNode() //创建一个文本节点
2)添加,移除,替换,插入
- appendChild()
- removeChild()
- replaceChild()
- insertBefore()
3) 查找
- getElementsByTagName()//通过标签名称
- getElementsByName()//通过元素的Name属性的值
- getElementById()//通过元素ID,唯一性
- querySelector()//用于接收一个CSS选择符,返回与该模式匹配的第一个元素
- querySelectorAll()//用于选择匹配到的所有元素
六.attribute和property的区别是什么?
property和attribute是二个不同的东西,属于不同的范畴。
- property是DOM中的属性,是JavaScript里的对象。
- attribute是HTML标签上的特性,它的值只能够是字符串;
简单理解,Attribute就是dom节点自带的属性,例如html中常用的id,class,title,align等
而property是这个DOM元素作为对象,其附加的内容,例如childNodes,firstChild等。
七.原始类型有哪几种?null是对象吗?
在JavaScript中,数据类型整体上来讲可以分为两大类:基本数据类型和引用数据类型
基本数据类型,一个6种:
string,symbol,number,boolean,undefined,null
其中symbol类型是ES6里面新添加的基本数据类型
引用数据类型,就只有一种:
object
基本数据类型的值又被称之为原始值或简单值,而引用数据类型的值又被称之为复杂值或引用值
八.什么是函数式编程,应用场景是什么?
函数式编程和面向对象编程一样,是一种编程式范式。强调执行的过程中而非结果,通过一系列的嵌套的函数调用,完成一个运算过程。它主要有以下几个特点:
- 函数时“一等公民”:函数优先,和其他数据类型一样
- 只要“表达式”,不用“语句”:通过表达式计算过程得到一个返回值,而不是通过一个语句修改某个状态。
- 无副作用:不污染变量,同一个输入永远得到同一个数据。
- 不可变性:前面一提到,不修改变量,返回一个新的值。
函数式编程的应用场景:
- Stateless components:React在0.14之后推出的无状态组件
- Redux
九.JavaScript中的数组和函数在内存中是如何存储的?
在JavaScript中,数组不是以一段连续的区域存储在内存中,而是一种哈希映射的形式存储在堆内存里面。它可以通过多种数据结构实现,其中一种是链表。
JavaScript中的函数是存储在堆内存中的,具体的步骤如下:
- 开辟堆内存(16进制得到内存地址)
- 声明当前函数的作用域(函数创建的上下文才是他的作用域,和在那执行的无关)
- 把函数的代码以字符串的形式存储在堆内存中(函数再不执行的情况下,只是存储在堆内存中的字符串)
- 将函数堆的地址,放到栈中供变量调用(函数名)
十.扩展运算符的作用及使用场景
扩展运算符是三个点(...),主要用于展开数组,将一个数组转为参数序列。
扩展运算符使用场景:
- 代替数组的apply方法
- 合并数组
- 复制数组
- 把arguments或NodeList转为数组
- 与解构赋值结合使用
- 将字符串转为数组
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!