js基础面试宝典

这篇博客涵盖了JavaScript的基础面试题目,包括数据类型、变量提升、作用域、闭包、递归等核心概念,还涉及到了堆栈、原型链、Es6新特性、事件循环机制、跨域、HTTP协议等相关知识,并探讨了小程序的特性和开发实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. JavaScript的数据类型都有什么?

基本数据类型:Number、String、Boolean、Null、Undefined
复杂数据类型:Object(Function、Array、Date、RegExp)

2. 什么是变量提升?

变量提升是当栈内存作用域形成时,JS代码执行前,浏览器会将带有var, function关键字的变量提前进行声明(值默认就是 undefined),定义 (就是赋值操作),这种预先处理的机制就叫做变量提升机制也叫预定义。

3.带 var 和不带 var 的区别?

(1)全局作用域中不带var声明变量虽然也可以但是建议带上 var声明变量,不带 var 的相当于给window对象设置一个属性罢了。
(2)私有作用域(函数作用域),带 var 的是私有变量。不带 var 的是会向上级作用域查找,如果上级作用域也没有那么就一直找到 window 为止,这个查找过程叫作用域链。
全局作用域中使用 var 申明的变量会映射到 window 下成为属性。

4.js 中的 堆栈

堆和栈都是运行时内存中分配的一个数据区,因此也被称为堆区和栈区;
(1)堆(heap)用于复杂数据类型(引用类型)分配空间,例如数组对象、object对象;它是运行时动态分配内存的,因此存取速度较慢。
(2)栈(stack)中主要存放一些基本类型的变量和对象的引用,(包含池,池存放常量),其优势是存取速度比堆要快,并且栈内的数据可以共享,但缺点是存在栈中的数据大小与生存期必须是确定的,缺乏灵活性

5.作用域

(1)作用域是指程序源代码中定义变量的区域。也就是程序可以生效并运行的空间。
(2)全局作用域是指变量可以在当前脚本的任意位置访问,拥有全局作用域的变量也被称为“全局变量”
(3)在函数内部声明的变量具有局部作用域,拥有局部作用域的变量也被称为“局部变量”,局部变量只能在其作用域中(函数内部)使用

6.js检测数据类型四种办法

(1)typeof对于基本数据类型判断是没有问题的,但是遇到引用数据类型(如:Array)是不起作用的
(2)instanceof可以用来判断数组和对象,但不能用于基础数据类型。
(3)constructor来判断数据的类型,但是除了null、undefined,因为他们不是由对象构建。
(4)Object.prototype.toString.call(); 任何类型都可以精准检测出来

7.闭包

(1)内部函数可以访问外部函数的值,该值会长期存储在内存中,因此产生了闭包
(2)闭包是一种保护私有变量的机制,在函数执行时形成私有的作用域,保护里面的私有变量不受外界干扰。 直观的说就是形成一个不销毁的栈环境, 闭包实现了传递值和功能的调用。
(3)优点:避免变量污染全局,变量的叠加使用
(4)缺点:因为常驻内存,如果有大量闭包不被释放,容易造成内存溢出

8.递归

(1)程序自我调用,简单理解就是函数自己调用自己。目的是为了处理不确定层级的相同数据结构的数据处理。
(2)优点:代码更简洁清晰,可读性更好;
缺点:时间和空间消耗比较大、很多计算都是重复的、调用栈可能会溢出

9.浅拷贝和深拷贝

(1)浅拷贝只是拷贝一层,对更深层次对象级别的只拷贝引用(地址)
(2)深拷贝拷贝多层,每一级别的数据都会拷贝
(3)Object.assign(target,...sources) es6新增方法可以浅拷贝
(4)JSON.parse(JSON.stringify(obj)) 可以实现暴力深拷贝
(5)一般深拷贝使用递归去实现

11. 字符串常用方法

(1)获取字符串长度:length
(2)获取字符串指定位置的值:charAt() 方法获取到的是指定位置的字符
(3)查询是否包含某字符:indexOf、lastIndexOf、includes、search。
(4)字符串拼接:出了使用+号,应该使用concat
(5)字符串分割成数组:split
(6)截取字符串:substr()、substring()和 slice()
(7)字符串大小写转换:toLowerCase转小写、toUpperCase转大写
(8)字符串转数字:parseInt转整数、parseFloat转小数

12.数组方法

