【JavaScript精华系列】JavaScript高级程序面试题汇总

三年前端开发人员这样背面试题 迟早进大厂系列 玩转 JavaScript 。点赞、收藏、评论、关注、三连支持!

在这里插入图片描述

文章目录

一、闭包

  • 什么是闭包
    • 闭包就是在一个函数里创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用域链
  • 闭包特性
    • 函数内部在嵌套函数
    • 内部函数可以引用外层的参数和变量
    • 参数和变量不会被垃圾回收机制回收
  • 我对闭包的理解
    • 使用闭包主要是为了设置私有方法和变量,优点是避免全局变量污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄漏。
    • 闭包的两个用处是:一是可以读取函数内部的变量,二是让这些变量始终保持在内存中
    • 封装对象的私有属性和私有方法
  • 闭包的好处与坏处
    • 好处:能够实现封装和缓存等
      • 坏处:消耗内存,不正当使用造成内存泄漏
  • 使用闭包注意点
    • 不能滥用闭包
    • 在退出函数之前,将不使用的局部变量全部删除

二、作用域链的理解

  • 他的作用是保证执行环境有权访问的变量和函数是有序的,作用域链的变量只能向上访问,不能向下访问,访问到window对象即被终止
  • 作用域就是变量与函数的可访问范围,作用域控制着变量与函数的可见性与生命周期

三、JavaScript原型,原型链?特点?

  • 原型:每个对象都会在内部初始化一个prototype属性,即原型
    • javascript的所有对象都有一个__proto__内部属性,这个属性对应的就是这个对象的原型
    • 除了原型__proto__之外,还预置了prototype属性
  • 原型链:如果这个对象不存在这个属性,那么就会去prototype里找这个属性,这个prototype又会有自己的prototype,一直下去,这就是原型链的概念
  • 关系:instance.constructor.prototype = instance.__proto__
  • 原型特点:javascript对象通过引用来传递的,当修改原型时,与之相关的对象也会继承这一改变

四、事件代理

  • 又称事件委托,就是把原本需要绑定的事件委托给父元素,让父元素担当事件监听的职务
  • 事件代理的原理是DOM元素的事件冒泡,使用事件代理好处是可以提高性能
  • 可以大量节省内存占用,减少事件注册
  • 可以实现新增子元素时无需再次对其绑定

五、JavaScript如何实现继承

  • 构造继承
  • 原型继承
  • 实例继承
  • 拷贝继承
  • 原型机制或applycall方法实现(建议使用构造函数与原型混合方式)

六、new操作符具体干了什么

  • 创建一个空对象,并且this变量引用该对象,同时还继承了该函数的原型
  • 属性方法被加到this引用的对象中
  • 新创建的对象由this所引用,并且最后隐式的返回this

七、Ajax原理

  • 原理

    • 在用户和服务器之间加了一个中间层(Ajax引擎),通过XmlHttpRequest对象向服务器发异步请求,从服务器获取数据,然后用JavaScript操作DOM,更新页面。
  • 代码

    • var xhr = null
      xhr = new XMLHttpRequest()
      xhr.open('get',url,true)
      xhr.send(null)
      xhr.onreadystatechange = function(){
      	if(xhr.readyState == 4) {
      		if(xhr.status == 200){
      			success(xhr.responseText)
      		}else {
      			fail && fail(xhr.status)
      		}
      	}
      }
      
  • 优缺点

    • 优点:
      • 通过异步模式,提升用户体验
      • 优化了浏览器服务器之间的传输,减少了不必要的数据往返,减少了带宽占用
      • ajax可实现动态不刷新
    • 缺点
      • 安全问题
      • 对搜索引擎支持比较弱
      • 不容易调试

