1.Js的数据类型有哪些他们的区别是什么
基本数据类型:Number String Boolean Null Undefined Symbol BigInt(ES6) (直接存储在内存中的,占用固定的内存空间;赋值是通过将值直接复制给变量来完成的;作为参数传递时,传递的是值的副本)
引用数据类型 :狭义的对象(object)、 数组(array)、函数(function) (引用数据类型的变量实际上存储的是对象在内存中的引用,通过引用访问和操作对象的属性和方法;赋值是将对象的引用赋给变量;作为参数传递时,传递的是引用的副本)
2.判断数据类型有几种方法
typeof运算符:
无法分辨Array、null和Object
instanceof 运算符:
原理是检查右边构造函数的原型对象(prototype),是否在左边对象的原型链上;
等同于:右边构造函数.prototype.isPrototypeOf(左边对象)
因此同一个实例对象,可能会对多个构造函数都返回true。
var d = new Date();
d instanceof Date // true
d instanceof Object // true
Object.prototype.toString.call方法
不能细分为谁谁的实例
3.作用域和作用域链
作用域:规定变量和函数的可使用范围称作作用域
作用域链:每个函数都有一个作用域,查找变量或者函数时,需要从局部作用域到全局作用域依次查找,这些作用域的集合称作作用域链
4.原型和原型链
原型:原型分为隐式原型和显式原型,每个对象都有一个隐式原型,它指向自己的构造函数的显式原型 原型链:每个对象都拥有一个原型对象,同时原型对象也可能拥有原型,这样一层一层,最终指向 null ,这种关系被称为原型链。
5.什么是闭包
闭包是什么:JS中内层函数可以访问外层函数的变量,使内部私有变量不受外界干扰,起到保护和保存的作用,我们把这个特性称作闭包。 好处: 隔离作用域,保护私有变量; 让我们可以使用回调,操作其他函数内部; 变量长期驻扎在内存中,不会被内存回收机制回收,即延长变量的生命周期; 坏处:内层函数引用外层函数变量,内层函数占用内存。如果不释放内存,过多时,易引起内存泄露。 引用场景: for循环中的保留i的操作 、防抖(多次触发只执行最后一次)和节流 (规定时间内只触发第一次)
6.内存泄露、垃圾回收机制
内存泄露:指我们无法在通过js访问某个对象,而垃圾回收机制却认为该对象还在被引用,因此垃圾回收机制不会释放该对象,导致该块内存永远无法释放,积少成多,系统会越来越卡以至于崩溃
垃圾回收机制:就是垃圾收集器按照固定的时间间隔,周期性地寻找那些不再使用的变量,然后将其清楚或释放内存。(标记清除/引用计数)
7.浅拷贝和深拷贝
浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。
深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改变原对象。
8.如何改变this指向(call、apply与bind区别)
call、bind、apply 都是 JavaScript 中用于改变函数执行上下文(即 this 指向)的方法。
传参: call、bind可以传递很多个参数,apply只有两个参数,第一个参数要绑定的对象、第二个参数为数组;
返回: call和apply方法是直接调用函数并改变函数上下文,而bind方法则是返回一个新函数,稍后调用时绑定指定的上下文。
9.箭头函数和普通函数的区别
箭头函数是普通函数的简写,但是它不具备很多普通函数的特性;
箭头函数的this指向它定义时所在的对象,而不是调用时所在的对象;
没有arguments对象,不能使用arguments;
不会进行函数提升;
不能作为构造函数。
10.什么是web缓存?
web缓存主要指的是两部分:浏览器缓存和http缓存。
浏览器缓存包括:
localStorage:永久保存,以键值对保存,存储空间5M。 sessionStorage:关闭页签/浏览器时清空,存储空间5M。 cookie:随着请求发送,通过设置过期时间删除(大概4kb)。 localStorage/sessionStorage是window的属性,cookie是document的方法。
http缓存:当Web请求抵达缓存时, 如果本地有“已缓存的”副本,就可以从本地存储设备而不是原始服务器中提取这个文档。
优点:
减少不必要的网络传输,节约宽带(就是省钱)
更快的加载页面(就是加速)
减少服务器负载,避免服务器过载的情况出现。(就是减载)
缺点:占内存(有些缓存会被存到内存中)
http缓存又分为强制缓存和协商缓存。
11.从 URL 输入到页面展现到底发生什么?
首先进行 DNS
域名解析,找到真实 IP
,向服务器发起请求,服务器交给后台处理完成后返回数据,浏览器接收⽂件( HTML
、JS
、CSS
、图象等)并对加载到的资源进⾏语法解析,从而构建DOM树等相应的内部数据结构并渲染页面。
12.setState是同步的还是异步的?
setState在React合成事件和生命周期方法中是异步的,在setTimeout和原生事件处理中是同步的。但是,从React 18开始,所有的setState调用都会自动进行批量处理(异步)。
13.前端性能优化
首屏关键css采用内联式;
异步加载css;
资源压缩;
合理使用选择器:
不要嵌套使用过多复杂选择器,最好不要三层以上
使用id选择器就没必要再进行嵌套
通配符和属性选择器效率最低,避免使用
减少使用昂贵的属性,例如:box-shadow等;
不使用@import:@import
会影响浏览器的并行下载,使页面在加载时增加额外的延迟,增添了额外的往返耗时,而且多个@import
可能会导致下载顺序紊乱。
14.前端首屏加载优化
减少入口文件体积,例如使用路由懒加载;
静态资源本地缓存,例如采用http缓存和localStorage;
UI框架按需加载,例如Element UI按需引入要使用的组件;
组件重复打包,例如在webpack
的config
文件中,修改CommonsChunkPlugin
的配置minChunks: 3,表示会把使用3次及以上的包抽离出来,放进公共依赖文件,避免了重复加载组件
图片资源压缩,例如使用雪碧图、使用线字体图标
使用SSR。
15.为什么使用vuex?
组件间数据共享:Vuex可以将数据共享给多个组件共同使用,避免了数据的重复获取和频繁更新,提高了代码的效率和复用性。
复杂状态的管理:当项目中的状态和数据交互变得复杂时,Vuex可以通过集中式存储和管理,将状态的变化和交互逻辑统一管理,提高了代码的可维护性和可读性。
异步操作的处理:Vuex可以将异步操作进行集中处理,使得异步操作的流程更加清晰和易于管理,也可以避免异步操作带来的错误和风险。
用户状态的管理:Vuex可以用于管理用户的登录状态、个人信息等敏感信息,使得应用更加安全和稳定。
代码的组织和模块化:Vuex可以将复杂的业务逻辑和状态管理进行模块化,使得代码更加清晰、易于理解和维护。
可预测性和调试:Vuex提供了一种可预测的状态管理模式,可以清晰地了解状态的变化和流向,方便进行调试和测试。
16.Webpack打包流程。
首先会从配置文件和 Shell 语句中读取与合并参数,并初始化需要使用的插件和配置插件等执行环境所需要的参数;初始化完成后会调用Compiler的run来真正启动webpack编译构建过程,webpack的构建流程包括compile(开始编译)、make(从入口点分析模块及其依赖的模块,创建这些模块对象 )、build(构建模块)、seal(封装构建结果)、emit阶段,执行完这些阶段就完成了构建过程。
17.js事件循环机制
JS 主线程不断的循环往复的从任务队列中读取任务,执行任务,这种运行机制称为事件循环(event loop)
浏览器的事件循环(event loop)中分成宏任务和微任务。JS 中任务分成同步任务和异步任务。
-
宏任务(macro task)
JS 中主栈执行的大多数的任务,例如:定时器,事件绑定,ajax,回调函数,node中fs操作模块等就是宏任务
-
微任务(micro task)
promise, async/await, process.nextTick等就是微任务。
JS 中任务的执行顺序优先级是:主栈全局任务(宏任务) > 宏任务中的微任务 > 下一个宏任务。所以 promise(微任务) 的执行顺序优先级高于setTimeout定时器。
18.服务端渲染(SSR)
服务端渲染 (SSR):将组件在服务端直接渲染成 HTML 字符串,作为服务端响应返回给浏览器,最后在浏览器端将静态的 HTML“激活”(hydrate) 为能够交互的客户端应用。
优点:
更快的首屏加载:无需等到所有的 JavaScript 都下载并执行完成之后才显示。数据获取过程在首次访问时在服务端完成,相比于从客户端获取,可能有更快的数据库连接。
统一的心智模型:可以使用相同的语言以及相同的声明式、面向组件的心智模型来开发整个应用,而不需要在后端模板系统和前端框架之间来回切换。
更好的 SEO:搜索引擎爬虫可以直接看到完全渲染的页面。
19.Vue2和Vue3的响应式原理
Vue2通过Object.defineProperty()递归设置对象每个属性的set和get,从而实现响应式,但是因为是对属性的劫持,所以新增和删除无法被监控到,因此添加了$set和$delete来作为补充;
Vue3通过ES6的Proxy来拦截和代理对象的多种操作,劫持的是整个对象,而不是单个属性,通过Proxy的捕获器,捕获对对象的所有操作,从而使得新增属性、删除属性、数组操作都能被监控。只有在访问嵌套对象时才会动态代理,而不是一次性递归遍历整个对象。
20.说说你对插槽的理解?
插槽本质上是对子组件的扩展,通过<slot>插槽向子组件内部指定位置传递内容,分为默认插槽、具名插槽和作用域插槽三种。
标签:缓存,函数,记录,对象,作用域,原型,内存,一些 From: https://www.cnblogs.com/serendipity-echo/p/18594355