(1)合并数组:concat
(2)指定字符数组转字符串:join
(3) 添加元素操作:push()尾部 和unshift()头部 
(4)shift() & pop() 删除元素操作
(5) sort() 数组排序,改变原数组
(6) reverse() 反转数组,改变原数组
(7)slice() 截取数组,不改变原数组
(8) splice() 更新数组,改变原数组
(9) indexOf() & lastIndexOf() 索引方法,不改变原数组
(10) find() & findIndex() 根据函数内的判断返回找到的数组内的第一个元素。不改变原数组。 (es6新增方法)
(11) forEach()、map()、filter()、some()、every() 迭代方法,不改变原数组。
(12) reduce()、reduceRight() 归并方法,不改变原数组
(13) keys()、values()、entries() 遍历数组方法,不改变原数组。 (es6新增方法)
(14) includes() 不改变原数组。 (es6新增方法)

13.对象

(1)创建对象的三种方式:
①var obj = {} 字面量
②New Object() 构造函数方式
③Object.create()  对象方法创建
(2)Object.entries(obj): 把对象转成键值对的数组
(3)Object.definedProperty() 监听对象属性的变化,vue2的数据响应式原理。
(4)Object.assign() 合并对个对象为一个对象
(5)Object.values() 把对象的值序列化为数组
(6)Object.keys() 把对象的属性名序列化为数组

14.JavaScript的基本规范?

(1)不要在同一行声明多个变量
(2)使用 ===或!==来比较true/false或者数值
(3)switch必须带有default分支
(4)函数应该有返回值
(5)for if else 必须使用大括号
(6)语句结束加分号
(7)命名要有意义,使用驼峰命名法

15.栈和堆的区别?

(1)栈(stack):由编译器自动分配释放,存放函数的参数值,局部变量等;
(2)堆(heap):一般由程序员分配释放,若程序员不释放,程序结束时可能由操作系统释放。

16.谈谈this的理解

(1)this总是指向函数的直接调用者(而非间接调用者)
(2)如果有new关键字,this指向new出来的那个对象
(3)在事件中,this指向目标元素,特殊的是IE的attachEvent中的this总是指向全局对象window。

17.什么是window对象? 什么是document对象?

(1)window对象代表浏览器中打开的一个窗口。
(2)document对象代表整个html文档。实际上,document对象是window对象的一个属性。

18. 同步和异步的区别?

(1)同步:每次程序只能执行一件事情,所有的执行程序需要排队。
(2)异步:同时可以做多件事情

19.JS垃圾回收机制?

(1)标记清除:这个算法把“对象是否不再需要”简化定义为“对象是否可以获得”。
①这个算法假定设置一个叫做根(root)的对象(在Javascript里,根是全局对象)。定期的,垃圾回收器将从根开始,找所有从根开始引用的对象,然后找这些对象引用的对象。从根开始,垃圾回收器将找到所有可以获得的对象和所有不能获得的对象。
(2)引用计数:这是最简单的垃圾收集算法。此算法把“对象是否不再需要”简化定义为“对象有没有其他对象引用到它”。如果没有引用指向该对象(零引用),对象将被垃圾回收机制回收。该算法有个限制:无法处理循环引用。两个对象被创建,并互相引用,形成了一个循环。它们被调用之后不会离开函数作用域,所以它们已经没有用了,可以被回收了。然而,引用计数算法考虑到它们互相都有至少一次引用,所以它们不会被回收。

20 null,undefined的区别?

(1)null表示一个对象被定义了,但存放了空指针,转换为数值时为0。
(2)undefined表示声明的变量未初始化,转换为数值时为NAN。
(3)typeof(null) -- object;
(4)typeof(undefined) -- undefined

21.请描述一下 cookies,sessionStorage 和 localStorage 的区别?

(1)共同点:都是保存在浏览器端,且同源的。
(2)区别
①cookie 数据始终在同源的 http 请求中携带(即使不需要),即 cookie 在浏览器和服务器间来回传递。
②而 sessionStorage 和 localStorage 不会自动把数据发给服务器,仅在本地保存。
③cookie 数据还有路径(path)的概念,可以限制 cookie 只属于某个路径下。
④存储大小限制也不同,cookie 数据不能超过 4k,同时因为每次 http 请求都会携带 cookie,所以 cookie 只适合保存很小的数据,如会话标识。
⑤sessionStorage 和 localStorage 虽然也有存储大小的限制,但比 cookie 大得多,可以达到 5M 或更大。
⑥数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie 只在设置的 cookie 过期时间之前一直有效,即使窗口或浏览器关闭。
⑦作用域不同,sessionStorage 在不同的浏览器窗口中不共享,即使是同一个页面;cookie 和 localStorage 在所有同源窗口中都是共享的。