八、如何解决跨域

  • ​ 跨域是什么

    • 浏览器同源策略SOP是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心,最基本的安全功能,如果没有他,浏览器会受到xss、CSFR等攻击。
    • 同源:协议+端口+域名 完全相同
  • 解决方法

    • jsonp(使用DOM里的script标签)

      var script = document.createElement('script');
      script.type = 'text/javascript';
      
      // 传参并指定回调执行函数为onBack
      script.src = 'http://www.....:8080/login?user=admin&callback=onBack';
      document.head.appendChild(script);
      
      // 回调执行函数
      function onBack(res) {
          alert(JSON.stringify(res));
      }
      
      
    • nginx代理

    • nodejs中间件代理

    • 后端在头部信息里设置安全域名

九、异步加载js方法

  • 设置script属性async="async"
  • 动态创建script DOM
  • XMLHttpRequest脚本注入
  • 异步加载库LABjs
  • 模块加载器Seajs

十、哪些操作会造成内存泄漏

  • 什么是JavaScript内存泄漏:指对象不需要还存在时,导致占用的内存不能使用或回收
  • 未使用var 声明的全局变量
  • 闭包函数
  • 循环引用
  • 控制台日志(console.log)
  • setTimeout的第一个参数使用字符串而不是函数的话,会引发内存泄漏

十一、XML和JSON的区别

  • 数据体积方面
    • json相对xml来说,数据的体积小,传输速度更快
  • 数据交互方面
    • json与JavaScript的交互更加方便
  • 数据描述方面
    • json对数据的描述性比xml较差
  • 传输速度方面
    • json的速度远大于xml

十二、设计模式

一个抽象的概念,是一种编写代码的方式,可以让人更加容易阅读、维护以及复用

  1. 工厂模式
  2. 单例模式
    1. 比如全局缓存、全局管理状态,只需一个对象即可
  3. 适配器模式
    1. 解决两个接口不兼容的情况
  4. 装饰模式
    1. 给对象添加功能
  5. 代理模式
  6. 发布-订阅者模式
  7. 外观模式

十三、js定义对象的方法

  • 对象字面量:var obj = {}
  • 构造函数:var obj = new Object()
  • Object.create()var obj = Object.create(Object.prototype)

十四、js的基本数据类型与引用数据类型

  • 基本数据类型:
    • undefined
    • null
    • boolean
    • number
    • string
    • symbol
  • 引用数据类型:
    • object
    • array
    • function

十五、JavaScript基本规范

  • 不在一行声明多个变量
  • 使用===/!==来比较true/false或者数值
  • 使用对象字面量来替代new Array这种形式
  • 不使用全局函数
  • switch语句必须带有default分支
  • if语句必须使用大括号
  • fon-in循环中的变量应该使用var关键字明确限定作用域

十六、null跟undefined区别

  • undefined 表示不存在的这个值,表示缺少值,还没有定义
  • 例如变量被声明了,但是没有赋值,就等于undefined
  • null表示一个对象被定义了,值为空值,是一个空对象,没有任何属性方法
  • 验证null时,一定要用===

十七、js延迟加载方法

  • 设置script属性defer="defer"
  • 动态创建script DOM:document.createElement('script')
  • xmlHttpRequest脚本注入
  • 延迟加载工具lazyLoad

十八、let和var的区别

  • let命令不存在变量提升,如果在let前使用,会导致报错
  • 如果块区中存在let和const命令,就会形成封闭作用域
  • 不允许重复声明,因此,不能在函数内部重新声明参数

十九、map与forEach的区别

  • forEach方法,是最基本的方法,就是遍历循环,默认3个传参,分别是遍历的数组内容item,数组索引index,和当前遍历数组array
  • map方法,与forEach方法一致,不同的是,它会返回一个新的数组,所以在callback需要有return值,如果没有返回undefined

二十、函数式编程

  • 他是一种编程范式
  • 具有以下特性:闭包和高阶函数、惰性计算、递归、函数是第一等公民、只用表达式

