<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path> </svg>
讯享网
JS的数据类型都有哪些?
数据类型分为基本数据类型和引用数据类型;
基本数据类型:
- String、Number、Boolean、Null、Undefined、Symbol、BigInt。
引用数据类型统称为Object类型,细分的话有:
- Object 、Array 、Function、Date、RegExp
基本数据类型的数据直接存储在栈中;而引用数据类型的数据存储在堆中,在栈中保存数据的引用地址,这个引用地址指向的是对应的数据,以便快速查找到堆内存中的对象。
顺便提一句,栈内存是自动分配内存的。而堆内存是动态分配内存的,不会自动释放。所以每次使用完对象的时候都要把它设置为null,从而减少无用内存的消耗
数据类型的判断方式?
1.
- 缺点:的值为,无法分辨是还是
2.
- 缺点:只能判断某对象是否存在于目标对象的原型链上,不能检测出基本类型
- 主要用于检查某个对象是否是某个构造函数的实例(或者说 检测某个对象是否继承自某个构造函数的原型链。)
3.
- 使用 constructor 可以查看目标构造函数,也可以进行数据类型判断。
- 但是不能判断 和 ,因为这两个特殊类型没有其对应的包装对象。和类似,返回结果的是自己的构造函数,而 则是自己与构造函数比较返回布尔值
4.
- 一种最好的基本类型检测方式 ;它可以区分所有数据类型。
- 缺点:不能细分为谁谁的实例
讯享网
为什么要用,为什么不用 ?⭐⭐
因为只有Object.prototype.toString.call()返回的是统一格式,而且 Array.prototype.toString.call()的部分类型无法检验。
判断数组的方式有哪些?
- Object.prototype.toString.call():
讯享网
- 通过原型链做判断
- 通过ES6的Array.isArray()做判断
讯享网
- 通过instanceof做判断
- 通过Array.prototype.isPrototypeOf
讯享网
null和undefined的区别?
- null代表空值,undefined代表未定义
- 在““情况下,两者相等。在””情况下,两者不相等,因为类型不同
- 使用判断, 类型是,类型是
- 将转为数值结果为,将转为数值结果为
为什么typeof null 是Object?
因为在JS中,不同的对象都是使用二进制存储的,如果二进制前三位都是0的话,系统会判断为是Object类型,而null的二进制全是0,自然也就判断为Object
这个bug是初版本的JavaScript中留下的,扩展一下其他五种标识位:
- 000 对象
- 1 整型
- 010 双精度类型
- 100字符串
- 110布尔类型
为什么0.1+0.2>0.3 ?
因为在JS底层中,每个变量是以二进制表示,固定长度为64位,其中第1位是符号位,再往后11位是指数位,最后52表示的是尾数位,而0.1和0.2转为二进制的时候是无限循环小数,所以JS就会进行截取,截取以后0.1和0.2就不是他们本身了,要比原来大那么一丢丢,所以0.1+0.2就>0.3了
如何解决这个问题,使0.1+0.2等于0.3?
先给他们放大倍数,随后再除以相应倍数
和有什么区别 ?
是严格意义上的相等,会比较两边的数据类型和值大小
- 数据类型不同返回false
- 数据类型相同,但值大小不同,返回false
是非严格意义上的相等
- 两边类型相同,比较大小
- 两边类型不同,根据下方表格,再进一步进行比较。
- Null == Undefined -> true
- String == Number -> 先将String转为Number,再比较大小
- Boolean == Number -> 现将Boolean转为Number,再进行比较
- Object == String,Number,Symbol -> Object 转化为原始类型,再进行比较
返回什么?
返回 ,永远不等于,判断是否为用一个函数 来判断;
传入的如果是其他数据类型,那么先将它使用转为数字类型再进行判断
- 在全局作用域中,非严格模式下,this指向全局对象window。
- 在全局作用域中,直接调用一个函数(非严格模式),this指向全局对象window。严格模式下,this是undefined。
- 在对象方法中,this指向调用方法的对象。
- 在构造函数中,this指向新创建的实例对象。
- 在事件处理函数中,this 指向绑定事件的DOM元素。
- 在箭头函数中,不会创建自己的this,它与包围它的非箭头函数的this值相同。就是定义时所在作用域的对象,而不是使用时所在的作用域的对象。
- 显示绑定:使用call、apply、bind可以显式绑定this。
JS 遍历数组的方法?
forEach 和 map 有什么区别?
- forEach() 没有返回值。
- 一般如果用来遍历修改原数组的话可以用 foreach 方法
- map() 会返回一个新数组。这个新数组由原数组中的每个元素经过指定函数处理后的值组成
- 当你需要遍历数组,并根据数组中的每个元素生成一个新数组时,使用 map。
什么是作用域,什么是作用域链?⭐⭐⭐⭐
- 规定变量和函数的可使用范围称作作用域
- 每个函数都有一个作用域链,查找变量或者函数时,需要从局部作用域到全局作用域依次查找,这些作用域的集合称作作用域链。
什么是执行栈,什么是执行上下文?⭐⭐⭐⭐
执行上下文分为:
- 全局执行上下文
- 创建一个全局的window对象,并规定this指向window,执行js的时候就压入栈底,关闭浏览器的时候才弹出
- 函数执行上下文
- 每次函数调用时,都会新创建一个函数执行上下文
- 执行上下文分为创建阶段和执行阶段
讯享网
<ul><li>创建阶段: <ul><li>函数环境:arguments对象(并赋值)、函数声明(并赋值)、变量声明(不赋值),函数表达式声明(不赋值);</li><li>;</li><li></li></ul> </li><li>执行阶段: <ul><li>变量赋值、函数表达式赋值,使变量对象变成活跃对象</li><li>代码执行</li></ul> </li></ul> </li></ul> </li><li><strong>eval执行上下文</strong></li></ul>执行栈:
- 首先栈特点:先进后出
- 当进入一个执行环境,就会创建出它的执行上下文,然后进行压栈,当程序执行完成时,它的执行上下文就会被销毁,进行弹栈。
- 栈底永远是全局环境的执行上下文,栈顶永远是正在执行函数的执行上下文
- 只有浏览器关闭的时候全局执行上下文才会弹出
什么是闭包?闭包的作用?闭包的应用?
函数执行,形成私有的执行上下文,使内部私有变量不受外界干扰,起到保护和保存的作用
作用:
- 保护
- 避免命名冲突
- 保存
- 解决循环绑定引发的索引问题
- 变量不会销毁
- 可以使用函数内部的变量,使变量不会被垃圾回收机制回收
应用:
- 设计模式中的单例模式
- for循环中的保留i的操作
- 防抖和节流
- 函数柯里化
缺点:会出现内存泄漏的问题
什么是闭包?
- 闭包就是指有权访问另一个函数作用域中的变量的函数。
- (或 闭包就是能访问到外部函数作用域中变量的函数)
闭包的特点
- 可以在函数外部访问到函数内部的变量:创建私有变量。
- 让这些变量常驻在内存中,不会在调用结束后,被垃圾回收机制回收。
- 会造成内存泄漏(有一块内存空间被长期占用,而不被释放):使用完闭包函数后手动释放
闭包的使用场景
- return 回一个函数
- 函数作为参数
- IIFE(立即执行函数)
- 循环赋值
- 使用回调函数就是在使用闭包
- 节流和防抖
- 函数柯里化
闭包的用途:
- 数据封装(封装私有变量):可以封装私有变量,提供公共的访问方法,保护数据不被随意修改。
- 函数工厂:可以用来创建函数工厂,根据传入的参数返回不同的函数实例。
- 做缓存:函数一旦被执行完毕,其内存就会被销毁,而闭包的存在,就可以保有内部环境的作用域。
- 模块化编程(实现共有变量):可以用来实现模块化的代码,封装功能,只暴露必要的接口。
原型对象
构造函数的内部的 prototype 属性指向的对象,就是构造函数的原型对象。
原型对象包含了可以由该构造函数的所有实例共享的属性和方法。当使用构造函数新建一个实例对象后,在这个对象的内部将包含一个指针(),这个指针指向构造函数的 原型对象,在 ES5 中这个指针被称为对象的原型。
原型对象(显示原型):
- 在声明了一个函数后,这个构造函数上会有一个属性,这个属性指向的就是这个构造函数对应的原型对象;原型对象上有一个constructor属性,这个属性指向的是这个构造函数。

