前端面试题集锦(6)

2023-10-31

目录

1、 常见的兼容问题有哪些 ?

1.1 获取标签节点:

1.2 获取卷去的高度:

1.3 获取样式 :

1.4 事件侦听器:

1.5 事件解绑 :

1.6 事件对象的获取 :

1.7 阻止默认行为 :

1.8 阻止事件冒泡:

1.9 获取精准的目标元素:

1.10 获取键盘码: 

2、 在 JS 中如何阻止事件冒泡 ?  

3、两个数组 var A = [1, 5, 6]; var B = [2, 6, 7],实现一个方

法,找出仅存在于A 或者 仅 存在于B中的所有数字。

4、 你了解构造函数吗 ? class 是什么 ? 两者有什么区别 ?

5、for (var i = 0; i < 5; i++) { setTimeout(function() {

console.log(i); }, 1000); } 要求:输出0,1,2,3,4

6、常见的 HTTP 请求有哪些 ? 他们的区别是什么 ?

7、 JS 的数据类型有哪些 ? 如何判断数据类型 ?他们的优缺点是什么?

8、数组常用方法有那些?

9、JavaScript如何存储cookie

10、函数的柯里化


1、 常见的兼容问题有哪些 ?

1.1 获取标签节点:

document.getElementsByClassName(' 类名 ') 在低版本 ie 中不兼容。解决方法是使用其他方式获取:
document.getElementById('id名')
document.getElementsByTagName('标签名')
document.getElementsByName('name属性值')
document.querySelector('css选择器')
document.querySelectorAll('css选择器')

1.2 获取卷去的高度:

// 当有文档声明的时候
document.documentElement.scrollTop
document.documentElement.srollLeft
// 没有文档声明的时候
document.body.scrollTop
document.body.scrollLeft

 解决办法使用兼容写法:

// 获取
var t = document.documentElement.scrollTop || document.body.scrollTop
var l = document.documentElement.srollLeft || document.body.scrollLeft
// 设置
document.documentElement.scrollTop = document.body.scrollTop = 数值
document.documentElement.srollLeft = document.body.scrollLeft = 数值

1.3 获取样式

// W3C 标准浏览器
window.getComputedStyle( 元素 )
// 低版本 IE
元素 .currentStyle

 使用函数封装的方式兼容:

function getStyle(ele,attr){
        if (window.getComputedStyle){
               return getComputedStyle(ele)[attr]
        }else{
               return ele.currentStyle[attr]
        }
}

1.4 事件侦听器:

// W3C 浏览器
ele.addEventListener( 事件类型 , 函数 )
// 低版本 Ie
ele.attachEvent( 'on 事件类型 ' , 函数 )

 使用函数封装的方式解决:

function bindEvent(ele,type,handler){
    if(ele.addEventListener){
         ele.addEventListener(type,handler)
    }else if(ele.attachEvent){
         ele.attachEvent('on'+type,handler)
    }else{
         ele['on'+type] = handler
    }
}

1.5 事件解绑 :

// W3C 浏览器
ele.removeEventListener( 事件类型 , 函数 )
// 低版本 Ie
ele.detachEvent( 'on 事件类型 ' , 函数 )

 使用函数封装的方式解决:

function unBind(ele,type,handler){
     if(ele.removeEventListener){
          ele.removeEventListener(type,handler)
     }else if(ele.detachEvent){
          ele.detachEvent('on'+type,handler)
     }else{
          ele['on'+type] = null
     }
 }

1.6 事件对象的获取

// W3C 浏览器
元素 .on 事件类型 = function (e){}
元素 .addEventListener( 事件类型 ,fn)
function fn(e){
}
// 在低版本 IE
元素 .on 事件类型 = function (){ window.event }
元素 .addEventListener( 事件类型 ,fn)
function fn(){
       window.event
}

 使用短路运算符解决:

元素.on事件类型 = function(e){
      var e = e || window.event
}
元素.addEventListener(事件类型,fn)
function fn(e){
      var e = e || window.event
}

1.7 阻止默认行为 :

// W3C 浏览器
元素 .on 事件类型 = function (e){
         e.preventDefault()
}
// 在低版本 IE
元素 .on 事件类型 = function (){ window.event.returnValue = false }

 通过封装函数解决:

元素.on事件类型 = function(e){
     var e = e || window.event
     e.preventDefault?e.preventDefault():e.returnValue=false
}

1.8 阻止事件冒泡:

// W3C 浏览器
元素 .on 事件类型 = function (e){
       e.stopPropagation()
}
// 在低版本 IE
元素 .on 事件类型 = function (){ window.event.cancelBubble = true }

 通过函数封装解决:

元素.on事件类型 = function(e){
    var e = e || window.event
    e.stopPropagation?e.stopPropagation():e.cancelBubble=true
}

1.9 获取精准的目标元素:

// W3C 浏览器
元素 .on 事件类型 = function (e){
        e.target
}
// 在低版本 IE
元素 .on 事件类型 = function (){ window.event.srcElement }

 通过短路运算符解决:

元素.on事件类型 = function(e){
     var e = e || window.event
     var target = e.target || e.srcElement;
}

1.10 获取键盘码: 

// W3C 浏览器
元素 .on 事件类型 = function (e){
         e.keyCode
}
// 在低版本火狐中
元素 .on 事件类型 = function (e){
         e.which
}

 通过短路运算符解决:

元素.on事件类型 = function(e){
     var e = e || window.event
     var keycode = e.keyCode || e.which;
}

2、 在 JS 中如何阻止事件冒泡 ?  

使用事件对象阻止事件冒泡,以前的 w3c 浏览器中,使用事件对象的方法阻止:
事件对象 .stopPropagation()

 ie低版本浏览器中,使用事件对象的属性阻止:

现在的 w3c 浏览器也支持 ie 低版本浏览器中的写法,所以以前在阻止事件冒泡的时候,需要考虑兼容写法,现在就不需要了,直接用ie 低版本浏览器中的写法即可

3、两个数组 var A = [1, 5, 6]; var B = [2, 6, 7],实现一个方

法,找出仅存在于A 或者 仅 存在于B中的所有数字。

function getDiff(arr, brr){
      // 仅存在于arr中的内容
      var onlyArr = arr.filter(item => !brr.some(v => item === v))
      // 仅存在于brr中的内容
      var onlyBrr = brr.filter(v => !arr.some(item => v === item))
      // 需要哪个就返回哪个,或者一起返回
      return {
            "仅存在于arr中的内容": onlyArr,
            "仅存在于brr中的内容": onlyBrr
      }
}

4、 你了解构造函数吗 ? class 是什么 ? 两者有什么区别 ?

es5 中构造函数其实就是在定义一个类,可以实例化对象, es6 class 其实是构造函数的语法糖。但还是有点区别的:
class 内部和 class 的方法内部,默认使用 严格模式
class 类不存在预解析,也就是 不能先调用class生成实例 ,再定义 class 类,但是 构造函数可以。
class 中定义的方法默认不能被枚举,也就是 不能被遍历
class 必须 使用 new 执行,但是构造函数没有 new 也可以执行。
class 中的 所有方法都没有原型 ,也就不能被 new
class 中继承 可以继承静态方法 ,但是构造函数的继承不能。

5for (var i = 0; i < 5; i++) { setTimeout(function() {

console.log(i); }, 1000); } 要求:输出01234

首先这个面试题考察的是对于 js 中异步代码以及作用域的理解:
js 中常见的异步代码包括定时器和 ajax js 执行代码的流程是碰到同步代码就执行,碰到异步就交给浏览器的webAPI处理,当 webAPI 中的异步该执行时, webAPI 会将需要执行的回调函数放在任务队列中,等候执行,所以, js中所有的异步代码总会在所有同步代码执行结束后,再执行任务队列中的代码。
在这个问题中,循环是同步代码,定时器是异步代码,所以整个循环都执行结束以后才会执行定时器代码。
for 循环中使用 var 定义的变量是全局变量,定时器回调函数中输出变量的时候,根据作用域规则,先在当前作用域中变量i 的定义表达式,如果没有找到,就去上一级作用域中找,此时,在局部作用域中没有找到,去上级作用域中,也就是全局找到了,全局中的i ,因为循环已经执行结束了,所以 i 的值是 5
最终,会输出 5 5
其次考察的是对于类似问题的解决方式,间接性判断你是否有过类似情况的开发:
这个问题的解决思路就是让回调函数中输出 i 的时候,不要去全局中找 i ,因为全局的 i 在循环执行结束后已经变成 5了,根据这个思路,有2 种解决办法:

