【前端面试知识点】- 大厂面试(三)

1.JS垃圾回收机制

解决内存的泄露,垃圾回收机制会定期(周期性)找出那些不再用到的内存(变量),然后释放其内存。
现在各大浏览器通常采用的垃圾回收机制有两种方法:1.标记清除,2.引用计数。

  • 标记清除

    • js中最常用的垃圾回收方式就是标记清除。垃圾回收机制在运行的时候会给存储再内存中的所有变量都加上标记(可以是任何标记方式),然后,它会去掉处在环境中的变量及被环境中的变量引用的变量标记(闭包)。而在此之后剩下的带有标记的变量被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。最后垃圾回收机制到下一个周期运行时,将释放这些变量的内存,回收它们所占用的空间。
    • 工作原理:
      当变量进入环境时,将这个变量标记为“进入环境”。当变量离开环境时,则将其标记为“离开环境”。标记“离开环境”的就回收内存。
    • 工作流程:
      垃圾回收器,在运行的时候会给存储在内存中的所有变量都加上标记; 去掉环境中的变量以及被环境中的变量引用的变量的标记;
      被加上标记的会被视为准备删除的变量; 垃圾回收器完成内存清理工作,销毁那些带标记的值并回收他们所占用的内存空间。
      到目前为止,IE、Firefox、Opera、Chrome、Safari的js实现使用的都是标记清除的垃圾回收策略或类似的策略,只不过垃圾收集的时间间隔互不相同。
  • 引用计数

    • 语言引擎有一张"引用表",保存了内存里面所有资源(通常是各种值)的引用次数。如果一个值的引用次数是0,就表示这个值不再用到了,因此可以将这块内存释放。
    • 工作原理:跟踪记录每个值被引用的次数。
    • 工作流程:
      声明了一个变量并将一个引用类型的值赋值给这个变量,这个引用类型值的引用次数就是1
      同一个值又被赋值给另一个变量,这个引用类型值的引用次数加1;
      当包含这个引用类型值的变量又被赋值成别的值了,那么这个引用类型值的引用次数减1; 当引用次数变成0时,说明没办法访问这个值了。
      当垃圾收集器下一次运行时,它就会释放引用次数是0的值所占的内存;

扩展:
但是,为了减少内存垃圾,我们还是可以对javascript代码进行彻底检查,有些代码中存在明显的产生过多内存垃圾的问题代码,这些正是我们需要检查并且完善的。

2.form表单的使用以及相应的属性值

type:

  • type=”text”是定义表单里面的单行文本框;
  • type=”password” 定义密码框;
  • type=”radio” 单选勾选框;
  • type=”checkbox” 多选勾选框;
  • type=”submit” 提交按钮;
  • type=”reset” 重置按钮;
  • type=”button”或者 两种方式都可以实现空按钮;

menthod

  • 其中 get/post 之间的区别
  • get传送的数据量较小,不能大于2KB。post传送的数据量较大,
  • get安全性非常低,post安全性较高。但是执行效率却比Post方法
    好。

action

  • action=url用来指定处理提交表单的格式.它可以是一个URL地址(提交给程式)或一个电子邮件地址.

target

  • ”“指定提交的结果文档显示的位置:
  • _blank :在一个新的、
  • 无名浏览器窗口调入指定的文档;
  • _self :在指向这个目标的元素的相同的框架中调入文档;
  • _parent :把文档调入当前框的直接的 frameset框中;

3.vue中的双向数据绑定原理(重点深入学习)

vue 双向数据绑定是通过 数据劫持 结合 发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变;

核心:关于VUE双向数据绑定,其核心是 Object.defineProperty()方法
(1)Object.defineProperty(obj, prop, descriptor) ,这个语法内有三个参数,分别为 obj (要定义其上属性的对象) prop (要定义或修改的属性) descriptor (具体的改变方法)
(2)简单地说,就是用这个方法来定义一个值。当调用时我们使用了它里面的get方法,当我们给这个属性赋值时,又用到了它里面的set方法;