讯享网
隐式原型:
- 每个实例对象都有一个属性,称为隐式原型
- 对象的隐式原型的值 默认 为对象的构造函数的显示原型
- ☆ 实例对象的属性指向的是构造函数的原型对象
- ☆ 实例对象不存在prototype属性

原型链:
当访问一个时,如果这个对象内部不存在这个属性,那么它就会沿着继续向上,直到找到为止,或者到链条末尾(即null)停止,这种链式查找过程称之为原型链。
- 原型链的尽头是null。也就是
什么是原型?什么是原型链?如何理解⭐⭐⭐⭐⭐
原型: 原型分为隐式原型和显式原型,每个对象都有一个隐式原型,它指向自己的构造函数的显式原型。每个构造方法都有一个显式原型。
- 是隐式原型;是显式原型
- 所有实例的都指向他们构造函数的prototype
- 所有的都是对象,自然它的指向的是的
- 所有的构造函数的隐式原型指向的都是的显示原型
- Object的隐式原型是null
原型链: 多个组成的集合成为原型链(概念类似于作用域链)
就是判断某对象是否位于某构造方法的原型链上。

JS 中的常用的继承方式有哪些?以及各个继承方式的优缺点。⭐⭐⭐⭐⭐
原型继承、组合继承、寄生组合继承、ES6的extend
原型继承
组合继承
讯享网
寄生组合继承
ES6中的类 extend
讯享网
什么是内存泄漏⭐⭐⭐⭐⭐
内存泄露是指不再用的内存没有被及时释放出来,导致该段内存无法被使用就是内存泄漏
为什么会导致的内存泄漏⭐⭐⭐⭐⭐
内存泄漏指我们无法在通过js访问某个对象,而垃圾回收机制却认为该对象还在被引用,因此垃圾回收机制不会释放该对象,导致该块内存永远无法释放,积少成多,系统会越来越卡以至于崩溃
垃圾回收机制都有哪些策略?⭐⭐⭐⭐⭐
- 标记清除法
- 垃圾回收机制获取根并标记他们,然后访问并标记所有来自它们的引用,然后在访问这些对象并标记它们的引用…如此递进结束后若发现有没有标记的(不可达的)进行删除,进入执行环境的不能进行删除
- 引用计数法
- 当声明一个变量并给该变量赋值一个引用类型的值时候,该值的计数+1,当该值赋值给另一个变量的时候,该计数+1,当该值被其他值取代的时候,该计数-1,当计数变为0的时候,说明无法访问该值了,垃圾回收机制清除该对象
- 缺点: 当两个对象循环引用的时候,引用计数无计可施。如果循环引用多次执行的话,会造成崩溃等问题。所以后来被标记清除法取代。
数组的浅拷贝: 如果是数组,我们可以利用数组的一些方法,比如 slice,concat 方法返回一个新数组的特性来实现拷贝,但假如数组嵌套了对象或者数组的话,使用 concat 方法克隆并不完整,如果数组元素是基本类型,就会拷贝一份,互不影响,
而如果是对象或数组,就会只拷贝对象和数组的引用,这样我们无论在新旧数组进行了修改,两者都会发生变化,我们把这种复制引用的拷贝方法称为浅拷贝。
深拷贝就是指完全的拷贝一个对象,即使嵌套了对象,两者也互相分离,修改一个对象的属性,不会影响另一个。浅拷贝: 以赋值的形式拷贝引用对象,仍指向同一个地址,修改时原对象也会受到影响
- (展开运算符) — 可以将一个数组中的元素展开到另一个数组中或者作为函数的参数传递
深拷贝: 完全拷贝一个新对象,修改时原对象不再受到任何影响
- : 性能最快
【 原理是 JOSN 对象中的 stringify 可以把一个 js 对象序列化为一个 JSON 字符串, parse 可以把 JSON 字符串反序列化为一个 js 对象,通过这两个方法,也可以实现对象的深复制。 】- 具有循环引用的对象时,报错
- 当值为函数、undefined、或 symbol 时,无法拷贝
- 进行逐一赋值
- Lodash的_.cloneDeep()
什么是DOM事件流?什么是事件委托
- DOM事件流
- 分为三个阶段
<ul><li>捕获阶段:事件从顶层元素开始向下传播</li><li>目标阶段:事件到达目标元素</li><li>冒泡阶段:事件从目标元素向上传播</li></ul> </li><li>在addeventListener()的第三个参数(useCapture)设为true,就会在捕获阶段运行,默认是false冒泡</li></ul> </li><li>事件委托(事件代理)- 利用冒泡的特点,在父元素上绑定事件监听器,而不需要在每个子元素上分别绑定,这种方式称为事件委托,能提高性能和代码可维护性。
- 当子元素触发事件时,事件会冒泡传递到父元素,由父元素的事件处理程序来处理这个事件。
事件冒泡和事件捕获有什么区别
- 事件冒泡
- 事件从目标元素开始,逐层向上传递到最外层的祖先元素(document 根对象)。
- 在中的第三属性设置为false(默认)
- 事件捕获
- 从最外层的祖先元素(document 根对象)开始,逐层向下传递事件,直到目标元素。
- 在中的第三属性设置为true
JS的执行机制(同步任务、异步任务)
JS是一门单线程语言,单线程就意味着,所有的任务需要排队,前一个任务结束,才会执行下一个任务。这样所导致的问题是:如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞。为了解决这个问题,JS中出现了同步和异步。
同步任务:即主线程上的任务,按照顺序由上⾄下依次执⾏,当前⼀个任务执⾏完毕后,才能执⾏下⼀个任务。
异步任务:不进⼊主线程,⽽是进⼊ 任务队列 的任务,执行完毕之后会产生一个回调函数,并且通知主线程。当主线程上的任务执行完后,就会调取最早通知自己的回调函数,使其进入主线程中执行。
- 任务队列:分为 宏任务队列 和 微任务队列 。
- 宏任务:每次事件循环首先检查并执行一个宏任务
讯享网
<ul><li>、、、</li></ul> </li><li>微任务:微任务在当前宏任务处理完后立即执行,优先级高于下一个宏任务 <ul><li>、、、</li><li>注意:<strong>promise是同步任务</strong></li></ul> </li></ul> </li></ul>事件循环执行机制
- 执行宏任务script
- 进入script后,所有的同步任务主线程执行
- 遇到宏任务,放入到宏任务队列里
- 遇到微任务,放入到微任务队列里
- 先清空微任务队列
- 再取一个宏任务执行,再清空微任务队列
- 依次循环
以此反复直到清空所有宏任务,这种不断重复的执行机制,就叫做事件循环
为什么JS是单线程
JS是单线程,但是浏览器是多线程。单线程是为了避免UI操作混乱,所有和UI操作相关的开发语言都应该是单线程。
代码题易考点
- promise 本身是一个同步的代码,只有它后面调用的 then() 方法里面的回调才是微任务
- then 方法需要 promise 里的 resolve 传值才会执行
- await 右边的表达式还是会立即执行,表达式之后的代码带上微任务,await 微任务可以转换成等价的 promise 微任务分析
- script 标签本身是一个宏任务,当页面出现多个 script 标签的时候,浏览器会把script标签作为宏任务来解析
为什么JS是单线程的?⭐⭐⭐⭐⭐
宏任务和微任务都有哪些⭐⭐⭐⭐⭐
- 宏任务:、、、
- 微任务:,、、
- 注意:Promise是同步任务
宏任务和微任务都是怎样执行的⭐⭐⭐⭐⭐
- 执行宏任务script,
- 进入script后,所有的同步任务主线程执行
- 所有宏任务放入宏任务执行队列
- 所有微任务放入微任务执行队列
- 先清空微任务队列,
- 再取一个宏任务,执行,再清空微任务队列
- 依次循环
例题1
解析
- 首先浏览器执行Js代码由上至下顺序,遇到setTimeout,把setTimeout分发到宏任务Event Queue中
- new Promise属于主线程任务直接执行打印2
- Promise下的then方法属于微任务,把then分到微任务 Event Queue中
- console.log(‘4’)属于主线程任务,直接执行打印4
- 又遇到new Promise也是直接执行打印5,Promise 下到then分发到微任务Event Queue中
- 又遇到setTimeout也是直接分发到宏任务Event Queue中,等待执行
- console.log(‘10’)属于主线程任务直接执行
- 遇到bar()函数调用,执行构造函数内到代码,打印8,在bar函数中调用foo函数,执行foo函数到中代码,打印9
- 主线程中任务执行完后,就要执行分发到微任务Event Queue中代码,实行先进先出,所以依次打印3,6
- 微任务Event Queue中代码执行完,就执行宏任务Event Queue中代码,也是先进先出,依次打印1,7。
- 最终结果:2,4,5,10,8,9,3,6,1,7
例题2
讯享网
运行结果: 5 7 10 8 1 2 4 6 3
例题3
变量和函数怎么进行提升的?优先级是怎么样的?
- 对所有函数声明进行提升(除了函数表达式和箭头函数),引用类型的赋值
- 开辟堆空间
- 存储内容
- 将地址赋给变量
- 对变量进行提升,只声明,不赋值,值为
var、let、const 有什么区别
- 存在变量提升
- 可以重新赋值、重复声明
- 在非函数作用域中定义是挂在到window上的
- 不存在变量提升
- 具有块级作用域
- 可以重新赋值、但不能重复声明
- 具有let的所有特征
- 声明变量时必须设置初始值
- 不可以重新赋值、重新声明
- 不可改变只适用于直接地址。如果使用const声明的是对象的话,是可以修改对象内部的值的。
为什么要使用模块化?都有哪几种方式可以实现模块化,各有什么特点?⭐⭐⭐
- 为什么要使用模块化
- 防止命名冲突
- 更好的分离,按需加载
- 更好的复用性
- 更高的维护性
和有什么区别?⭐⭐⭐
- 导出方式不一样
- 是的引用,两个指向的是用一个地址,而require能看到的只有
JS模块包装格式有哪些?⭐⭐⭐
- commonjs
- 同步运行,不适合前端
- AMD
- 异步运行
- 异步模块定义,主要采用异步的方式加载模块,模块的加载不影响后面代码的执行。所有依赖这个模块的语句都写在一个回调函数中,模块加载完毕,再执行回调函数
- CMD
- 异步运行
- seajs 规范
ES6和commonjs的区别⭐⭐⭐
Commonjs、AMD、CMD、UMD、ESM 都有什么区别
- Commonjs
- 是同步执行的,不适合前端,后端 nodejs 可以使用 commonjs。
- 使用方式
讯享网
- AMD/CMD/UMD 适用前端 异步执行
- AMD
- CMD
讯享网
- AMD 和 CMD 的差别是
<ul><li>AMD 是依赖前置(把依赖放在前面)、提前执行(即使没有用到某个模块,也会提前执行)</li><li>CMD依赖就近、延时执行(用到的时候在声明依赖)</li></ul> </li></ul> </li><li> <p>ESM</p>- 使用 export 、 export default 来导出模块,使用 import 来引入模块
- ESM 和 commonjs 的区别主要在于
- commonjs 是运行时加载 ;ESM 是编译时加载
- commonjs 是同步加载模块;ESM 是异步加载模块
- commonjs 是对值的浅拷贝;ESM 是对值的引用,而且不可修改(直接地址不可修改,类似于 const)。
require 和 import的区别?⭐⭐⭐
- 调用时机
- require 是运行时调用,所以其实是可以放在任何地方的
- Import 是编译时调用,所以必须放在文件的开头
- 使用时,
- require 需要使用 module.exports = fs 或者exports.fs = xxx
- import 用 export default 或 export const xx
- 解构赋值
- require 是赋值的过程
- import 是解构的过程
箭头函数和普通函数的区别?箭头函数可以当做构造函数 new 吗?⭐⭐⭐⭐⭐
箭头函数是普通函数的简写,但是它不具备很多普通函数的特性
- 箭头函数的this指向它定义时所在的对象,而不是调用它的对象
- 不能通过call、apply、bind方法直接修改它的 this 指向
- 不会进行函数提升
- 没有对象,不能使用,如果要获取参数的话可以使用运算符
- 没有属性,不能作为生成器Generator使用
- 不能作为构造函数实例化对象
- 没有prototype属性,new关键字内部需要把新对象的指向函数的prototype
什么是requestAnimationFrame?⭐⭐⭐⭐
- requestAnimationFrame请求数据帧可以用做动画执行
- 可以自己决定什么时机调用该回调函数
- 能保证每次频幕刷新的时候只被执行一次
- 页面被隐藏或者最小化的时候暂停执行,返回窗口继续执行,有效节省CPU
讯享网
js常见的设计模式⭐⭐⭐⭐
- 单例模式、工厂模式、构造函数模式、发布订阅者模式、迭代器模式、代理模式
- 单例模式
- 不管创建多少个对象都只有一个实例
- 工厂模式
- 代替new创建一个对象,且这个对象想工厂制作一样,批量制作属性相同的实例对象(指向不同)
讯享网
- 构造函数模式
- 发布订阅者模式
- 代理模式
- 迭代器模式
点击300ms 延迟问题⭐⭐⭐⭐⭐
- 设置一个 meta 标签
- fastClick 插件
- 自己实现
- 实现大概思路:封装一个函数,接受两个参数,一个是目标对象,一个是点击后的回调函数; 在 ontouchstart 开始计时,在 ontouchend 中计时结束,如果超出150ms 就
讯享网
如何实现上传视频?⭐⭐⭐⭐
- input type = ‘file’去接收
- 用 window.URL.createObjectURL(file)把 file 文件转换为 URL(现场的/前端转为 URL)
或者用 FormData 去接收, 把 file 文件append 进去,然后传给后端,使用返回的 URL
setTimeOut第三个参数是什么?⭐⭐⭐⭐⭐
可以作为参数传给函数,一般用于 for 循环赋值
什么是暂时性死区?⭐⭐⭐⭐⭐
暂时性死区是指,当进入一个作用域,我去使用一个变量名,而这个变量名已经存在了,但是是不可获取的,就会报错,造成暂时性死区问题;比如一个作用域下面使用了 let 定义了 ,但是在定义之前就使用了 ,就会报错;暂时性死区意味着 typeof 也不是绝对安全的操作

