BAT及各大互联网公司2020前端笔试面试题

1.请你谈谈Cookie的优缺点

优点:极高的扩展性和可用性

  1. 数据持久性。
  2. 不需要任何服务器资源。 Cookie 存储在客户端并在发送后由服务器读取。
  3. 可配置到期规则。 控制 cookie 的生命期,使之不会永远有效。偷盗者很可能拿到一个过期的 cookie 。
  4. 简单性。 基于文本的轻量结构。
  5. 通过良好的编程,控制保存在 cookie 中的 session 对象的大小。
  6. 通过加密和安全传输技术( SSL ),减少 cookie 被破解的可能性。
  7. 只在 cookie 中存放不敏感数据,即使被盗也不会有重大损失。

缺点:

  1. Cookie 数量和长度的限制 。 数量:每个域的 cookie 总数有限。 a) IE6 或更低版本最多 20 个 cookie b) IE7 和之后的版本最后可以有 50 个 cookie c) Firefox 最多 50 个 cookie d) chrome 和 Safari 没有做硬性限制 长度:每个 cookie 长度不超过 4KB ( 4096B ),否则会被截掉。
  2. 潜在的安全风险 。 Cookie 可能被拦截、篡改。如果 cookie 被拦截,就有可能取得所有的 session 信息。
  3. 用户配置为禁用 。有些用户禁用了浏览器或客户端设备接受 cookie 的能力,因此限制了这一功能。
  4. 有些状态不可能保存在客户端 。例如,为了防止重复提交表单,我们需要在服务器端保存一个计数器。如果我们把这个计数器保存在客户端,那么它起不到任何作用。

2.Array.prototype.slice.call(arr,2)方法的作用是:

利用Array原型上的slice方法,使用call函数的第一个参数,让这个方法中的this指向arr,并传递参数2,实际上等于arr.slice(2),即从下标为2开始截取到末尾。

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

基本数据类型:String,Boolean,Number,Undefined, Null

引用数据类型:Object(Array,Date,RegExp,Function)

那么问题来了,如何判断某变量是否为数组数据类型?

方法一.判断其是否具有“数组性质”,如slice()方法。可自己给该变量定义slice方法,故有时会失效 方法二.obj instanceof Array 在某些IE版本中不正确 方法三.方法一二皆有漏洞,在ECMA Script5中定义了新方法Array.isArray(), 保证其兼容性,最好的方法如下:

1if(typeof Array.isArray==="undefined") 2{ 3 Array.isArray = function(arg){ 4 return Object.prototype.toString.call(arg)==="[object Array]" 5 }; 6}

4.简单说一下浏览器本地存储是怎样的

总的来说,浏览器存储分为以下几种: 1、Cookie存储,明文,大小限制4k等 2、localStorage,持久化存储方式之一,不用在两端之间传输,且限制大小为10M 3、sessionStorage,会话级存储方式,浏览器关闭立即数据丢失 4、indexDb,浏览器端的数据库

5.原型链:

原型链是由原型对象组成,每个对象都有 proto 属性,指向了创建该对象的构造函数的原型,proto 将对象连接起来组成了原型链。是一个用来实现继承和共享属性的有限的对象链。

属性查找机制: 当查找对象的属性时,如果实例对象自身不存在该属性,则沿着原型链往上一级查找,找到时则输出,不存在时,则继续沿着原型链往上一级查找,直至最顶级的原型对象Object.prototype,如还是没找到,则输出 undefined;

属性修改机制: 只会修改实例对象本身的属性,如果不存在,则进行添加该属性,如果需要修改原型的属性时,则可以用: b.prototype.x = 2;但是这样会造成所有继承于该对象的实例的属性发生改变。

6.变量对象

变量对象,是执行上下文中的一部分,可以抽象为一种 数据作用域,其实也可以理解为就是一个简单的对象,它存储着该执行上下文中的所有 变量和函数声明(不包含函数表达式)。 活动对象 (AO): 当变量对象所处的上下文为 active EC 时,称为活动对象。

7.作用域链