1.在异步代码外面嵌套一层函数作用域:

for(var i = 0;i < 5; i++){
     (function(i) {
         setTimeout(function() {
             console.log(i)
         }, 1000)
     })(i)
}

原理是自调用函数会产生作用域,循环 5 次就会产生 5 个作用域,每个作用域代码在执行的时候都有形参 i传递。所以每个作用域中的i 都是不同的,分别是: 0 1 2 3 4 。当作用域中的异步代码执行的时候,自己作用域中没有i 变量的定义,然后上级作用域就是自调用函数的作用域,找到了单独的 i 。最终可以输出:
0 1 2 3 4
2. 将循环代码中的var换成es6的let
for(let i = 0;i < 5; i++){
     setTimeout(function() {
          console.log(i)
     }, 1000)
}
es6 let 自带块级作用域,原理跟第一种解决思路是一样的,转成 es5 后,代码是一样的。

6、常见的 HTTP 请求有哪些 ? 他们的区别是什么 ?

常见的有5种,分别是GET、HEAD, POST、PUT、 DELETE
       GET :它是最常见的方法,用于获取资源,常用于向服务器查询某些信息。打开网页一般都是用GET方法,因为要从 Web 服务器获取信息
       HEAD :类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头。
       POST :向指定资源提交数据进行处理请求(例如提交表单或者上传文件), 数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或对已有资源的修改。
       PUT :从客户端向服务器传送的数据取代指定文档的内容。
       DELETE :请求服务器删除指定的页面。
最常见的HTTP请求方法是GET 和 POST。GET一般用于获取/查询资源信息,而POST一般用于更新资源信息。GET和POST的区别:
       GET 提交的数据会放在 ? 之后,以问号(?)分割 URL 和传输数据,参数之间以&相连
       GET 提交的数据大小有限制(因为浏览器对 URL 的长度有限制), 而 POST 方法提交的数据大小没有限制。
       GET 方式提交数据会带来安全问题,比如一个登录页面通过 GET 方式提交数据时,用户名和密码将出现在URL 上,如果页面可以被缓存或者其他人可以访问这台机器,就可以从历史记录获得该用户的账号和密码

7、 JS 的数据类型有哪些 ? 如何判断数据类型 ?他们的优缺点是什么?

typeof 用来检测数据类型的运算符
检测的不管是数组还是正则都返回的是 "object", 所以 typeof 不能判断一个值是否为数组

instanceof/constructor。检测某一个实例是否属于某一个类使用instanceof/constructor可以检测数组和正则

instanceof 检测的时候 , 只要当前的这个类在实例的原型链上 ( 可以通过 原型链__proto__ 找到它 ), 检测出来的结果都是true
基本数据类型 的值是不能用 instanceof 来检测的
类的原型继承 ,instanceof 检测出来的结果其实是 不准确的

Object.prototype.toString.call(value) ->找到Object原型上的toString方法,让方法执行,并且让方法中的this变为value(value->就是我们要检测数据类型的值)。检测的类型比较多,也比较精准。

8、数组常用方法有那些?

数组的常用方法 这样的面试题 算是非常基础的面试题 面试官的目的 也不会只是单纯的让你背诵出数组的所有方法
这里的关键点 是 常用 这两个字 面试官的 目的是 通过 这个问题 看你平时在项目中 对于 数组函数的应用和理解 然后判断出 你平时在项目中对于数组的应用 然后推测出你真实的技术水平
这里建议的回答方式是 通过一个 自己用的最多的数组函数方法 深入展开的说一说 在 实际项目中的应用
例如谈到 数组单元删除 数组 ,splice() 除了要说 函数的用法之外 还要谈到 具体的项目中 删除数组单元之后 数组坍塌的影响 以及如何处理
concat() 连接两个或更多的数组,并返回结果。
join() 把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。
pop() 删除并返回数组的最后一个元素。
shift() 删除并返回数组的第一个元素
push() 向数组的末尾添加一个或更多元素,并返回新的长度。
unshift() 向数组的开头添加一个或更多元素,并返回新的长度。
reverse() 颠倒数组中元素的顺序。
slice() 从某个已有的数组返回选定的元素
sort() 对数组的元素进行排序
splice() 删除元素,并向数组添加新元素。
toSource() 返回该对象的源代码。
toString() 把数组转换为字符串,并返回结果。
toLocaleString() 把数组转换为本地数组,并返回结果。
valueOf() 返回数组对象的原始值

