JS进阶篇前端面试题整合一

js的垃圾回收机制是什么原理

垃圾回收机制有两种方法

  • 第一种是标记清除法:当变量进入执行环境时,就标记这个变量为”进入环境”,当变量离开环境的时候,则将其标记为”离开环境”,垃圾收集器在运行的时候会给储存在内存中的所有变量都加上标记,然后它会去掉环境中的标量以及被环境中的变量引用的标记,而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了,最后,垃圾收集器完成内存清除工作,销毁那些带标记的值,并回收他们所占用的内存空间
  • 第二种是引用计数法:当声明了一个变量并将一个引用类型赋值给改变量是,则这个值得引用次数就是1,相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值得引用次数就减1,当这个引用次数变成0时,则说明没有办法在访问这个值了,因而就可以将其所占的内存空间给收起来,这样垃圾收集器再下次运行时,它就会释放那些引用次数为0的值所占的内存

哪些操作会造成内存泄露,怎样避免内存泄露

会造成内存泄漏的操作:

  • 意外的全局变量引起的内存泄露
  • 闭包引起的内存泄露
  • 控制台日志
  • 没有清理的DOM元素引用
  • 被遗忘的定时器或者回调 

避免内存泄露的操作:

  • 减少不必要的全局变量,或者生命周期较长的对象,及时对无用的数据进行垃圾回收
  • 注意程序逻辑,避免“死循环”之类的
  • 避免创建过多的对象  原则:不用了的东西要及时归还(置为null)

AMD\CMD区别

  • AMD即Asynchronous Module Definition,翻译过来就是异步模块化定义(RequireJS)
  • CMD即 common moudle definition,翻译过来即通用模块定义(SeaJS)
  • RequireJS在主文件里是将所有的文件同时加载,然而SeaJS强调一个文件一个模块。
  • AMD推崇依赖前置,CMD推崇依赖就近。
  • AMD加载完模块后,就立马执行该模块;CMD加载完某个模块后没有立即执行而是等到遇到require语句的时再执行
  • 所以,他们两者的不同导致各自的优点是AMD用户体验好,因为模块提前执行了;CMD性能好,因为只有用户需要的时候才执行。

面向对象的三个特性

封装 : 屏蔽内部细节   用户直接调用被封装的功能
继承 : 子类拥有父类的所有属性或方法
多态 (js中不存在多态概念)

原型,原型链的理解

所有的构造函数都有一个prototype属性,这个属性也叫 原型对象   构造函数.prototype    所有的构造函数new出来的对象也都有一个原型对象   实现 :对象.__proto__
原型链就是实例对象和原型之间的链接
原型对象的执行流程:

  • 首先去实例上查找,如果找到了就返回
  • 如果没做查找到,就去改构造函数的原型上查找,如果找到了就返回,如果没找到,就去Object.prototype的原型上查找,找到了就返回,否则返回undefined

继承的方式

1.通过改变父类的执行环境来实现
2.通过call
3.通过apply
4.原型继承
5.混合继承
6.es6构造函数

作用域链的理解

作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到window对象即被终止,作用域链向下访问变量是不被允许的
安全隐患:污染全局环境,或者造成内存泄露的问题,变量的提升

闭包的理解

什么是闭包
一个函数内部返回一个匿名函数,这个函数就称为闭包
闭包中this指向 window
特点
(1)函数嵌套函数
(2)函数可以引用外层的参数和变量
(3)参数和变量不会被垃圾回收机制回收
闭包的缺点:常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。
为何要使用闭包:为了设计私有方法和变量,避免全局变量污染 希望一个变量长期驻扎在内存中

下面这个ul,如何点击每一列的时候alert其index(闭包解决方式)

<ul id="test">
    <li>这是第一条</li>
    <li>这是第二条</li>
    <li>这是第三条</li>
</ul>

方法一:

//将i属性绑定到标签对象中的index
var liItems=document.getElementById('test').getElementsByTagName('li');
for(var i=0;i<liItems.length;i++)
{
    liItems[i].index=i;
    liItems[i].onclick=function(){
        alert(this.index);
    };
}

方法二:

//将i属性通过参数传递至function作用域中,立即执行函数在下一次循环之前先将i绑定至作用域
var liItems=document.getElementById('test').getElementsByTagName('li');
for(var i=0;i<liItems.length;i++)
{
     liItems[i].onclick=(function(a){
        return function() {
            alert(a);
        }
    })(i);

}

方法三(es6的let产生暂时性死区,与声明的变量所在的块级作用域(for循环内)都不会造成闭包,var只受function的作用域影响,let受所有带‘{}‘大括号的作用域影响):

//通过let
var liItems=document.getElementById('test').getElementsByTagName('li');
        for (let i = 0; i < liItems.length; i++) {
            liItems[i].onclick = function () {
                alert(i);
            }
        }

高内聚低耦合的理解

高内聚 :模块内部高内聚 。 一个系统有多个模块组成,在划分模块式,要把功能关系紧密的放到一个模块中,这就叫做高内聚低耦合:功能关系远的放到其它模块中。模块之间的联系越少越好,接口越简单越好,这叫做低耦合,也称为细线通信

TCP和UDP的最完整的区别

1.基于连接与无连接
2.TCP要求系统资源较多,UDP较少;
3.UDP程序结构较简单
4.流模式(TCP)与数据报模式(UDP);
5.TCP保证数据正确性,UDP可能丢包
6.TCP保证数据顺序,UDP不保证 

JS处理异步的方式

  • 利用回调函数(es5常用方法)
  • 用async和await来处理异步(es7-8中新增)
  • promise(es6新增)
  • 发布/订阅 我们假定,存在一个"信号中心",某个任务执行完成,就向信号中心"发布"(publish)一个信号,其他任务可以向信号中心"订阅"(subscribe)这个信号,从而知道什么时候自己可以开始执行。这就叫做"发布/订阅模式"(publish-subscribe pattern),又称"观察者模式"(observer pattern)(和事件原理一样)
  • 事件 触发一个事件也可以作为异步的处理  当触发某个事件再来执行某件事(js底层解决异步常用方法)

深拷贝浅拷贝的理解

浅拷贝:只是复制当前的对象,该对象内部的引用(Object,Array等堆内存数据)不能复制
深拷贝:对对象内部的引用均复制,是创建一个新的实例
简言之:是否复制了子对象,修改了克隆后的对象属性值,影响到原对象-浅拷贝  不影响-深拷贝

常见的HTTP请求返回状态码

  • 200成功
  • 304请求浏览器缓存的内容
  • 400语义有误,当前请求无法被服务器理解
  • 401当前请求需要用户验证
  • 404未找到
  • 403服务器已经理解请求,但是拒绝执行它
  • 500服务器错误
  • 503服务器端暂时无法处理请求

1开头的(信息类):表示接收到请求并且继续处理,用于指定客户端应相应的某些动作
2开头的(响应成功):表示动作被成功接收,理解和接受。
3开头的(重定向):为了完成指定的动作,必须接受进一步处理,用于已经移动的文件并且常被包含在定位头信息中指定新的地址信息
4开头的(客户端错误类):请求包含错误语法或不能正确执行
5开头的(服务器端错误):服务器遇到错误,无法完成请求

html页面怎么解析的?它加载顺序是什么?

  1. 用户输入网址(假设是个html页面,并且是第一次访问),浏览器向服务器发出请求,服务器返回html文件
  2. 浏览器开始载入html代码,如果发现<head>标签内有一个<link>标签引用外部CSS文件
  3. 浏览器又发出CSS文件的请求,服务器返回这个CSS文件
  4. 浏览器继续载入html中<body>部分的代码,并且CSS文件已经加载完成了,开始渲染页面
  5. 如果浏览器在代码中发现一个<img>标签引用了一张图片,向服务器发出请求。此时浏览器不会等到图片下载完,而是异步渲染后面的代码
  6. 服务器返回图片文件,由于图片占用了一定面积,影响了后面段落的排布,因此浏览器需要回过头来重新渲染这部分代码
  7. 如果浏览器发现了一个包含一行Javascript代码的<script>标签,会立即运行它
  8. 如果Javascript脚本执行了浏览器隐藏掉代码中的某个<style>(style.display=”none”),浏览器就得重新渲染这部分代码
  9. 如果这时用户点了一下界面中的“换肤”按钮,Javascript让浏览器换了一下<link>标签的CSS路径,那么浏览器就会向服务器请求了新的CSS文件,重新渲染页面

总结:最好将无论内部或是外部JS文件放到所有html内容之后,这样会令用户感觉页面加载速度变快了,否则如果将所有外部文件(包括css和JS)引用都放到<head>中,意味着必须等到全部的JS代码都被下载解析和执行完毕后,才能开始呈现页面的内容(当浏览器遇到<body>),这样会导致呈现页面时出现明显的延迟,二延迟期间的浏览器窗口将是一片空白。

谈谈web攻击技术

  • XSS攻击
  • CSRF攻击
  • 网络劫持攻击
  • 控制台注入代码
  • 钓鱼

同步和异步的区别

同步:阻塞的,A需要等待B完成任务后再开始任务
异步:非阻塞的,A,B同时开始任务

打个简单的比方:Ajax请求数据渲染页面操作,需要使用同步方式渲染,因为js执行的时间很短,几乎可以忽略不计,而Ajax请求需要等待时间,所以,需要等待Ajax请求完毕,收到响应信息后再渲染页面

解释a = b||c,fn&&fn(),a=(b,c),a?b:c的作用或含义

a = b||c:和if(!b) {a=c}效果一致,如果b存在,把b的值赋给a,否则把c的值赋给a(短路求值,提升效率)
fn&&fn():和上面的效果一样,但条件相反,如果fn不存在,则不执行,否则将执行(短路求值,提升效率)
a=(b,c):这里是逗号运算符的用法之一,先执行运算符左侧的操作数,然后再执行右侧的操作数,最后返回右侧操作数的值,即a=c
a?b:c:条件表达式(三元表达式),若a为真,返回b,若a为假,则返回c

对if语句的优化

  • 把次数多的条件和执行结果放到最前面
  • 减少第一次无用的判断,可以用嵌套判断
  • 判断语句禁止出现三次嵌套

对switch的理解

  • switch的括号里面放的是一个变量
  • case相对应的值是关于这个变量的一个值
  • switch里面的这个变量和case里面这个变量不会进行隐式类型的一个转换,而是进行了恒等比较。所以一定要注意这个变量和这个case里 面的值是不是一个类型
  • 关于switch里面的case会有一个穿透效果,这个效果有的时候会给我们带来好处(详情请看最后一个案例),有的时候会给我们带来坏处, 如果不需要这种穿透效果的时候加break
  • swicth里面如果这个变量没有匹配到case里面这个值,那么就需要返回一个信息。所以在case的末尾一定要加上一个default;这样既给用 户的体验比较完美,另一方面对代码的今后维护也有很大的帮助
  • 比较的值是固定值

if和swicth的应用场景

if :
1、具体的值进行判断
2、区间的判断
3、对运算的结果是boolean类型表达式进行判断 true false
switch:
1、对具体的值进行判断
2、值的个数是固定的
对于几个固定的值判断,建议使用switch 语句。因为switch 语句会将具体的答案都加载进内存,效率相对高一点 基于代码的可读性:如果条件较少时,if-else容易阅读,而条件较多时switch更容易阅读

do-while循环的使用及while的区别