4.vue单向数据流

vue单向数据流:在vue中需要遵循单向数据流原则

在父传子的前提下,父组件的数据发生会通知子组件自动更新
子组件内部,不能直接修改父组件传递过来的props => props是只读的

5.undefined、null、NaN有什么区别?

从数据类型上:

  • undefined和null是原始数据类型,当使用双等号对两种类型的 值进行比较时会返回 true,使用三个等号时会返回 false,NaN表示为not a number,用typeof检测undefined返回undefined,null返回object,NaN返回number

从使用场景上:

  • undefined 表示未定义是所有没有赋值变量的默认值,是自动赋值为undefined
  • null 表示空值,可以用null赋值给变量去清空变量
  • NaN的场景就比较多,比如数据的类型转换时,被转换的数据不含有可以转换的部分,就会返回NaN

注意:NaN是一种特殊类型的的number,它与任何数据都不相等,包括自己本身,其他数据类型和NaN运算的结果都是NaN

7.如何获取安全的undefined 值?

因为 undefined 是一个标识符,不是保留字,所以可以被当作变量来使用和赋值, 但是这样会影响 undefined 的正常判断。表达式 void ___ 没有返 回值,因此返回结果是 undefined。void 并不改变表达式的结果, 只是让表达式不返回值。因此可以用 void 0 来获得 undefined。

void后跟一个表达式 void(expression),他会执行这个表达式,然后返回undefined
可以使用void 0来代替undefined,因为undefind不是保留字。所以在某些浏览器下,undefind的值可能会被修改。

8.Object.is() 与比较操作符 “=== ” 、 “==” 的区别?

  • 使用双等号(==)进行相等判断时,如果两边的类型不一致,则会进 行强制类型转化后再进行比较。
  • 使用三等号(===)进行相等判断时,如果两边的类型不一致时,不 会做强制类型准换,直接返回 false。
  • 使用 Object.is 来进行相等判断时,一般情况下和三等号的判断相 同,它处理了一些特殊的情况,比如 -0 和 +0 不再相等,两个 NaN 是相等的 一般情况下NaN不与任何类型相等包括自身

9. 什么是 JavaScript 中的包装类型?

在 JavaScript 中,基本类型是没有属性和方法的,但是为了便于操 作基本类型的值,在调用基本类型的属性或方法时 JavaScript 会在 后台隐式地将基本类型的值转换为对象,例如字符串

  const a = 'abc'
  console.log(a.length); //3
  • 使用Object ()函数显式地将基本类型转换为包装类 型
  • valueOf ()方法将包装类型倒转成基本类型

10.const 对象的属性可以修改吗

  • const 保证的并不是变量的值不能改动,而是变量指向的那个内存地 址不能改动
  • 对于基本类型的数据(数值、字符串、布尔值),其值 就保存在变量指向的那个内存地址,因此等同于常量
  • 引用类型的数据(主要是对象和数组)来说,变量指向数据的 内存地址,保存的只是一个指针,const 只能保证这个指针是固定不 变的,至于它指向的数据结构是不是可变的,就完全不能控制了(例如给对象添加一个新的方法和值)

11.new 操作符的实现步骤

  1. 创建一个新对象
  2. 将构造函数的作用域赋给新对象(也就是将对象的__proto__属性 指向构造函数的 prototype 属性)
  3. 构造函数中的 this 指向该对象,执行构造函数中的代码(也就是 为这个对象添加属性和方法)
  4. 返回新的对象

如果是new一个箭头函数可以吗?
回答:不可以,箭头函数它没有prototype,也没有自己的this 指向,更不可以使用 arguments 参数,所以不能 New 一个箭头函数。

12.this指向问题(JS高级)

this 是执行上下文中的一个属性,它指向最后一次调用这个方法的 对象。

  • 默认绑定
  • 隐式绑定
  • 显示绑定

call(默认传入数据没有格式)
applay(传入数据是一个数组)
bind(传入参数可以是数组或者直接传入都可)但是bind可以减少call和apply多次绑定同一个对象造成的代码冗余。因为bind会返回一个回调函数,在使用多顶绑定时直接调用回调函数即可。

  • new关键字进行绑定