9、JavaScript如何存储cookie

基本语法是 document.cookie = '键名=键值;expires=时间对象;path=路径' ;
时效 如果不设定 默认是 seeion 会话时效
路径 如果不设定 默认是 当前文件所在文件夹
设定时效 要 设定一个时间对象 时间对象的时间戳 就是 时效期
要注意计算 当前时区 和 世界标砖时间的时间差
路径一般设定为根目录 也就是 '/'

10、函数的柯里化

所谓的柯里化函数 指的是 把 接受多个参数的函数 变换成 接受一个单一参数的函数 并且返回接受余下的
参数而且返回结果的新函数
// 普通的add函数
function add(x, y) {
    return x + y
}

// Currying后
function curryingAdd(x) {
    return function (y) {
        return x + y
    }
}

add(1, 2) // 3
curryingAdd(1)(2) // 3

优点: 

1 , 参数复用
例如 一个函数 有两个参数 但是第一个参数会被反复使用 每次都需要输入 一个重复的参数
使用柯里化函数之后 只需要 输入一个参数就可以了
2 , 提前确认
提前定义好一个参数 也就 决定了整个函数程序的执行方向 避免每次都执行判断比较等

缺点:

只能提前定义一个参数 如果想要提前定义多个参数 这样的语法是不支持

柯里化函数执行效能上的问题:

存取 arguments 对象通常要比存取命名参数要慢一点
一些老版本的浏览器在 arguments.length 的实现上是相当慢的
使用 函数 .apply() 和 函数 .call() 通常比直接调用 fn() 稍微慢点
创建大量嵌套作用域和闭包函数会带来花销,无论是在内存还是速度上
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

前端面试题集锦(6) 的相关文章

随机推荐

  • FreeCAD是什么、如何下载(windows+0.18.4版本)和安装以及中文设置

    目录 一 FreeCAD是什么 二 如何下载FreeCAD 三 FreeCAD安装过程 四 如何设置成中文 一 FreeCAD是什么 我本意是想用Qt连接CAD实现CAD的二次开发 实现在qt界面改变参数同时CAD图纸上的尺寸发生相应变化
  • Linux之Web服务器配置(Apache)

    摘要 Web Service技术 能使得运行在不同机器上的不同应用无须借助附加的 专门的第三方软件或硬件 就可相互交换数据或集成 依据Web Service规范实施的应用之间 无论它们所使用的语言 平台或内部协议是什么 都可以相互交换数据
  • 基于stm32f103c8t6HAL库六路电磁寻迹智能车

    基于stm32f103c8t6HAL库六路电磁寻迹智能车 学习单片机第一次参加相关比赛 下面分享一些关于调车的心得 1 控制舵机 舵机是控制小车转向的器件 而PWM波可以控制舵机 占空比越大 舵机旋转角度越大 接下来我们打开cubemx配置
  • FreeSwitch常用命令

    1 通话相关 先打客户 再转坐席 没有录音 EslMessage elme client sendSyncApiCommand originate sofia gateway huawei 015011275853 bridge user
  • JDBC数据源配置及管理

    JDBC驱动程序 JDBC驱动程序组件为java程序连接不同数据库系统提供服务 它通常由数据库系统方开发提供或由第三方提供 下载对应不同数据库的JDBC 数据库连接信息配置 URL 连接数据库系统资源描述符 DriverClass 数据库系
  • 交付文档注意事项

    最近涉及到项目交付 编写了很多技术文档 但因为没有经验导致多次修改 尤其是客户和我们技术人员的关注点其实是不一样的 就导致我没有抓住重点 导致反复修改 这里总结下我的一些经验 文档与技术协议合同对应 就我所经历的项目 前期的技术要求和最后的
  • 十大必掌握C++11新特性

    简介 C 11 之前被称作C 0x 即ISO IEC 14882 2011 是目前的C 编程语言的正式标准 它取代第二版标准ISO IEC 14882 2003 第一版ISO IEC 14882 1998发布于1998年 第二版于2003年
  • OCR测试——字体和背景颜色

    测试目的 测试图片中字体颜色和背景颜色对文字识别的影响 一 测试图片选择 黑色字体 白色背景 黑色字体 橙色背景 绿色字体 黑色背景 绿色字体 白色背景 白色字体 绿色背景 白色字体 橙色背景 橙色字体 白色背景 混合色字体 混合色背景 二
  • c# 遍历文件夹下的.exe文件,找到主应用程序文件

    遍历文件夹下的文件 exe文件 public static string ForeachFiles string FilePath SearchOption AllDirectories 指遍历全部的子文件夹 所有都遍历一次 string
  • 见到的一篇IOCP流程 自己用demo实现了一下, 简单照抄,改动了一点点

    要分析的实例分为两个线程 分别是主线程 MAIN 还有一个是创建的线程 ServerThread 1 主函数完成初始化工作 1 1 主线程 HANDLE hCompletion CreateIoCompletionPort INVALID
  • 针对树莓派vnc连接被拒绝,树莓派固定ip后上不了网的问题

    三月份玩了会树莓派 实现树莓派小车的自动登录 自动连接wifi 固定ip和vnc远程连接 具体见之前的树莓派小车记录的博客里 昨天发现小车虽然可以连接wifi 固定ip 甚至能vnc连接但是没有网络 ping不通除了自身ip以外的任何地址
  • SpringBoot单元测试Mock静态方法

    这两天写单元测试碰到了一个问题 就是这个subnetmap里面的数据格式我不知道是怎么样的 所以直接mock掉返回自己指定的值吧 mockito库并不能 mock静态方法 需要依赖powermock这个库才能对静态方法mock 可以直接用这
  • fastadmin 配置完成后部署到服务器报找不到模块问题

    现象 本地直接安装的fastadmin框架可以正常运行 迁移到服务器或者给别人用的时候就不行了 跟这个问题差不多nginx配置了rewrite fastadmin后台首页可以访问 但一刷新会去首页 怎么办 FastAdmin问答社区 现象一
  • 代码走查和代码审查_21世纪的代码审查

    代码走查和代码审查 有句老话说 不要谈论宗教或政治 为什么 因为这些主题充满了强烈的见解 但客观答案却很薄弱 一个人的确定性就是另一个人的怀疑 别人的常识只是对那些持不同看法的人的先验偏见 可悲的是 与这些有争议的主题进行对话会产生比光更多
  • 三元运算符 使用

    三元运算符 三元表达式判断闰年 var b 2012 var year b 4 0 b 100 0 闰年 平年 console log year 判断奇数偶数 var a prompt 输入你要判断的数 var a 3 var res a
  • 使用docker部署springboot项目并连接上mysql数据库

    使用docker部署springboot项目并连接上mysql数据库 预览 http 8 142 6 23 screen 项目开源地址 前端vue https gitee com gaohan888 echarts learning tre
  • 旧版vue-cli脚手架Webpack3项目如何升级Webpack4

    vue cli脚手架出到了4 3 1版本 目前主推通过create命令来新建项目 与过去的vue cli2的init命令不同的是 create命令脚手架建完的项目webpack为4 而init采用的模板中引用的webpack版本还是3 单独
  • 程序人生-Hello’s P2P

    第一章 概述 1 1 Hello 简介 1 1 1 P2P Program to Process 从程序到进程 P2P指Hello c从源程序到进程的过程 Hello c经过预处理器的编译预处理 得到预编译文件Hello i Hello i
  • Java多对象的内存情况分析

    这种情况指的是在一个类中创建了多个对象 最先创建的对象直接指向类 后面创建的对象则指向第一个创建的对象 那么针对这种情况就会出现如下情况 1 照旧生成栈内存和堆内存 但是堆内存只会生成一个包含类中所有属性和方法的内存地址 2 因为后面创建的
  • 前端面试题集锦(6)

    目录 1 常见的兼容问题有哪些 1 1 获取标签节点 1 2 获取卷去的高度 1 3 获取样式 1 4 事件侦听器 1 5 事件解绑 1 6 事件对象的获取 1 7 阻止默认行为 1 8 阻止事件冒泡 1 9 获取精准的目标元素 1 10