Bootstrap

前端面试高频题目总结(二):javascript(附详解)

目录

1、js内存泄漏与垃圾回收机制的原理

概念

js垃圾回收机制原理 

2、构造函数 new 实际发生了什么?

3、什么是XSS攻击?

XSS概念

XSS危害

XSS分类

XSS预防

4、什么是CSRF攻击?

CSRF概念

CSRF危害

CSRF的两个特点

如何预防CSRF

5、什么是SQL注入?

6、说一说map和forEach是区别

不同点

相同点

7、Web Components是什么

8、javascript中arguments相关的问题

9、undefined与null的区别


1、js内存泄漏与垃圾回收机制的原理

概念

程序的运行需要内存,不再用到的内存,没有及时释放,就叫做内存泄漏。

js提供了自动内存管理,减轻了程序员的负担,这叫做“ 垃圾回收机制(garbage collection)”

js垃圾回收机制原理 

垃圾回收机制会定期,即周期性寻找那些不再使用的内存(即变量),然后释放其内存,各大主流理论常用的垃圾回收机制方法有两种:标记清除和引用计数

标记清除:

js中最常用的垃圾回收方式是标记清除。当变量进入环境时,就将这个变量标记为“进入环境”,当变量离开环境时,则被标记为“离开环境”。只要变量进入环境,就有可能被使用到,因此它们占用的内存不能被释放。

示例如下:

function demo(){
    var num = 10;    //被标记"进入环境"
    var sayHello = "唯一的阿金,你好!";    //被标记"进入环境"
}
test();    //执行完毕后之后,num 和 sayHello 又被标记"离开环境",被回收

垃圾回收机制在运行时,给存储在内存中的所有变量都加上标记,然后,将处在环境中的变量和被环境中的变量引用的变量(即闭包)的标记去除,其余所有带标记的变量是即将被清除的变量。当垃圾回收机制运行到下一个周期时,会释放掉这些变量的内存。

引用计数:

语言引擎用一张“引用表”,保存内存中所有的资源(通常是各种值)的引用次数,如果引用次数是0,则该值所占用的内存可以被释放了;如果一个值不再需要了,但是引用次数不为0,垃圾回收机制是不能释放这块内存的,因此会导致内存泄漏。例如:

let arr = [1,2,3,4];
console.log("hello world");

数组[1,2,3,4]是一个值,会占用内存,变量arr是对这个值的引用,后续虽然不再使用arr,但是这个值的引用次数是1,因此它会持续占用内存,解决办法是:解除arr对数组[1,2,3,4]的引用。

let arr = [1,2,3,4];
console.log("hello world");
arr = null;

综上所述,程序员需要关注内存占用,如果有些值占用了空间,但是不再使用了,就必须要检查是否还存在对它们的引用,如果有的话,则手动解除引用。

参考文章:JS内存泄漏与垃圾回收机制_博客-CSDN博客_js垃圾回收机制 

2、构造函数 new 实际发生了什么?

前提知识:对象.__proto__  = 构造函数.prototype

  • 创建出一个对象;
  • 将构造函数的属性、方法添加给对象;
  • 让构造函数的this指向新创建的对象:this.xxx = xxx;
  • 将对象.__proto__与构造函数.prototype对应。

参考文章:当我们new一个构造函数时,发生了什么? - 掘金 

3、什么是XSS攻击?

XSS概念

XSS是跨站脚本攻击,Cross Site Scripting,为了不与层叠样式表CSS混淆,将跨站脚本攻击写成XSS,具体指的是:攻击者可以通过向Web页面中插入script代码,当用户浏览这个网页时,就会运行被插入的script脚本代码,达到攻击者的目的。

XSS危害

  • 获取cookie:网站中的登录一般都是用cookie作为某个用户的身份证明,如果cookie被攻击者拿到,就可以绕过密码直接登录。当空间、论坛如果可以被插入script代码,那么进入空间或者论坛的人的账号就可以轻易被攻击者获取。
  • 恶意跳转:直接在页面中插入window.location.href,进行跳转

XSS分类

  • 反射型XSS:非持久性XSS,通过URL参数直接注入,反射型就是临时通过url访问网站,网站服务端将恶意代码从url中取出,拼接在HTML中返回给浏览器,用户就会执行恶意代码。
  • 存储型XSS:持久型XSS,存储到数据库后读取时注入,就是将恶意代码以留言的形式保存在服务器数据库,任何访问网站的人都会受到攻击。

XSS预防