13.JavaScript 脚本延迟加载的方式有哪些?

延迟加载就是等页面加载完成之后再加载 JavaScript 文件。js 延 迟加载有助于提高页面加载速度。

  • defer 属性:给 js 脚本添加 defer 属性,这个属性会让脚本的加 载与文档的解析同步解析,然后在文档解析完成后再执行这个脚本文 件,这样的话就能使页面的渲染不被阻塞。多个设置了defer 属性的脚本按规范来说最后是顺序执行的,但是在一些浏览器中可能不是 这样。
  • async 属性:给 js 脚本添加 async 属性,这个属性会使脚本异步 加载,不会阻塞页面的解析过程,但是当脚本加载完成后立即执行 js 脚本,这个时候如果文档没有解析完成的话同样会阻塞。多个 async 属性的脚本的执行顺序是不可预测的,一般不会按照代码的顺序依次 执行。
  • 动态创建 DOM 方式:动态创建 DOM 标签的方式,可以对文档的加载 事件进行监听,当文档加载完成后再动态的创建 script 标签来引入 js 脚本。
  • 使用 setTimeout 延迟方法:设置一个定时器来延迟加载 js 脚本文 件
  • 让 JS 最后加载:将 js 脚本放在文档的底部,来使 js 脚本尽可能 的在最后来加载执行。

14.对 JSON 的理解

  • JSON 是一种基于文本的轻量级的数据交换格式。它可以被任何的编 程语言读取和作为数据格式来传递。
  • 在项目开发中,使用 JSON 作为前后端数据交换的方式。在前端通过 将一个符合 JSON 格式的数据结构序列化为 JSON 字符串,然后将它传递到后端,后端通过 JSON 格式的字符串 解析后生成对应的数据结构,以此来实现前后端数据的一个传递
  • 因为 JSON 的语法是基于 js 的,因此很容易将 JSON 和 js 中的对 象弄混,但是应该注意的是 JSON 和 js 中的对象不是一回事,JSON 中对象格式更加严格,比如说在 JSON 中属性值不能为函数,不能出 现 NaN 这样的属性值等,因此大多数的 js 对象是不符合 JSON 对 象的格式的。

在 js 中提供了两个函数来实现 js 数据结构和 JSON 格式的转换 处理
JSON.stringify 函数,通过传入一个符合 JSON 格式的数据结构, 将其转换为一个 JSON 字符串。如果传入的数据结构不符合 JSON 格 式,那么在序列化的时候会对这些值进行对应的特殊处理,使其符合 规范。在前端向后端发送数据时,可以调用这个函数将数据对象转化 为 JSON 格式的字符串。
JSON.parse() 函数,这个函数用来将 JSON 格式的字符串转换为一 个 js 数据结构,如果传入的字符串不是标准的 JSON 格式的字符串 的话,将会抛出错误。当从后端接收到 JSON 格式的字符串时,可以 通过这个方法来将其解析为一个 js 数据结构,以此来进行数据的访 问

15.什么是 DOM 和 BOM?

  • DOM 指的是文档对象模型,它指的是把文档当做一个对象,这个对象 主要定义了处理网页内容的方法和接口。
  • DOM 的最根本的对象 document 对象也是 BOM 的 window 对象的子对象。
  • BOM 指的是浏览器对象模型,它指的是把浏览器当做一个对象来对待, 这个对象主要定义了与浏览器进行交互的法和接口。BOM 的核心是 window,而 window 对象具有双重角色,它既是通过 js 访问浏览器 窗口的一个接口,又是一个 Global(全局)对象。
  • window 对象含有 location 对象、navigator 对象、screen 14
    对象等子对象