数组可以改变原数组的方法⭐⭐⭐⭐⭐
push()、pop()、shift()、unshift()、splice()、sort()、reverse()
不改变原数组的方法:
- join():变成字符
- slice():截取
- concat():合并数组
如何捕获浏览器关闭事件?⭐⭐
讯享网
localstorage 怎么存储图片⭐⭐⭐⭐
创建一个canvas对象,把图片保存在 canvas 中,然后 canvas 对象 toDataUrl,在把 dataurl 数据存储在 localstorage 中。
或者使用 blob 二进制流存储,canvas 对象toBlob
如何实现大文件上传?⭐⭐⭐⭐
使用 input 接受大文件,使用file.slice进行分割分块上传(制定好一个块的大小,然后进行分割),等所有块上传完毕之后,promise.all(),运行成功回调
如何实现 localstorage 定时清除⭐⭐⭐⭐
- 自己重写一个 set 方法,内部逻辑就是添加一个现在的时间以及有效时长
- 再重写一个 get 方法,每当 get 的时候先进行判断是否过期,如果过期就删除,并返回 null,没过期的话正常返回
web worker是干什么的?⭐⭐⭐
js是单线程的,而web worker可以多创建一个子线程,多出来的这个子线程执行代码时不会阻塞主线程。它有几个限制,
同源限制,子线程资源必须和主线程资源是同源
dom限制,子线程不能操作dom
文件限制,不能打开本机(file://)文件,只能来源于网络
通信限制,只能使用postmessage来传输信息
脚本限制,不能使用alert、confirm方法
jquery 如何实现链式调用⭐⭐⭐
node 事件循环机制和浏览器事件循环机制有什么区别⭐⭐
浏览器和 Node 环境下,microtask 任务队列的执行时机不同
Node 端,microtask 在事件循环的各个阶段之间执行
浏览器端,microtask 在事件循环的 macrotask 执行完之后执行
https://zhuanlan.zhihu.com/p/讲一讲Reflect⭐⭐
顾名思义,reflect反射的意思。可以反射对象
Reflect可以提供一些方法去拦截js的操作,Reflect不是一个函数对象,所以它不可构造,Reflect内部的方法和属性都是静态的。
比如创建一个没有原型的对象,也就是说他自己不能调用任何基于Object原型链上的方法
讯享网
Object.keys和Object.getOwnPropertyNames有什么区别?⭐⭐⭐
Object.keys只列出非原型上可枚举的key值,而Object.getOwnPropertyNames列出非原型上的所有key值(Symbol除外)
如何配置rem⭐⭐⭐
clientHeight、offsetHeight、scrollHeight有什么区别⭐⭐⭐
- clientHeight
- 用户可见内部高度+padding
- offsetHeight
- 总高度,算上滚动条
- scrollHeight
- 可滚动高度的+padding
- scrollTop
- 当前元素距离顶部的距
触底加载
- scrollTop + clientHeight >= scrollHeight - 50px
BOM和DOM的区别⭐⭐⭐
BOM就是window,包含windows(窗口)、navigator(浏览器)、screen(浏览器屏幕)、history(访问历史)、location(地址)等,浏览器相关的东西。bom是包含DOM的。
DOM是document, html相关的都在里面
倒计时用setTimeout来实现还是setInterval⭐⭐⭐⭐
- setTimeout
- 因为假如用setInterval的话,该程序执行需要105ms,而设置的间隔为100ms,则还没运行完最后的那5毫秒就会运行下一次的函数
promise相对于async…await的优缺点⭐⭐⭐
- promise
- 无法取消
- 错误无法被try…catch捕获,但是可以被catch方法捕获
- async传染力比较强
fetch优缺点 ⭐⭐⭐⭐
- fetch脱离了XHR,基于promise实现
- 对某些错误不会reject,比如状态码400、500
- fetch不支持超时timeout处理
- fetch默认不携带cookie,需要手动配置
- fetch没有办法监测请求进度,而xhr可以
秒传、分片传输、断点传输⭐⭐⭐⭐
- 秒传
- 文件上传前,服务器先对文件做MD5校验,如果服务器上有同样的文件,则返回一个新地址,如果不想秒传也可以,修改文件中的内容就可以了(改名字不行)
- 分片传输
- 利用Blob提供的slice方法把大文件分割为一个个小文件分别传输。全部上传完成时候由服务端进行归总整合
- 断点传输
- 在分片上传的基础上,分成一个个小文件之后,每个小文件上传完毕之后对其进行状态的存储(localStorage),如果中间发生网络断线或者刷新,下次可以接着上次的进度上传
e.target和e.currentTarget的区别⭐⭐⭐
e.target是点击的那个对象,e.currentTarget是绑定该事件的对象
JS性能优化的方式⭐⭐⭐⭐⭐
- 垃圾回收
- 闭包中的对象清楚
- 防抖节流
- 分批加载(setInterval,加载10000个节点)
- 事件委托
- 少用with
- requestAnimationFrame的使用
- script标签中的defer和async
- CDN
1. let、const
let 特点:
- 变量不能重复声明
- 块级作用域
- 不存在变量提升
- 不影响作用域链
const 特点:
- 定义时要赋初始值
- 一般常量使用大写(潜规则)
- 变量不能重复声明
- 常量值不能修改
- 不存在变量提升
- 块级作用域
- 对于数组和对象的元素修改,不算做对常量的修改,不会报错
2. 解构赋值
定义:ES6允许按照一定的模式从数组和对象中提取值,对变量进行赋值,称为解构赋值。
数组解构
讯享网
对象解构
3. 模板字符串
作用:
- 内容中可以直接出现换行符
- 变量拼接
4. 简化对象写法
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。
讯享网
5. 箭头函数
语法: () => { }
- 特点:
- this 是静态的. this 始终指向函数声明时所在作用域下的 this 的值
<ul><li>注:不能通过call、apply、bind方法直接修改它的 this 指向</li></ul> </li><li>不能作为构造实例化对象</li><li>不能使用 arguments 变量</li><li>没有原型属性</li></ul> </li><li><strong>箭头函数的简写</strong>:- 当形参有且只有一个的时,可省略小括号
- 当代码体只有一条语句的时候,可省略花括号, 此时 return 必须省略,而且语句的执行结果就是函数的返回值
6. 函数参数默认值
- 形参初始值 具有默认值的参数, 一般位置要靠后(潜规则)
- 与解构赋值结合
讯享网
7. rest参数
ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments
8. 扩展运算符
『 … 』 扩展运算符能将『数组』转换为逗号分隔的『参数序列』
讯享网
9. Symbol
- 特点:
- Symbol 的值是唯一的,用来解决命名冲突的问题
- Symbol 值不能与其他数据进行运算
- Symbol 定义的对象属性不能使用 for…in 循环遍 历 ,但是可以使用Reflect.ownKeys 来获取对象的所有键名
关于Symbol的更多信息@点击了解更多
10. 迭代器
11. 对ES6新增的Class的了解
一、Class的基本概念
本质:Class在ES6中是一种语法糖,其背后仍然是基于JS的原型继承。
目的:使JavaScript的面向对象编程更加直观和易于理解。
命名:类名建议使用大写字母开头,以区别于普通的函数或变量。
二、Class的声明与实例化
声明:使用class关键字后跟类名来声明一个类。类体中包含构造方法(constructor)和其他方法。讯享网
实例化:使用new关键字后跟类名及其实例化时所需的参数来创建类的实例。
三、Class的特性
:
每个类都必须有一个构造函数,用于初始化新创建的对象。
如果不显式定义构造函数,则会添加一个空的构造函数。
:
ES6的Class支持通过extends关键字实现继承。
子类可以继承父类的属性和方法,并可以覆盖或扩展它们。
子类构造函数中必须通过super()调用父类构造函数,且必须作为子类构造函数的第一个调用。
:
使用static关键字定义的方法,无法被类的实例调用,只能通过类本身调用。
静态方法通常用于实现与类的实例无关的功能。
:
TypeScript在ES6 Class的基础上增加了public、private和protected三个访问修饰符,用于控制类成员(属性和方法)的访问权限。
四、Class与原型链
ES6的Class在底层仍然是基于原型的。
当使用class关键字定义一个类时,JS引擎会自动创建一个构造函数,并将类中定义的方法添加到构造函数的原型对象上。
类的实例继承自构造函数的原型对象,因此可以访问原型对象上的方法。
五、使用场景
ES6的Class可以用于封装数据和行为,提高代码的可读性和可维护性。
它支持继承和多态,使得面向对象编程在JS中更加容易实现。封装axios的思路
在Vue项目中封装过axios。封装axios的目的是为了更方便地进行网络请求管理,主要步骤分为一下几步:
- 安装axios:使用npm或yarn安装axios
讯享网
- 创建axios实例:在项目中创建一个用于配置axios的模块
- 在vue项目中使用封装好的axios实例
讯享网
- 登录组件中示例:
map在项目中什么情况下使用
- 转换数组元素
- 提取对象数组中的特定属性
- 保持原始数据不变
- 处理复杂数据结构
- 数据过滤:配合filter()
typescript
面向对象
node.js的了解
算法
数据结构
bootstrap
鉴权
怎么做一个○中间有个x关闭按钮
讯享网
如果一个列表,给你好多条数据,没有分页,怎么优化
- 虚拟滚动:虚拟滚动技术可以提高性能,因为它只渲染当前可见区域内的数据,而不是整个列表。这样可以减少页面渲染的工作量,特别是在处理大量数据时。
使用第三方库如vue-virtual-scroller或vue-virtual-scroll-list
示例:使用 vue-virtual-scroller 插件实现虚拟滚动。
- 无限滚动:无限滚动允许用户滚动列表时动态加载更多数据,而不是一次性加载所有数据。这种方式可以提供更流畅的用户体验,同时减少页面加载时间。
示例:使用无限滚动实现动态加载数据。
讯享网
- 懒加载:对于图片等资源的懒加载,你可以使用Vue的指令或第三方库。但Vue本身不提供内置的懒加载指令,因此你可能需要自定义指令或使用如vue-lazyload这样的库。
使用vue-lazyload的例子:
首先,安装vue-lazyload:
然后,在你的Vue项目中引入并使用它:
讯享网
注意:将your-image-url.jpg替换为你的实际图片URL,并确保dist/error.png和dist/loading.gif是有效的路径(或者你可以指定其他路径或资源)。
- 搜索和过滤:允许用户通过搜索框输入关键字进行搜索,或者提供过滤选项来筛选数据,可以帮助用户快速找到他们感兴趣的内容,而不必浏览整个大量数据列表。
示例:添加搜索框和过滤功能来帮助用户查找特定数据。
- 数据缓存
- 数据压缩
如果给你一个草图,怎么做这个页面
- 分析草图:仔细观察草图,了解页面的结构、布局、内容和样式。
- 准备工作:
- 创建一个新的Vue.js项目(如果还没有)。
- 将草图中的设计元素(如颜色、字体、布局)转化为CSS样式。
- 页面布局:
- 使用Vue组件来组织页面结构,将页面拆分为多个组件,每个组件负责不同的功能区域。
- 使用HTML和CSS来实现草图中的布局。
- 添加样式:
- 使用CSS来为页面和组件添加样式,确保页面的外观与草图一致。
- 可以使用Flexbox或Grid布局来实现灵活的页面布局。
- 处理交互:
- 根据草图中的交互设计,添加相应的交互效果和动画。
- 使用Vue.js的响应式数据和事件处理机制来处理用户交互。
- 填充内容:
- 根据草图中的内容,添加文本、图片和其他元素到页面中。
- 可以使用静态数据或模拟数据来填充页面内容。
- 优化和调试:
- 在不同设备和浏览器上测试页面,确保页面在各种环境下都能正常显示和工作。
- 使用浏览器开发者工具进行调试,修复布局问题和样式错误。
- 部署:
- 将页面部署到服务器或静态托管服务上,确保用户可以访问到您的页面。
css隔行变色怎么实现
- 使用:nth-child()
讯享网
- 使用:nth-of-type()(针对表格)
- this 是静态的. this 始终指向函数声明时所在作用域下的 this 的值
- 宏任务:每次事件循环首先检查并执行一个宏任务
- 分为三个阶段




版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/173626.html