基本方案是对数据进行严格的输出编码,比如HTML元素的编码,JavaScript编码,css编码,url编码等等。

  • 浏览器的防御和“X-XSS-Protection”有关,默认值为1,即默认打开XSS防御,可以防御反射型的XSS,不过作用有限,只能防御注入到HTML的节点内容或属性的XSS,例如URL参数中包含script标签。不建议只依赖此防御手段。
  • 防御HTML节点内容,通过转义<为&lt以及>为&gt来实现防御HTML节点内容。
  • 预防HTML属性,通过转义"->&quto来实现防御,一般不转义空格,但是这要求属性必须带引号。
  • 预防JavaScript代码,通过将数据进行JSON序列化。
  • 开启浏览器XSS防御:Http Only cookie,禁止 JavaScript 读取某些敏感 Cookie,攻击者完成XSS注入后也无法窃取此 Cookie。

4、什么是CSRF攻击?

CSRF概念

CSRF攻击是Cross site request forgery,跨站请求伪造,它与 XSS 非常不同,XSS 利用站点内的信任用户,而 CSRF 则通过伪装成受信任用户的请求来利用受信任的网站。

CSRF危害

  • 攻击者B盗用A的身份,以A的名义发送恶意请求
  • 获取用户的隐私信息
  • 配合其他漏洞攻击
  • CSRF蠕虫

CSRF的两个特点

  • CSRF(通常)发生在第三方域名。
  • CSRF攻击者不能获取到Cookie等信息,只是使用

如何预防CSRF

防范CSRF攻击,其实本质上就是让网站能够识别出哪些请求是非正常用户主动发起的。这就要求我们在请求中嵌入一些额外的授权数据,让网站服务器能够区分出这些未授权的请求

  • 阻止不明外域的访问
    • 同源检测
    • Samesite Cookie
  • 提交时要求附加本域才能获取的信息
    • CSRF Token
    • 双重Cookie验证

5、什么是SQL注入?

 SQL注入,就是通过把Sql命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器,执行恶意的sql命令。

6、说一说map和forEach是区别

不同点

  • map:有返回值,可以开辟新空间,return的新数组和原数组长度一样,方便链式调用其他数组的新方法,如filter、reduce等,且map的处理速度比forEach快,
  • forEach:默认无返回值,返回结果是undefined,forEach不改变对该数组本身的引用,但是可以改变数组中的元素的值。

相同点

  • 都是循环遍历数组中的每一项

  • 每次执行匿名函数都支持三个参数,参数分别为item(当前每一项),index(索引值),arr(原数组)

  • 匿名函数中的this都是指向window

  • 只能遍历数组

7、Web Components是什么

Web Components是一套提供完善的封装机制把web组件标准化,每个框架实现的组件都统一标准地进行输入输出,有助于更好地推进组件的复用。包含三个部分:

  • custom element:一组JavaScript API,让开发者自定义HTML元素,根据需要在页面中使用;
  • Shadow DOM:一组 JavaScript API,用于将封装的“Shadow”DOM 树附加到元素(与主文档 DOM 分开呈现)并控制相关功能。通过这种方式,将元素的特征保持为私有,因此可以编写脚本和设置样式,避免与文档的其他部分发生冲突。
  • HTML 模板:可以多次重用<template> 和<slot>元素

8、javascript中arguments相关的问题

  • arguments:是一个类数组对象,当调用有参函数时,往这个有参函数传参时,js会把所传的参数全部存到一个到arguments的对象中。
  • 原理:js中每一个函数都有一个Arguments对象实例arguments对象,引用着函数的实参。
  • 作用:有了arguments这个对象,我们就可以不用给函数设置形参,可以动态地通过arguments传参。

9、undefined与null的区别

  • undefined 表示一个变量自然的、最原始的状态值,这种状态会在以下四种场景中出现:声明了一个变量,但是没有赋值;访问对象上不存在的属性;函数定义了形参,但是没有传递实参;使用void对表达式求值。null 表示一个对象被人为的重置为空对象,而非一个变量最原始的状态。在内存里的表示就是,栈中的变量没有指向堆中的内存对象。
  • typeof undefined 返回“ undefined ” ,而typeof null 返回 “object”,后者的原因是:JavaScript数据类型在底层以32位二进制的形式表示,对于所有对象类型,它的前 3位 都以 000 作为类型标记。而,null的二进制位是以全0表示的,因此会被typeof判断为对象类型。
  • null == undefined返回true,null === undefined 返回false。因为== 比较的是值,而 === 比较的是值跟类型。null 和 undefined在比较值时,会分别转换为布尔值,他们俩的布尔值都是false,因此值相等,但是类型不相等。
  • null 转化为 number 时,会转换成 0, undefined 转换为 number 时,会转换为 NaN。在进行算术运算时,如加法运算:let a = undefined + 1;let b = null + 1,涉及到js的隐式类型转换,将表达式中的变量转换为number类型。

;