16.原型和原型链的理解

  • 原型:在 JavaScript 中是使用构造函数来新建一个对象的,每一个构造函 数的内部都有一个 prototype 属性,它的属性值是一个对象,这个 对象包含了可以由该构造函数的所有实例共享的属性和方法。当使用 构造函数新建一个对象后,在这个对象的内部将包含一个指针,这个 指针指向构造函数的 prototype 属性对应的值,在 ES5 中这个指针 被称为对象的原型
  • Object.getPrototypeOf() 方法,可以通过这个方法来获取对象的原 型。
  • 原型链:当访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又会有自己的原 型,于是就这样一直找下去,也就是原型链的概念。
  • JavaScript 对象是通过引用来传递的,创建的每个新对象实 体中并没有一份属于自己的原型副本。当修改原型时,与之相关的对 象也会继承这一改变
  • 原型链的终点:由于 Object 是构造函数,原型链终点 Object.prototype.proto, 而 Object.prototype.proto=== null // true,所以,原型链 的终点是 null。原型链上的所有原型都是对象,所有的对象最终都 是由 Object 构造的,而 Object.prototype 的下一级是 Object.prototype.proto。

17.作用域、作用域链的理解

作用域:
全局作用域

  • 最外层函数和最外层函数外面定义的变量拥有全局作用域
  • 所有未定义直接赋值的变量自动声明为全局作用域
  • 所有 window 对象的属性拥有全局作用域 全局作用域有很大的弊端,过多的全局作用域变量会污染全局命名空 间,容易引起命名冲突

函数作用域

  • 函数作用域声明在函数内部的变零,一般只有固定的代码片段可以访 问到作用域是分层的,内层作用域可以访问外层作用域,反之不行

块级作用域

  • 使用 ES6 中新增的 let 和 const 指令可以声明块级作用域,块级作用 域可以在函数中创建也可以在一个代码块中的创建(由{ }包裹的代 码片段)
    let 和 const 声明的变量不会有变量提升,也不可以重复声明 在循环中比较适合绑定块级作用域,这样就可以把声明的计数器变量 限制在循环内部。

作用域链:

  • 在当前作用域中查找所需变量,但是该作用域没有这个变量,那这个 变量就是自由变量。如果在自己作用域找不到该变量就去父级作用域 查找,依次向上级作用域查找,直到访问到 window 对象就被终止, 这一层层的关系就是作用域链。
  • 作用域链的作用是保证对执行环境有权访问的所有变量和函数的有 序访问,通过作用域链,可以访问到外层环境的变量和函数。

18.Proxy 可以实现什么功能?

ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例

希望监听一个对象的相关操作,那么我们可以先创建一个代理对象(Proxy对象);
之后对该对象的所有操作,都通过代理对象来完成,代理对象可以监听我们想要对原对象进行哪些操作 首先,我们需要new
Proxy对象,并且传入需要侦听的对象以及一个处理对象,可以称之为handler; üconst p = new Proxy(target,
handler) 之后的操作都是直接对Proxy的操作,而不是原有的对象,因为我们需要在handler里面进行侦听;

19.常用的正则表达式有哪些?

大佬整理的很全,大家自行跳转链接,但是希望能够养成自己动手编辑正则的技能。

20.escape、encodeURI、encodeURIComponent 的区别

JavaScript中有三个可以对字符串编码的函数,分别是: escape,encodeURI,encodeURIComponent

  • escape是对字符串(string)进行编码(而另外两种是对URL),作用是让它们在所有电脑上可读
  • encodeURI方法不会对下列字符编码 ASCII字母、数字、~!@#$&*()=:/,;?+’
  • encodeURIComponent方法不会对下列字符编码 ASCII字母、数字、~!*()’

总结
escape()除了 ASCII 字母、数字和特定的符号外,对传进来的字符串全部进行转义编码,因此如果想对URL编码,最好不要使用此方法。而encodeURI() 用于编码整个URI,因为URI中的合法字符都不会被编码转换。encodeURIComponent方法在编码单个URIComponent(指请求参 数)应当是最常用的,它可以讲参数中的中文、特殊字符进行转义,而不会影响整个URL。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拉格朗日(Lagrange)

手敲不易,谢谢各位老板,打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值