我们知道,我们可以在执行上下文中访问到父级甚至全局的变量,这便是作用域链的功劳。作用域链可以理解为一组对象列表,包含 父级和自身的变量对象,因此我们便能通过作用域链访问到父级里声明的变量或者函数。 由两部分组成:

  • [[scope]]属性: 指向父级变量对象和作用域链,也就是包含了父级的[[scope]]和AO
  • AO: 自身活动对象 如此 [[scopr]]包含[[scope]],便自上而下形成一条 链式作用域。

8.闭包

闭包属于一种特殊的作用域,称为 静态作用域。它的定义可以理解为: 父函数被销毁 的情况下,返回出的子函数的[[scope]]中仍然保留着父级的单变量对象和作用域链,因此可以继续访问到父级的变量对象,这样的函数称为闭包。 闭包会产生一个很经典的问题: 多个子函数的[[scope]]都是同时指向父级,是完全共享的。因此当父级的变量对象被修改时,所有子函数都受到影响。 解决: 变量可以通过 函数参数的形式 传入,避免使用默认的[[scope]]向上查找 使用setTimeout包裹,通过第三个参数传入 使用 块级作用域,让变量成为自己上下文的属性,避免共享

9. script 引入方式:

html 静态<script>引入 js 动态插入<script> <script defer>: 延迟加载,元素解析完成后执行 <script async>: 异步加载,但执行时会阻塞元素渲染

10.对象的拷贝

浅拷贝: 以赋值的形式拷贝引用对象,仍指向同一个地址,修改时原对象也会受到影响 Object.assign 展开运算符(...)

深拷贝: 完全拷贝一个新对象,修改时原对象不再受到任何影响 JSON.parse(JSON.stringify(obj)): 性能最快 具有循环引用的对象时,报错 当值为函数、undefined、或symbol时,无法拷贝 递归进行逐一赋值

11.new运算符的执行过程

新生成一个对象 链接到原型: obj.proto = Con.prototype 绑定this: apply 返回新对象(如果构造函数有自己 retrun 时,则返回该值)

12.instanceof原理

能在实例的 原型对象链 中找到该构造函数的prototype属性所指向的 原型对象,就返回true。即:

1// __proto__: 代表原型对象链 2instance.[__proto__...] === instance.constructor.prototype 3// return true

13.类型判断

判断 Target 的类型,单单用 typeof 并无法完全满足,这其实并不是 bug,本质原因是 JS 的万物皆对象的理论。因此要真正完美判断时,我们需要区分对待: 基本类型(null): 使用 String(null) 基本类型(string / number / boolean / undefined) + function: 直接使用 typeof即可 其余引用类型(Array / Date / RegExp Error): 调用toString后根据[object XXX]进行判断 很稳的判断封装:

1let class2type = {}'Array Date RegExp Object Error'.split(' ').forEach(e => class2type[ '[object ' + e + ']' ] = e.toLowerCase()) 2function type(obj) { 3 if (obj == null) return String(obj) 4 return typeof obj === 'object' ? class2type[ Object.prototype.toString.call(obj) ] || 'object' : typeof obj 5}

14.模块化

模块化开发在现代开发中已是必不可少的一部分,它大大提高了项目的可维护、可拓展和可协作性。通常,我们 在浏览器中使用 ES6 的模块化支持,在 Node 中使用 commonjs 的模块化支持。 分类: oes6: import / export ocommonjs: require / module.exports / exports oamd: require / defined require与import的区别 orequire支持 动态导入,import不支持,正在提案 (babel 下可支持) orequire是 同步 导入,import属于 异步 导入 orequire是 值拷贝,导出值变化不会影响导入值;import指向 内存地址,导入值会随导出值而变化

15.防抖与节流

防抖与节流函数是一种最常用的 高频触发优化方式,能对性能有较大的帮助。 防抖 (debounce): 将多次高频操作优化为只在最后一次执行,通常使用的场景是:用户输入,只需再输入完成后做一次输入校验即可。

1function debounce(fn, wait, immediate) { 2 let timer = null 3 4 return function() { 5 let args = arguments 6 let context = this 7 8 if (immediate && !timer) { 9 fn.apply(context, args) 10 } 11 12 if (timer) clearTimeout(timer) 13 timer = setTimeout(() => { 14 fn.apply(context, args) 15 }, wait) 16 } 17}