二十一、this的指向

  • this的指向在函数定义时确定不了的,只有在函数执行的时候才能确定this到底指谁,实际上this的最终指向的是那个调用它的对象
  • 默认绑定:全局环境指向window(浏览器环境),nodejs环境指向global
  • 隐式绑定:被直接对象所包含的函数调用时,this就隐式绑定到了该直接对象
  • 隐式丢失:隐式丢失是指被隐式绑定包含的函数丢失了绑定对象,从而绑定到了window
  • 显示绑定:通过call、apply、bind把对象绑定到this上
  • 箭头函数没有this指向,所以要通过作用域链来查找this指向

二十二、异步编程的实现方式

  • 回调函数
    • 简单、容易理解
    • 不利于维护、代码耦合性高
  • 事件监听
    • 容易理解、可以绑定多个事件
    • 事件驱动型、流程不够清晰
  • 发布/订阅者模式
    • 类似事件监听、但是可以通过消息中心了解现在的发布者、订阅者
  • Promise对象
    • 可以利用then方法,进行链式写法、可以书写错误时的回调函数
    • 编写和理解相对比较困难
  • generator函数
    • 函数体内外的数据交换、错误处理机制
    • 流程管理不方便
  • async函数
    • 内置执行器、更好的语义、更广的实用性、返回的是promise、结构清晰
    • 错误处理机制没有

二十三、对原生JavaScript了解程度

  • 数据类型、运行、对象、Function、继承、闭包、作用域、原型链、事件、json、RegExp、ajax、DOM、BOM、内存泄漏、跨域、异步加载、模板引擎、前端MVC、路由、模块化、canvas、ECMAScript

二十四、js动画与css动画区别即响应实现

  • css动画在性能上稍微好一点,浏览器会对css3动画做一些优化,代码相对简单,但是不够灵活、兼容性低
  • js动画可以控制单帧动画,同时可以兼容IE6,对于一些复杂的动画,使用JavaScript会比较靠谱,对于一些小动画使用css

二十五、js数组和对象的遍历

循环遍历数组导致js性能问题低

  • for in 循环
    • 需要分析出array的每个属性,这个操作性能开销很大。
  • for 循环
  • forEach
    • 参数:value、index
    • 无法遍历对象
    • IE不支持该方法
    • forEach无法使用break

二十六、gulp是什么

  • 前端开发过程中一种基于流的代码构建工具,是自动化项目的构建利器
  • 流:建立在面向对象的基础上的一种抽象的处理数据的工具
  • 特点:易于使用、构建快速、易于学习

二十七、vue的双向绑定数据的原理

  • 采用的是数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter、getter,在数据变动时发布消息给订阅者,触发相应的回调

二十八、事件

  • addEventListener的第三个参数设置为
    • true:表示该元素在事件的捕获阶段响应事件
    • false:表示该元素在事件的冒泡阶段响应事件

二十九、let 跟 var 跟 const

  • let
    • 允许你声明一个作用域被限制在块级中的变量、语句或者表达式
    • let绑定不受变量提升的约束
    • 该变量处于从块开始到初始化处理的暂存死驱
  • var
    • 声明变量的作用域限制在其声明位置的上下文中,而非声明变量总是全局的
    • 由于变量声明总是在任意代码执行之前处理的,所以在代码中的任意位置声明变量总是等效在代码开头声明
  • const
    • 声明创建一个值的只读引用

三十、如何渲染几万条数据并不卡住页面

通过window.requestAnimationFrame()来每16ms刷新一次

  • 该方法传入一个回调函数作为参数

三十一、添加、移出、移动、复制查找节点

  • 创建新节点
    • createDocumentFragment() 创建一个DOM片段
    • createElement() 创建一个具体的元素
    • createTextNode() 创建一个文本节点
  • 添加、移出、替换、插入
    • appendChild()
    • removeChild()
    • replaceChild()
    • insertBefore()
  • 查找
    • getElementsByTagName()
    • getElementsByName()
    • getElementById()

三十二、正则表达式

  • 当使用RegExp()构造函数时,不仅需要转义引号(\表示),并且还需要双反斜杠(\\表示一个\)。

三十三、JavaScript中callee和caller的作用

  • caller是返回一个对函数的引用,该函数调用了当前函数
  • callee是返回正在被执行的function函数,也就是指定的function对象的正文

三十四、window.onload和$(document).ready

  • window.onload:必须等到页面内容包括图片的所有元素都渲染完毕,才能执行该方法
  • $(document).ready:是DOM结构绘制完毕后就执行,不必等到加载完毕

三十五、addEventListener和attachEvent的区别

  • 前者是符合w3c规范的标准方法,后者是IE低版本的非标准方法
  • 前者支持事件冒泡和事件捕获,后者只支持事件吗冒泡
  • 前者的第一个参数中事件类型不需要添加on,后者需要添加on
  • 如果为同一个元素绑定多个事件,前者会按照事件绑定的顺序执行,后者会按照事件绑定的顺序倒序执行

三十六、数组去重

  • 利用ES6 Set去重
    • Array.from(new Set(arr))
  • splice去重
    • 双for循环实现
  • indexOf去重
    • 看数组中第一个元素出现的位置
  • 利用sort()
    • 排序,遍历与相邻元素比较
  • 利用includes
    • 检测数组是否有某个值
  • 利用hasOwnPropery() 判断是否存在对象属性
  • 利用filter
  • 利用递归
  • 利用Map数据结构去重

三十七、判断两个对象相等

  • 转换为字符串比较
    • JSON.stringify(obj1)==JSON.stringify(obj2)

三十八、项目做过的性能优化

  • 减少HTTP请求
  • 减少DNS查询
  • 使用CND
  • 图片懒加载
  • 避免重定向
  • 减少DOM元素数量
  • 减少DOM操作
  • 使用外部JavaScript与css
  • 压缩JavaScript与css、图片等
  • 减少iframe使用
  • 避免图片src为空
  • 把样式表反正link中
  • 把JavaScript放在页面底部

三十九、变量提升

  • 当执行js代码时,会生成执行环境,只要代码不是在函数里写的,就是在全局执行环境中,函数中的代码就会产生函数执行环境,至此两种执行方式
  • 变量提升
    • 将声明的代码移动到了底部
    • 在执行环境中,会有两个阶段,第一个阶段是创建的阶段,JS解释器会找出需要提升的变量和函数,并给她们在内存中开辟空间,函数的话会将整个函数存入内存,变量只声明赋值为undefined,所以在第二个阶段,也就是代码执行阶段,我们可以提前使用
    • 在提升的过程中,相同的函数覆盖上一个函数,并且函数优先与变量提升

四十、MVVM

  • MVVM模式

    • MVVM是model-view-viewModel的简写,是一个软件架构设计模式
  • MVVM原理

    • MVVM的出现促进了前后端分离,极大提高了开发效率

    • Model:数据模型,泛指后端进行的各种业务逻辑和数据操控

    • View:视图层,也就是用户界面。前端主要由HTML|CSS来构建,已经产生了各大MVVM框架,如VUE、React、Angular···

    • ViewModel:是由前端开发人员生成和维护的视图数据层。他是MVVM模式的核心,是连接view和model的桥梁。在这一层,前端开发人员从后端获取到Model数据进行转换处理,做二次封装,以生成符合view层使用预期的视图数据模型,需要注意的是viewModel所封装出来的数据模型包括视图的状态和行为两部分,而model层的数据只包含状态的,view视图层是用来展示行为的,这样的封装使得viewModel可以完整的描述view层,由于实现了双向绑定,ViewModel内容会实时展现在view层,开发者不用在低效的去操纵DOM更新视图,View层展现的不是model层的数据,而是ViewModel层的数据,由ViewModel负责与Model层交互,这就完全解耦了View层和Model层,这个解耦是前后端分离最重要的一点。

    • VIewModel层,就像是一个中转站,负责转换Model中的数据对象来让数据变得更加容易管理使用,该层向上与视图层进行双向数据绑定,向下与model数据层通过请求接口进行数据交互,起到呈上起下的作用

  • MVVM设计模式的优缺点

    • 优点:双向数据绑定,单向绑定与双向绑定
      • 单向绑定:ViewModel层变化时,自动更新View层
      • 双向绑定:在单向绑定的基础上,View层变化时,自动更新ViewModel
    • 缺点
      • Bug很难调试。因为使用双向绑定模式,当看到界面异常了,就可能是view层代码有bug,有可能是model层代码有问题。另外,数据绑定的声明是指令式的写在View的模板中,这是无法打断点debug的
      • 大模块中Model也会很大 ,虽然使用方便了也很容易保证了数据的一致性,但是长期使用不释放内存就造成了花费更多的内存
      • 对于大型图形应用程序,视图状态较多,ViewModel的构建和维护的成本都会比较高

