JavaScript前端面试题(高频)

1.null和undefined的区别

null 和 undefined基本同义,二者又有什么区别呢?
null表示没有对象,即该处不应该有值
1) 作为函数的参数,表示该函数的参数不是对象
2) 作为对象原型链的终点

undefined表示缺少值,即此处应该有值,但没有定义
1)定义了形参,没有传实参,显示undefined
2)对象属性名不存在时,显示undefined
3)函数没有写返回值,即没有写return,拿到的是undefined
4)写了return,但没有赋值,拿到的是undefined
null和undefined转换成number数据类型

null 默认转成 0
undefined 默认转成 NaN

2.get和post的区别,至少写出4点

  • get方式请求参数会显示在地址栏后面,post参数不显示在地址栏上面,get相对于post不安全(安全性)
  • get因为参数显示在地址栏,地址栏是有长度限制,一般用于发送文本数据是够用的,但是如果上传文件的话只能用post方式(数据量)
    • 谷歌 8kb
    • IE 2kb
  • get方式参数显示在地址栏,地址只能显示ACSII码表支持的字符,如果有中文或者空格会出现乱码问题,post不会(编码)
  • get方式请求的数据会默认被浏览器缓存,post则不会(缓存)

3.cookie localstorage sessionstorage区别,至少5点

(1)cookie一般存储比较重要的数据,前后端公用的数据,有一定的大小限制(4kb),有过期时间
(2)localStorage和sessionStorage存储的数据只能前端使用,相对于比较大(5M)
(3)localStorage存储的数据是永久的,除非用户自己手动清除缓存,否则会一直存在。sessionStorage存储的数据是会话级别的,关闭浏览器就会自动删除
(4)域的概念 一个域下面只能使用自己域里面的cookie
(5)cookie的过期时间是以服务器时间为准的

4.写出至少五种遍历数组的方式

(1)for循环
(2)forEach
(3)map
(4)for of
(5)filter
(6)some
(7)every

5.谈谈你对原型以及原型链理解,各5分

原型

  • 每一个函数都有一个自带属性叫做prototype,构造函数也有
  • 每一个对象都有一个自带属性叫做__proto__
  • 一般原型都要和构造函数结合使用
  • 构造函数的prototype就是new出来对象的__proto__

原型链

  • 每一个对象使用属性或者方法的时候会优先在自身查找 自身有就使用自身的
  • 自身没有会往它的__proto__里面查找,找到了就使用 找不到就为undefined

6.var let const的区别

(1)var声明的变量会挂载在window上,而let和const声明的变量不会(window)
(2)同一作用域下var可以声明同名变量,而let和const不能(同名变量)
(3)var声明变量存在变量提升,let和const不存在变量提升(变量提升)
(4)let和const声明形成块作用域(作用域)
(5)const一旦声明必须赋值,不能使用null占位,声明后不能再修改,如果声明的是复合类型数据,可以修改其属性

7.cookie的特点

  1. 前后端共用的数据空间(公用)
  2. 时效性 过期时间是以服务器时间为准的(时效)
  3. 域的概念 一个域下面只能使用自己域里面的cookie(同域)
  4. 大小 4kb 数量50条(大小数量)

8.什么是事件委托

在开发中,如果我们想要给一个元素绑定事件,需要获取到这个元素进行绑定,但如果元素是动态生成,无法获取从而无法绑定,
此时我们就需要利用冒泡原理把这个事件委托给这个元素的页面存在的父元素来绑定

9.如何实现事件委托

获取页面已经存在的父元素,0.给这个父元素绑定同类型的事件,利用冒泡原理子元素也会触发这个事件,在通过event.target
来缩小事件触发的范围。

10.值传递和引用传递的区别

(1)基础数据类型和复杂的数据类型在赋值的时候因为存储方式不一样,导致赋值的内容也不一样。(存储方式不一样导致赋值的内容也不一样)
(2)基础的数据类型之间赋值是直接将一个变量的数据拷贝给另外一个变量,一个变量的变化不会改变另外一个变量的数据,被称为值传递的过程。(基础数据类型)
(3)复杂数据类型之间的赋值是将一个变量的地址拷贝给另外一个变量,因为地址(引用)指向的数据是同一个位置,所以一个变量变化会导致另
一个也发生变化,这种赋值过程被称为引用传递。(复杂数据类型)

11.什么是跨域?

(1)因为浏览器出于安全考虑,有同源策略。也就是说,如果协议、域名或者端口有一个不同就是跨域,Ajax 请求会失败。(同源策略,协议域名端口号)

12.跨域的解决方案

(1)JSONP
JSONP 的原理很简单,就是利用script标签(没有跨域限制)的漏洞。通过script标签访问需要访问的后端的地址,后端返回一个函数调用的方式,将需要发送给前端的数据当成这个函数的参数,前端只需要定义一个同名的函数接受后端返回的数据即可。
JSONP使用简单且兼容性不错,但是只限于get请求,无法发送post请求
JSONP使用还需要后端的配合
此种记住已经不是ajax请求了,是script请求
(2)配置反向代理
因为同源策略是限制浏览器访问别人的服务器,我们可以绕过直接请求,先让我们浏览器请求自己的服务器,由自己的服务器请求别人的,拿到数据之后返回给我们的浏览器。这种只需要简单的配置即可(ajax请求)
(3)后端设置CORS

13.new关键字做了哪些事情

(1)new会创建一个空对象(创建一个空对象)
(2)new会将构造函数内部this指向到这个创建出来的对象(指向创建出来的对象)
(3)new会将创建对象的__proto__指向构造函数的prototype(对象的__proto__指向构造函数的protetype)
(4)new会返回这个创建出来的对象(返回创建出来的对象)

14.浏览器缓存的认识

(1)缓存机制是浏览器自带的机制,浏览器会将get请求访问到的资源缓存到本地,这样做的目的是为了提高用户的访问速度和节约用户的流量。
(2)但是缓存也会造成一些问题,有时候服务端文件发生变化名称还是之前老的名字,浏览器无法识别这个文件的变化,还会使用缓存中的文件。
(3)为了解决这个问题我们有时候需要在请求的过程中告诉浏览器我们不使用缓存,针对于get请求只要每次携带的参数变化浏览器就不会使用缓存文件,认为你要获取新的数据。

15.构造函数和普通函数以及箭头函数区别

构造函数在定义的时候和普通函数没有区别,只是定义的时候要求名称首字母大写。
箭头函数不可以当成构造函数使用,因为箭头函数的this指向问题
普通函数this指向看谁在调用这个函数,如果没有找到,一般是window的隐式调用
箭头函数this有两种说法:一种认为箭头函数没有this,一种认为箭头有this和外层的this一样
构造函数this指向当前的实例对象

16.this指向怎么看

(1)普通函数看调用
谁在用这个函数this就指向谁
找不到就是windows在调用
普通函数和定义没有关系
谁.函数()
(2)箭头函数看定义
箭头函数没有this用的是上级作用域里的this
箭头函数看箭头函数的定义位置,和谁调用无关

17.如何改变this指向

(1)call
(2)apply
(3)bind
bind不会立即调用这个函数,而是会返回一个改变了this指向的新函数,自己去调用这个新函数
call和apply传参方式不一样,call从第二个参数开始往后传实参,apply从第二个参数开始传数组

18.js作用域

(1)全局作用域
(2)局部作用域
块级作用域,函数作用域

19.什么是回调地狱,如何解决回调地狱问题

-1.回调函数中嵌套回调函数的情况就叫做回调地狱。回调地狱就是为是实现代码顺序执行而出现的一种操作,它会造成我们的代码可读性非常差,后期不好维护。

-2.如何解决:
(1)Promise 对象就是为了解决这个问题而提出的。它不是新的语法功能,而是一种新的写法,允许将回调函数的嵌套,改成链式调用。
promise只有两个状态resolve和reject,当它触发任何一个状态后,它会将当前的值缓存起来,并在有回调函数添加进来的时候尝试调用回调函数,如果这个时候还没有触发resolve或者reject,那么回调函数会被缓存,等待调用,如果已经有了状态(resolve或者reject),则立刻调用回调函数。并且所有回调函数在执行后都立即被销毁。
(2) ES6 co/yield方案
yield: Generator 函数是协程在 ES6 的实现,而yield是 Generator关键字, 异步操作需要暂停的地方,都用yield语句注明。
co: co 模块是著名程序员 TJ Holowaychuk 于 2013 年 6 月发布的一个小工具,用于 Generator 函数的自动执行。
(3)ES7 async/await 方案
async/await是es7的新标准,并且在node7.0中已经得到支持。
它就是 Generator 函数的语法糖,async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await,仅此而已。可以理解官方对co和Generator 封装方案。

20.如何实现继承

(1)原型链继承
(2)构造函数继承
(3)组合继承(父类实例作为子类原型,实现函数复用)
(4)class继承(ES6引入class关键字,class可以通过extends关键字实现继承)

21.什么是闭包