节流(throttle): 每隔一段时间后执行一次,也就是降低频率,将高频操作优化成低频操作,通常使用场景: 滚动条事件 或者 resize 事件,通常每隔 100~500 ms执行一次即可。

1function throttle(fn, wait, immediate) { 2 let timer = null 3 let callNow = immediate 4 5 return function() { 6 let context = this, 7 args = arguments 8 9 if (callNow) { 10 fn.apply(context, args) 11 callNow = false 12 } 13 14 if (!timer) { 15 timer = setTimeout(() => { 16 fn.apply(context, args) 17 timer = null 18 }, wait) 19 } 20 } 21}

为了不影响阅读体验,只分享部分面试题,更多面试题及答案可以【点击我】阅读下载哦~无偿分享给大家,算是一个感恩回馈吧

16.函数柯里化

在一个函数中,首先填充几个参数,然后再返回一个新的函数的技术,称为函数的柯里化。通常可用于在不侵入函数的前提下,为函数 预置通用参数,供多次重复调用。

1const add = function add(x) { 2 return function (y) { 3 return x + y 4 } 5} 6const add1 = add(1) 7add1(2) === 3 8add1(20) === 21

17.get请求传参长度的误区

误区:我们经常说get请求参数的大小存在限制,而post请求的参数大小是无限制的。 实际上HTTP 协议从未规定 GET/POST 的请求长度限制是多少。对get请求参数的限制是来源与浏览器或web服务器,浏览器或web服务器限制了url的长度。为了明确这个概念,我们必须再次强调下面几点: HTTP 协议 未规定 GET 和POST的长度限制 GET的最大长度显示是因为 浏览器和 web服务器限制了 URI的长度 不同的浏览器和WEB服务器,限制的最大长度不一样 要支持IE,则最大长度为2083byte,若只支持Chrome,则最大长度 8182byte

18.补充get和post请求在缓存方面的区别

post/get的请求区别,具体不再赘述。 补充补充一个get和post在缓存方面的区别: get请求类似于查找的过程,用户获取数据,可以不用每次都与数据库连接,所以可以使用缓存。 post不同,post做的一般是修改和删除的工作,所以必须与数据库交互,所以不能使用缓存。因此get请求适合于请求缓存。

19.说说前端中的事件流

HTML中与javascript交互是通过事件驱动来实现的,例如鼠标点击事件onclick、页面的滚动事件onscroll等等,可以向文档或者文档中的元素添加事件侦听器来预订事件。想要知道这些事件是在什么时候进行调用的,就需要了解一下“事件流”的概念。 什么是事件流:事件流描述的是从页面中接收事件的顺序,DOM2级事件流包括下面几个阶段。 事件捕获阶段 处于目标阶段 事件冒泡阶段 addEventListener:addEventListener 是DOM2 级事件新增的指定事件处理程序的操作,这个方法接收3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。 IE只支持事件冒泡。

20.如何让事件先冒泡后捕获

在DOM标准事件模型中,是先捕获后冒泡。但是如果要实现先冒泡后捕获的效果,对于同一个事件,监听捕获和冒泡,分别对应相应的处理函数,监听到捕获事件,先暂缓执行,直到冒泡事件被捕获后再执行捕获之间。

21.说一下事件委托

简介:事件委托指的是,不在事件的发生地(直接dom)上设置监听函数,而是在其父元素上设置监听函数,通过事件冒泡,父元素可以监听到子元素上事件的触发,通过判断事件发生元素DOM的类型,来做出不同的响应。 举例:最经典的就是ul和li标签的事件监听,比如我们在添加事件时候,采用事件委托机制,不会在li标签上直接添加,而是在ul父元素上添加。 好处:比较合适动态元素的绑定,新添加的子元素也会有监听函数,也可以有事件触发机制.

为了不影响阅读体验,只分享部分面试题,更多面试题及答案可以【点击我】阅读下载哦~无偿分享给大家,算是一个感恩回馈吧

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )