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

简介: 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页面怎么解析的?它加载顺序是什么?


用户输入网址(假设是个html页面,并且是第一次访问),浏览器向服务器发出请求,服务器返回html文件

浏览器开始载入html代码,如果发现<head>标签内有一个<link>标签引用外部CSS文件

浏览器又发出CSS文件的请求,服务器返回这个CSS文件

浏览器继续载入html中<body>部分的代码,并且CSS文件已经加载完成了,开始渲染页面

如果浏览器在代码中发现一个<img>标签引用了一张图片,向服务器发出请求。此时浏览器不会等到图片下载完,而是异步渲染后面的代码

服务器返回图片文件,由于图片占用了一定面积,影响了后面段落的排布,因此浏览器需要回过头来重新渲染这部分代码

如果浏览器发现了一个包含一行Javascript代码的<script>标签,会立即运行它

如果Javascript脚本执行了浏览器隐藏掉代码中的某个<style>(style.display=”none”),浏览器就得重新渲染这部分代码

如果这时用户点了一下界面中的“换肤”按钮,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执行:代码从上往下执行


递归与循环的区别


递归算法:

优点:代码简洁、清晰,并且容易验证正确性。

缺点:

它的运行需要较多次数的函数调用,如果调用层数比较深,每次都要创建新的变量,需要增加额外的堆栈处理,会对执行效率有一定影 响,占用过多的内存资源。

递归算法解题的运行效率较低。在递归调用的过程中系统为每一层的返回点、局部变量等开辟了栈来储存。递归次数过多容易造成栈溢出 等

注意:递归就是在过程或函数里调用自身;

使用递归策略时要注意的几个条件:

必须有一个明确的递归结束条件,称为递归出口。

递归需要有边界条件、递归前进段和递归返回段。

当边界条件不满足时,递归前进。当边界条件满足时,递归返回。


循环算法:

优点:速度快,结构简单。

缺点:并不能解决所有的问题。有的问题适合使用递归而不是循环。如果使用循环并不困难的话,最好使用循环

相关文章
|
2月前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
|
2月前
|
JavaScript 前端开发 Java
springboot解决js前端跨域问题,javascript跨域问题解决
本文介绍了如何在Spring Boot项目中编写Filter过滤器以处理跨域问题,并通过一个示例展示了使用JavaScript进行跨域请求的方法。首先,在Spring Boot应用中添加一个实现了`Filter`接口的类,设置响应头允许所有来源的跨域请求。接着,通过一个简单的HTML页面和jQuery发送AJAX请求到指定URL,验证跨域请求是否成功。文中还提供了请求成功的响应数据样例及请求效果截图。
springboot解决js前端跨域问题,javascript跨域问题解决
|
2月前
|
JSON JavaScript 前端开发
[JS]面试官:你的简历上写着熟悉jsonp,那你说说它的底层逻辑是怎样的?
本文介绍了JSONP的工作原理及其在解决跨域请求中的应用。首先解释了同源策略的概念,然后通过多个示例详细阐述了JSONP如何通过动态解释服务端返回的JavaScript脚本来实现跨域数据交互。文章还探讨了使用jQuery的`$.ajax`方法封装JSONP请求的方式,并提供了具体的代码示例。最后,通过一个更复杂的示例展示了如何处理JSON格式的响应数据。
40 2
[JS]面试官:你的简历上写着熟悉jsonp,那你说说它的底层逻辑是怎样的?
|
2月前
|
JSON 前端开发 JavaScript
聊聊 Go 语言中的 JSON 序列化与 js 前端交互类型失真问题
在Web开发中,后端与前端的数据交换常使用JSON格式,但JavaScript的数字类型仅能安全处理-2^53到2^53间的整数,超出此范围会导致精度丢失。本文通过Go语言的`encoding/json`包,介绍如何通过将大整数以字符串形式序列化和反序列化,有效解决这一问题,确保前后端数据交换的准确性。
56 4
|
2月前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
176 1
|
2月前
|
JavaScript 前端开发 开发者
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第27天】在前端开发领域,Vue.js和Angular是两个备受瞩目的框架。本文对比了两者的优劣,Vue.js以轻量级和易上手著称,适合快速开发小型到中型项目;Angular则由Google支持,功能全面,适合大型企业级应用。选择时需考虑项目需求、团队熟悉度和长期维护等因素。
60 1
|
2月前
|
JavaScript 前端开发 API
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第26天】前端技术的飞速发展让开发者在构建用户界面时有了更多选择。本文对比了Vue.js和Angular两大框架,介绍了它们的特点和优劣,并给出了在实际项目中如何选择的建议。Vue.js轻量级、易上手,适合小型项目;Angular结构化、功能强大,适合大型项目。
48 1
|
2月前
|
缓存 前端开发 JavaScript
"面试通关秘籍:深度解析浏览器面试必考问题,从重绘回流到事件委托,让你一举拿下前端 Offer!"
【10月更文挑战第23天】在前端开发面试中,浏览器相关知识是必考内容。本文总结了四个常见问题:浏览器渲染机制、重绘与回流、性能优化及事件委托。通过具体示例和对比分析,帮助求职者更好地理解和准备面试。掌握这些知识点,有助于提升面试表现和实际工作能力。
67 1
|
2月前
|
前端开发 JavaScript UED
"前端小技巧大揭秘:JS如何将后台时间戳秒变亲切小时前、分钟前,让用户秒懂,提升互动体验!"
【10月更文挑战第23天】在Web开发中,将后台返回的时间戳转换为“小时前”、“分钟前”、“刚刚”等友好的时间描述是常见需求。本文介绍如何用JavaScript实现这一功能,通过计算当前时间和时间戳的差值,返回相应的描述,提升用户体验。
43 1
|
3月前
|
JavaScript 前端开发 应用服务中间件
vue前端开发中,通过vue.config.js配置和nginx配置,实现多个入口文件的实现方法
vue前端开发中,通过vue.config.js配置和nginx配置,实现多个入口文件的实现方法
211 0