四十一、事件流

事件流分为三个阶段,捕获阶段、处于目标节点阶段、冒泡阶段

  • 捕获事件流
    • 从根节点开始执行,一直往子节点查找执行,直到查找到目标节点
  • 冒泡事件流
    • 从目标节点开始执行,一直往父节点冒泡查找执行,直到查找到根节点

四十二、JavaScript对象生命周期

  • 当创建一个JavaScript对象时,JavaScript会自动为该对象分配适当的内存
  • 垃圾回收器定期扫描对象,并计算引用了该对象的其他对象的数量
  • 如果被引用的数量为0,或唯一引用是循环的,那么该对象的内存即可回收

四十三、caller和callee

  • caller
    • 返回一个函数的引用,这个函数调用了当前的函数(谁在调用我
  • callee
    • 返回正在执行的函数本身的引用(正在执行的函数

四十四、JavaScript的组成

  • ECMAScript:JavaScript语言基础
  • BOM:浏览器对象模型:提供了浏览器窗口之间进行交互的对象方法
  • DOM:文档对象模型:规定了访问HTML和XML的接口

四十五、js内置对象

  • 数据封装类型对象:Object、Array、Boolean、Number、String
  • 其他对象:Function、Arguments、Math、Date、RegExp、Error
  • ES6新增对象:Symbol、Map、Set、Promise、Proxy

四十六、JavaScript的基本规范

  • 代码缩进,4个空格
  • 代码段使用{}包裹
  • 语句结束使用分号;
  • 变量和函数在使用前声明
  • 以大写字母开头名构造函数,全大写命名常量
  • 规范定义JSON对象,补全双引号
  • 用{}和[]声明对象数组

四十七、如何编写高性能JavaScript

  • 遵守严格模式'use strict'
  • 将js脚本放到页面底部
  • 将js脚本成组打包,减少请求
  • 进来使用局部变量来保存全局变量
  • 尽量减少使用闭包
  • 使用window对象属性方法时,省略window
  • 尽量减少对象成员嵌套
  • 缓存DOM节点访问
  • 尽量使用直接量创建对象数组
  • 最小化重绘和回流

四十八、实现一个对页面某个节点的拖拽(原生JS)

  • 给需要绑定的元素节点绑定mousedown,mousemove,mouseup事件
  • mousedown事件触发后,开始拖拽
  • mousemove时,需要通过event.clientXevent.clientY获取拖拽位置,并实时更新位置
  • mouseup时,拖拽结束

四十九、判断两个对象相等

  • 转换 为字符串判断
    • JSON.stringify

五十、typeof与instanceof

两者是用来判断一个变量是否为空或者是什么类型的

  • typeof:检测出除了null之外的原型类型(String、Number、Boolean、undefined),对于对象类型的能判断出function,对于Array、Null使用typeof判断都返回Object
    • 判断一个值是否为数组,使用Array.isArray()
  • instanceof:只能用来判断两个对象是否属于实例关系,而不能判断一个对象实例具体属于哪种类型
    • [] instanceof Array //true
    • [] instanceof Object //true

五十一、=====

  • == :两者的类型不一样,就会进行类型转换,然后在比较
  • ===:直接比较类型或者值是否相等
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值