do-while() 无论条件是否成立至少执行一次,和while规则一样,唯一不同的是do{}while会先执行一次(先执行后判断

while和for的区别

for循环是知道了循环次数,while是不知道循环次数
for限定了循环次数
while是条件循环

break和continue return的区别

continue只是中止本次循环,接着开始下一次循环 ,只能出现在循环中
break用于完全结束一个循环,跳出循环体 不在执行break下面的代码,只能出现在选择或者循环中
return作用是返回函数的值,不在执行return下面的代码,只能出现函数中

函数的作用

减少代码的编写(代码重复利用)
隐藏处理细节,便于今后的修改和维护
控制执行时机

对参数的理解

参数分为:形参和实参
有了参数以后可以使函数变的更加灵活
形参和实参要一一对应
如果对应的形参没有传值,那么值是undefined

对arguments的了解

  • 函数内部自带的一个对象
  • 存储的是所有的实参
  • 可以使用[ ]及下标访问arguments中的内容 arguments[0] 访问第一个实参
  • 可以使用 arguments.length 确定传入实参的个数
  • 最常用的用途: 判断传入参数的个数(根据参数个数做不同的事情)

请说一下js的编译和执行

js的预编译:
把var 和 function 定义的变量提升到script的最上方
赋值语句不会被提升,哪怕等号后面是一个function

js执行:代码从上往下执行

递归与循环的区别

递归算法:
优点:代码简洁、清晰,并且容易验证正确性。
缺点:
它的运行需要较多次数的函数调用,如果调用层数比较深,每次都要创建新的变量,需要增加额外的堆栈处理,会对执行效率有一定影 响,占用过多的内存资源。
递归算法解题的运行效率较低。在递归调用的过程中系统为每一层的返回点、局部变量等开辟了栈来储存。递归次数过多容易造成栈溢出 等
注意:递归就是在过程或函数里调用自身;
使用递归策略时要注意的几个条件:
必须有一个明确的递归结束条件,称为递归出口。
递归需要有边界条件、递归前进段和递归返回段。
当边界条件不满足时,递归前进。当边界条件满足时,递归返回。

循环算法:
优点:速度快,结构简单。
缺点:并不能解决所有的问题。有的问题适合使用递归而不是循环。如果使用循环并不困难的话,最好使用循环

 

原文地址:https://blog.csdn.net/time_____

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


1==&gt;简述一下src与href的区别 src用于替换当前元素; href用于在当前文档和引用资源之间确立联系 2==&gt;、谈谈以前端角度出发做好SEO需要考虑什么? a.&#160;了解搜
什么是window对象?什么是document对象? window对象代表浏览器中打开的一个窗口。 document对象代表整个html文档。实际上, document对象是window对象的一个属性
1 》vue-router有哪几种导航钩子? 第一种:是全局导航钩子:router.beforeEach(to,from,next) 第二种:&#160;组件内的钩子 beforeRouteEnter
1=&gt;为什么data是一个函数 【理解】 组件的data写成一个函数, 这样每复用一次组件,就会返回一分新的data。 也就说:给每个组件实例创建一个私有的数据空间。 各个组件维护各自的数据。
01 vue3的新特征 1.组合式API. setUp作为组合函数的入口函数 2.Teleport 传送门 3.片段 template下可以有多个标签 4.用于创建自定义渲染器。我的理解是 creat
// var&#160;arr=[1,2,23,23,4,5,5]; // var&#160;newarr=new&#160;Set(arr);&#160;//去重 // console.log([.
摆好姿势 摆好姿势 如何使下面的等式成立 if(a==1&amp;&amp;a==3&amp;a==5){ console.log(666) } var a=[1,3,5] a.join=a.shif
1=&gt;为什么data是一个函数 【理解】 ok 每复用一次组件,就会返回一分新的data。 也就说:【每个组件实例创建】一个【私有】的数据空间。各个组件维护各自的数据。 如果单纯的写成对象形式,
以下是收集一些面试中经常会遇到的经典面试题以及自己面试过程中无法解决的问题,通过对知识的整理以及经验的总结,重新巩固自身的前端基础知识,如有错误或更好的答案,欢迎指正。:) 在网页中,一个元素占有空间
1 Action是不是线程安全的?如果不是 有什么方式可以保证Action的线程安全?如果是,说明原因不是声明局部变量,或者扩展RequestProcessor,让每次都创建一个Action,或者在s
解决js兼容性问题使用 event对象 function eventHandler(event) { event = event || window.event} 获取滚动条属性 var scrollTop = document.documentElment.scrollTop || document.body.scrollTop
浏览器的内核 IE: trident内核,Firefox:gecko内核,Safari:webkit内核,Opera:以前是presto内核,Opera现已改用Google Chrome的Blink内核,Chrome:Blink(基于webkit,Google与Opera Software共同开发) HTML中的Doctype有什么作用 此标签可告知浏览器文档使用哪种HTML或XHTML规范。(重点:告诉浏览器按照何种规范解析页面) div+css的布局较table布局有什么...
如何创建函数第一种(函数声明): function sum1(num1,num2){ return num1+num2; } 第二种(函数表达式): var sum2 = function(num1,num2){ return num1+num2; } 第三种(函数对象方式): var sum3 = new Function("num1","num2","return num1+num2");三种弹窗的单词以及三种弹窗的功能1.alert //弹出对话框并输出一段提示信...
js的垃圾回收机制是什么原理垃圾回收机制有两种方法第一种是标记清除法:当变量进入执行环境时,就标记这个变量为”进入环境”,当变量离开环境的时候,则将其标记为”离开环境”,垃圾收集器在运行的时候会给储存在内存中的所有变量都加上标记,然后它会去掉环境中的标量以及被环境中的变量引用的标记,而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了,最后,垃圾收集器完成内存清除工作,销毁那些带标记的值,并回收他们所占用的内存空间 第二种是引用计数法:当声明了一个变量并将
Ajax 是什么? 如何创建一个Ajax?AJAX全称是Asychronous JavaScript And Xml(异步的 JavaScript 和 XML)它的作用是用来实现客户端与服务器端的异步通信效果,实现页面的局部刷新,早期的浏览器并不能原生支持ajax,可以使用隐藏帧(iframe)方式变相实现异步效果,后来的浏览器提供了对ajax的原生支持其主要通过XMLHttpRequest(标准浏览器)、ActiveXObject(IE浏览器)对象实现异步通信效果实现方式(gitee上的案例):
谈一谈let与var和const的区别let为ES6新添加申明变量的命令,它类似于var,但是有以下不同: let命令不存在变量提升,如果在let前使用,会导致报错let暂时性死区的本质,其实还是块级作用域必须“先声明后使用”的性质,let 暂时性死区的原因:var 会变量提升,let 不会。let,const和class声明的全局变量不是全局对象的属性const可以在多个模块间共享const声明的变量与let声明的变量类似,它们的不同之处在于,const声明的变量只可以在声明时赋值,不可
解释一下为何[ ] == ![ ] // ---&gt; true首先看一张图![ ] 是 false原式:[ ] == false根据第八条,false通过tonumber()转换为0原式:[ ] == 0根据第十条,[ ]通过ToPrimitive()转换为' '原式:' ' == 0根据第六条原式:0 == 0尝试实现new function ObjectClass() {//对象 console.log(arguments[...
谈谈对Node的理解Node.js 在浏览器外运行V8 JavaScript引擎,单线程 非阻塞I/O 事件驱动,适应于数据高并发,适合多请求,但不适合高运算,有权限读取操作系统级别的API,npm 仓库,常用框架:Express,koa,Socket.io,AdonisJs,NestJS什么是gulp?作用?机制是什么?gulp是基于node的自动化构建工具作用:1 自动压缩JS文件2 自动压缩CSS文件3 自动合并文件4 自动编译sass5 自动压缩图片6 自动刷
vue和react的区别React严格上只针对MVC的view层,Vue则是MVVM模式virtual(虚拟) DOM不一样,vue会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树。而对于React而言,每当应用的状态被改变时,全部组件都会重新渲染,所以react中会需要shouldComponentUpdate这个生命周期函数方法来进行控制组件写法不一样,React推荐的做法是 JSX + inline style,也就是把HTML和CSS全都写进JavaScript了,即'all in
谈谈对react的理解react是基于v(视图层)层的一款框架,虚拟dom和diff算法react特点:声明式设计高效,其中高效以现在虚拟dom,最大限度减少与dom的交互和diff算法灵活,体现在可以与已知的框架或库很好的配合JSX,是js语法的扩展组件化,构建组件,是代码的更容易得到复用,比较建议在大型项目的开发单项数据,实现单项数流,从而减少代码复用react有哪几个生命周期自己的总结分为三个阶段,初始,运行中,销毁初始化: 执行getDefaultProps钩子