22从敲入 URL 到渲染完成的整个过程,包括 DOM 构建的过程?

(1)用户输入 url 地址,浏览器根据域名寻找 IP 地址
(2)浏览器向服务器发送 http 请求,如果服务器段返回以 301 之类的重定向,浏览器根据相应头中的 location 再次发送请求
(3)服务器端接受请求,处理请求生成 html 代码,返回给浏览器,这时的 html 页面代码可能是经过压缩的
(4)浏览器接收服务器响应结果,如果有压缩则首先进行解压处理,紧接着就是页面解析渲染
(5)解析渲染该过程主要分为以下步骤:解析 HTML、构建 DOM 树、DOM 树与 CSS 样式进行附着构造呈现树
(6)布局
(7)绘制

23.原型链--函数与对象的关系

(1) Function函数是所有函数的祖先函数
​
(2) 所有构造函数都有一个prototype属性,叫原型对象,也称为显式原型
​
(3) 所有原型对象都有一个constructor属性,指向被new的构造函数
​
(4) 被new出来的对象叫实例对象,它们都有一个__proto_对象,叫隐式原型,它指向构造函数的prototype对象
​
(5) 原型链就是当从对象上获取属性的时候,它的查找顺序先从对象自身找,如果没有就沿着__proto__一直找,这个寻找过程叫原型链

24.Es6的class类?

(1)Class类是使用函数的prototype对象封装的,可以实现封装,多态和继承。
(2)类有constructor函数作为初始化类时调用的第一个构造函数
(3)类使用extends实现类之间的继承

25.var与let/const的区别

(1)let/const 声明的变量只在let/const 命令所在的代码块 {} 内有效,在 {} 之外不能访问。
(2)使用 let/const关键字声明的全局作用域变量不属于 window 对象,所以不可以用window. 变量名的方式访问这些变量。
(3)Var会提升,let const不会
(4)Var可以重复声明,let const不可以
(5)Let声明的变量可以重复赋值,const不可以
(6)Let和var都用于声明变量,const用于声明常量

26 模板字符串

(1) 使用一对反引号包裹字符串,使用${}放置变量
​
(2) 优点:可以多行字符串换行书写,可以使用变量和表达式,不用用+拼接了

27 解构赋值简介

(1) 解构赋值:按照一定的模式,从数组 / 对象中提取值,并对变量进行赋值
​
(2) 数组解构按位置解构
​
(3) 对象解构按属性名解构

28 js function和 箭头函数区别?

(1) 箭头函数不可以当做构造函数,也就是说,不可以使用 new 命令,否则会抛出错误。
​
(2) this、arguments、caller等对象在箭头函数体内都不存在。
​
(3) 箭头函数this指向上一层作用域,function的this指向调用它的对象

29函数重载

(1)  函数名相同,函数的参数不同 (包括参数个数和参数类型),根据参数的不同去执行不同的操作。

30js 函数尾调用

(1) 在函数的最底部发起另一个函数的调用就是函数尾调用
​
(2) 目的时为了节约性能
​
(3) 一个函数返回的是另一个函数的调用结果,那么就被称为尾调用

31 链式调用

(1) 在构造函数中创建方法时,return this 返回当前调用方法的对象,可以实现链式调用方法

32箭头函数的this指向

主要是用来改变this的指向,就是说如果创建一个构造函数,我们在里面再加一个函数,它们两个的this指向不同,第一个指向实例的本身,而第二个默认指向window
​
因为箭头函数有一个特性,就是不绑定this,会捕获其定义时所在的this指向作为自己的this

js事件循环机制

js是单线程,所以有三个任务队列,同步任务,微任务,宏任务,每次先执行同步任务,在执行微任务,在执行宏任务,全部完成后再从头开始,这样周而复始的循环叫做事件循环

JS继承

盗用构造函数:通过call,apply将要继承的函数的this指向当前的this。缺点:无法继承原型链上的属性和方法。
​
原型链继承:直接new一个对象赋值给prototype,缺点就是所有的属性都会被共享。
​
组合继承:结合盗用构造函数和原型链继承两种方式,既继承了原型链上的方法,又将构造函数中的属性添加到了实例对象上。

跨域解决方式

Jsonp:利用script标签的src属性不受同源策略的限制,可以利用src去调用后端的接口。缺点:必须定义一个全局方法。
​
反向代理:就是利用一个中间服务将我们发起的请求转发到服务端,并且在返回的时候在响应头里添加允许跨域的头。vue中的配置方法:在vue.config.js中配置proxy代理。
​
cors:后端在响应头里添加允许跨域的头,这个是后端解决的。