-1.含义
闭包使用的就是返回一个函数,这样函数作用域就不会被销毁,局部变量会在内存空间内。只要我们在调用这个函数,该函数内部有一个局部变量,返回的函数内部使用着这个局部变量,此时就可以访问到局部变量。
-2.使用场景
闭包一般在我们希望避免全局变量污染时会使用,我们使用一个局部变量,这样别人就无法覆盖我使用的变量
-3.条件
(1)返回一个引用数据类型(返回的是一个函数)
(2)必须有一个变量使用着这个函数的返回值
-4.优缺点
(1)优点
可以访问一个局部变量
可以延长一个局部变量的生命周期
可以避免全局变量污染问题
(2)缺点
占用内层空间,大量使用闭包会造成 栈溢出
由于闭包会一直占用内存空间,直到页面销毁,我们可以主动将已使用的闭包销毁,只有我们主动切断链接,将这个链接地址置为null,闭包才会被垃圾回收机制回收内存空间

22.什么是单例

保证整个系统中一个类只有一个对象的实例,实现这种功能的方式就叫单例模式。

  • 1、单例类只能有一个实例。
  • 2、单例类必须自己创建自己的唯一实例。
  • 3、单例类必须给所有其他对象提供这一实例。

23.什么是柯里化

-1.含义:是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。
把一个之前接收多个参数的函数变成多个接收单个参数的函数,本质上是将一个功能复杂的函数拆分成多个单一功能的子函数
-2.作用:
(1)可以简化参数,达到参数的复用
(2)可以实现一个函数的延迟调用

24.ES6新增特性

(1)const与let
(2) 模板字符串
(3)解构赋值
(4) 对象简写法
(5) for…of循环
(6) 展开运算符
(7)剩余参数(可变参数)
(8) ES6箭头函数
(9) 参数默认值
(10)类和继承
(11)模块化规范

25.什么是promise对象

-1.Promise对象是ES6( ECMAScript 2015 )对于异步编程提供的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。
-2.

26.如何解决异步

-1.回调函数(容易造成回调地狱)
-2.promise
-3.generator(属于微任务)
-4.async+await(可与promise混用)

27.防抖和节流

节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
防抖: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时

28.SPA及其优缺点

-1、优点:

1). 良好的交互体验
用户不需要重新刷新页面,获取数据也是通过Ajax异步获取,页面显示流畅。
2). 良好的前后端工作分离模式
单页Web应用可以和RESTful规约一起使用,通过REST API提供接口数据,并使用Ajax异步获取,这样有助于分离客户端和服务器端工作。更进一步,可以在客户端也可以分解为静态页面和页面交互两个部分。
3). 减轻服务器压力
服务器只用出数据就可以,不用管展示逻辑和页面合成,吞吐能力会提高几倍;
4). 共用一套后端程序代码
不用修改后端程序代码就可以同时用于Web界面、手机、平板等多种客户端;

-2、缺点:

1). SEO难度较高
由于所有的内容都在一个页面中动态替换显示,所以在SEO上其有着天然的弱势,所以如果你的站点对SEO很看重,且要用单页应用,那么就做些静态页面给搜索引擎用吧。
2). 前进、后退管理
由于单页Web应用在一个页面中显示所有的内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理,当然此问题也有解决方案,比如利用URI中的散列+iframe实现。
3). 初次加载耗时多
为实现单页Web应用功能及显示效果,需要在加载页面的时候将JavaScript、CSS统一加载,部分页面可以在需要的时候加载。所以必须对JavaScript及CSS代码进行合并压缩处理,如果使用第三方库,建议使用一些大公司的CDN,因此带宽的消耗是必然的。

29.pop、push、shift、unshift分别是什么,怎么用;

push 头部添加
pop 头部删除
unshift 尾部添加
shift 尾部删除

30.简述一下promise

JavaScript中的Promise是一种用于处理异步操作的方法,它可以让你通过一个单独的对象来跟踪异步操作的状态,并且具有管理处理程序的能力。Promise对象有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。当一个异步操作完成时,Promise对象的状态会改变,并且你可以通过相应的处理程序来捕获这些状态改变。这样可以让你更容易地管理复杂的异步代码,并且可以更好地处理错误和异常。

31.简述一下js中的设计模式

单例模式
策略模式
代理模式
迭代器模式
发布订阅模式-观察者模式
命令模式
模板方法模式

32.简述一下js中的数据结构

栈内存:javaScript中,数据类型分为基本数据类型和引用数据类型,基本数据类型七种包含:null、undefined、string、number、boolean、symbol、bigint 这几种。在内存中这几种数据类型存储在栈空间,我们按值访问。基本类型都存储在栈内存中,是大小固定并且有序的

堆内存:一般由操作人员(程序员)分配释放,若操作人员不分配释放,将由OS(操作系统)回收释放。分配方式类似链表。堆存储在二级缓存中。JavaScript 的数据类型除了原始类型,还有一类是 Object 类型,它包含:ObjectFunctionArrayDateRegExp

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不二哈

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

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

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

打赏作者

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

抵扣说明:

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

余额充值