什么是跨域

协议域名端口一致是同源策略,如果违反了同源策略,则会造成跨域。

http和https的区别

HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。简单来说,HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。

有哪些请求

get:把参数放在url中,所以传输的数据是透明的,有大小限制。
​
post:把请求数据放在body中,传输数据大,请求比get慢,因为会先发送一个options预请求去询问服务器能否接受这个请求。
​
put:更新。
​
delete:对这个资源的删操作。但要注意:客户端无法保证删除操作一定会被执行,因为http规范允许服务器在不通知客户端的情况下撤销请求。
​
patch:有一个对象你要更新有十个属性,但只能更新两个属性,只能部分。
​
options:用于获取当前URL所支持的方法。若请求成功,则会在http头中包含一个名为"Allow"的头,值是所支持的方法,如get和post

三次握手

第一次握手:客户端发送网络包,服务端收到了。这时候服务端的都结论:客户端的发送能力、服务端的接受能力正常。
​
第二次握手:服务端收到网络包会给客户端响应,这时候服务端发送网络包,客户端收到了,此时的服务端得出结论:服务端的发送能力没有问题,因为客户端没有给服务端响应。
​
第三次握手:客户端收到网络包后,给服务端响应,这时候客户端给服务端发送网络包,服务端收到了,此时服务端得出结论:客户端的发送、接受能力没有问题,自己的发送,接受能力也没有问题。

token值会过期吗?怎么处理?

会,token有失效时间,在请求的响应拦截器中去判断状态码是否为401,如果是401 token失效,清空token,弹出警告框告知用户跳转到登录页面重新登录

动态路由的实现方式

后端会根据当前登录人的角色返回相应的权限菜单,我们会在全局路守卫中进行判断,如果当前进入的路径在这个权限菜单中,则可以跳转,如果不在的话我们就跳转到首页中

Object.defineProperty()方法有何作用(选背)

 1.语法
​
Object.defineProperty(obj, prop, descriptor)
​
 2.定义
​
在对象上定义一个新属性
​
vue.js是采用`数据劫持`结合`发布者-订阅者模式`的方式,通过`Object.defineProperty()`来劫持各个属性的`setter`,`getter`,在数据变动时发布消息给订阅者,触发相应的监听回调来渲染视图
​
3.参数
​
obj 目标对象。
​
prop 定义或修改的属性的名字。
​
descriptor 定义或修改的属性描述符。
​
##### 4.返回值
​
返回被操作的对象,即返回 obj 参数
​

怎么将一个数据放入到数组中

向数组的末尾添加元素(push)
​
向数组的开头添加元素(unshift)
​
var arr=[...arr1,...arr2]

怎么让一个元素水平垂直都居中

  1. 使用定位和margin(必须知道子元素的宽高)

  2. 使用定位和transform(不用知道宽高)

  3. 使用弹性盒

怎么让css做一个小三角

给元素设置宽度 高度都为0,然后设置边框的为50 然后透明,想要哪个方向的三角让当前方向重新设置边框即可

怎么实现小程序的组件通信

小程序父传子:
​
1. 在页面中或者组件中的wxml的组件标签上用自定义属性挂载要传输的数据
​

<标签 自定义属性名=“{{变量}}”></标签>

<Head suibian="classname"></head>

​
2. 在子组件中通过properties来接受数据
​
```
properties: {
    自定义属性名:类型
  },
```
​
小程序子传父:
​
1. 在页面或者父组件的子组件标签上自定义事件挂载要执行的方法
2. 在子组件中通过this.triggerEvent("事件名","参数")来触发自定义事件

html5和css3新增加了哪些

 css3新特性
​
1. 选择器
2. 背景和边框
3. 文本效果
4. 2D/3D 转换 — 变形(transform)、过渡(transtion)、动画(animation)
5. 媒体查询 @media
6. 弹性盒子flex
​
###### 1. h5新增特性:
​
1. 语义化标签:header、footer、section、nav、aside、article
   增强型表单:input 的多个 type
   新增表单属性:placehoder、required、min 和 max
   音频视频:audio、video
   canvas 画布  kan  wa si
   地理定位
   拖拽
   本地存储:
   localStorage 没有时间限制的数据存储;
   sessionStorage, session 的数据存储,当用户关闭浏览器窗口后,数据会被删除
   新事件:onresize、ondrag、onscroll、onmousewheel、onerror、onplay、onpause
   WebSocket:建立持久通信协议

小程序

小程序授权登录

小程序登录授权
登录按钮注册点击事件,
在事件中用微信中的wx.login的方法来获取code,
创建一个对象来收需要的值 ,
然后把这个对象作为参数去请求登录接口,
如果登录成功就会返回一个token的值,
储存到本地缓存中并跳转到支付页面。

生命周期

 小程序生命周期:
​
 onLaunch:小程序初始化完成(全局只触发一次)
​
 onShow:小程序启动,或从后台切入前台时触发
​
 onHide:小程序从前台切入后台时调用
​
 onError:小程序发生脚本错误,或者api调用失败时触发,会带上错误信息
​
 onPageNotFound:小程序要打开的页面不存在时触发,会带上页面信息回调该函数
​
 页面的生命周期:
​
 onLoad:页面加载时触发
​
 onShow:页面显示时触发
​
 onReady:页面初次渲染完成触发
​
 onHide:页面隐藏时触发
​
 onUnload:页面卸载时触发
​
​
​
 页面执行时的钩子:
​
 onPullDownRefresh:监听用户下拉动作
​
 onReachBottom:页面上拉触底事件
​
 onShareAppMessage:用户点击右上角转发
​
 onPageScroll:页面滚动触发事件
​
 onTabItemTap:当前是Tab页,点击Tab时触发

5、路由跳转几种方式以及它们的区别

 1、wx.navigateTo()
​
 保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面。
​
 2、wx.switchTab()
 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。
​
 3、wx.redirectTo()
 关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面。
​
 4、wx.navigateBack()
 关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages 获取当前的页面栈,决定需要返回几层。
 注意:此方法返回上个页面,页面不会重新加载。
​
 5、wx.reLaunch()
 关闭所有页面,打开到应用内的某个页面。
​
 6、导航组件:,跳转方式默认为navigator,可通过open-type属性改变跳转方式。

用户授权包括哪些授权

 获取当前的地理位置、速度:wx.getLocation(Object object)
​
 获取手机号:需要将 button 组件 open-type 的值设置为 getPhoneNumber,当用户点击并同意之后,可以通过 bindgetphonenumber 事件回调获取 到动态令牌code,然后把code传到开发者后台,并在开发者后台调用微信后台提供的 phonenumber.getPhoneNumber 接口,消费code来换取用户手机 号。每个code有效期为5分钟,且只能消费一次。
​
 获取用户信息:wx.getUserInfo(Object object) (旧api)

小程序如何实现分包

小程序大小限制

· 整个小程序所有分包大小不超过 8M
​
 · 单个分包/主包大小不能超过 2M

你是怎么封装微信小程序的数据请求的?

一、将所有的接口放在统一的js文件中并导出

二、在app.js中创建封装请求数据的方法

三、在子页面中调用封装的方法请求数据

http.js文件
const baseURL = "基准地址"
function http(params) {
  wx.showLoading({
    title: '拼命加载中...',
  })
  return new Promise((resolve, reject) => {
    wx.request({
      ...params,
      url: baseURL + params.url,
      success: res => {
        if (res.statusCode === 200) {
          wx.hideLoading()
          return resolve(res)
        } else {
          wx.hideLoading()
          return reject('请查看参数、方法以及代码')
        }
      },
      fail: err => {
        wx.hideLoading()
        return reject(err)
      },
      complete: () => {
        wx.hideLoading()
      }
    })
  })
}
export default http
home.js文件
export async function getBanner(data) {
  return await http({
    url: "banner/list",
    method: "GET",
    data
  })
}
improt{getBanner} from "home.js"
getBanner().then(res=>{
    //函数体代码
})
​

小程序的双向数据绑定和Vue有何不同

小程序直接this.data的属性是不可以同步到视图的,必须调用:this.setData({})

22、小程序的wxml和html有什么区别?

HTML是用于创建网页的语言。通过使用HTML标记标签创建html文档来创建网页。

小程序的wxss和css有什么区别?

 WXSS(WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式。
​
 WXSS 用来决定 WXML 的组件应该怎么显示。
​
 为了适应广大的前端开发者,WXSS 具有 CSS 大部分特性。同时为了更适合开发微信小程序,WXSS 对 CSS 进行了扩充以及修改。
​
 与 CSS 相比,WXSS 扩展的特性有:
​
 尺寸单位

23.Ajax的原理及步骤

Ajax的原理简单来说通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用JavaScript来操作DOM而更新页面

步骤:

1:创建XMLHttpRequest对象,也就是创建一个异步调用对象

2:建立连接

3:发送请求

4:设置函数监控状态,接收数据。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Pinia-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值