最近在整理 JavaScript 的时候发现遇到了很多面试中常见的面试题,本部分主要是作者在 Github 等各大论坛收录的 JavaScript 相关知识和一些相关面试题时所做的笔记,分享这份总结给大家,对大家对 JavaScript 的可以来一次全方位的检漏和排查,感谢原作者 CavsZhouyou 的付出,原文链接放在文章最下方,如果出现错误,希望大家共同指出!
附笔记链接,阅读往期更多优质文章可移步查看,喜欢的可以给我点赞鼓励哦:https://github.com/Wscats/articles
涉及知识点:
栈:原始数据类型(Undefined、Null、Boolean、Number、String)
堆:引用数据类型(对象、数组和函数)
回答:
详细资料可以参考:
《JavaScript 有几种类型的值?》
《JavaScript 有几种类型的值?能否画一下它们的内存图;》
《什么是堆?什么是栈?他们之间有什么区别和联系?》
《标准内置对象的分类》
《JS 所有内置对象属性和方法汇总》
《JavaScript 深入理解之 undefined 与 null》
《JavaScript 深入理解之原型与原型链》
p.proto
p.constructor.prototype
Object.getPrototypeOf(p)
以 0X、0x 开头的表示为十六进制。
以 0、0O、0o 开头的表示为八进制。
以 0B、0b 开头的表示为二进制格式。
《JavaScript 字符串间的比较》
《详解 JS 中 Number()、parseInt() 和 parseFloat() 的区别》
《前端表单验证常用的 15 个 JS 正则表达式》
《JS 常用正则汇总》
《JS - 生成随机数的方法汇总(不同范围、类型的随机数)》
《Fisher and Yates 的原始版》
《javascript 实现数组随机排序?》
《JavaScript 学习笔记:数组随机排序》
《JavaScript 深入理解之对象创建》
《JavaScript 深入理解之继承》
《JavaScript 深入理解之作用域链》
1.第一种是函数调用模式,当一个函数不是一个对象的属性时,直接作为函数来调用时,this 指向全局对象。
2.第二种是方法调用模式,如果一个函数作为一个对象的方法来调用时,this 指向这个对象。
3.第三种是构造器调用模式,如果一个函数用 new 调用时,函数执行前会新创建一个对象,this 指向这个新创建的对象。
4.第四种是 apply 、 call 和 bind 调用模式,这三个方法都可以显示的指定调用函数的 this 指向。其中 apply 方法接收两个参数:一个是 this 绑定的对象,一个是参数数组。call 方法接收的参数,第一个是 this 绑定的对象,后面的其余参数是传入函数执行的参数。也就是说,在使用 call() 方法时,传递给函数的参数必须逐个列举出来。bind 方法通过传入一个对象,返回一个 this 绑定了传入对象的新函数。这个函数的 this 指向除了使用 new 时会被改变,其他情况下都不会改变。
《JavaScript 深入理解之 this 详解》
《eval()》
《DOM, DOCUMENT, BOM, WINDOW 有什么区别?》
《Window 对象》
《DOM 与 BOM 分别是什么,有何关联?》
《JavaScript 学习总结(三)BOM 和 DOM 详解》
《JS 事件模型》
1.事件是用户操作网页时发生的交互动作,比如 click/move, 事件除了用户触发的动作外,还可以是文档加载,窗口滚动和大小调整。事件被封装成一个 event 对象,包含了该事件发生时的所有相关信息( event 的属性)以及可以对事件进行的操作( event 的方法)。
2.事件处理机制:IE 支持事件冒泡、Firefox 同时支持两种事件模型,也就是:事件冒泡和事件捕获。
3.event.stopPropagation() 或者 ie 下的方法 event.cancelBubble = true;
《Javascript 事件模型系列(一)事件及事件的三种模型》
《Javascript 事件模型:事件捕获和事件冒泡》
《一个 DOM 元素绑定多个事件时,先执行冒泡还是捕获》
《JavaScript 事件委托详解》
《为什么 ["1", "2", "3"].map(parseInt) 返回 [1,NaN,NaN]?》
《JavaScript 深入理解之闭包》
相关知识点:
消除 Javascript 语法的一些不合理、不严谨之处,减少一些怪异行为;
消除代码运行的一些不安全之处,保证代码运行的安全;
提高编译器效率,增加运行速度;
为未来新版本的 Javascript 做好铺垫。
区别:
1.禁止使用 with 语句。
2.禁止 this 关键字指向全局对象。
3.对象不能有重名的属性。
《Javascript 严格模式详解》
《js 判断一个对象是否属于某一类》
《instanceof》
《new 操作符具体干了什么?》
《JavaScript 深入之 new 的模拟实现》
《Object.prototype.hasOwnProperty()》
《深入了解 JavaScript 中的 JSON 》
《通过一行代码学 JavaScript》
一般有以下几种方式:
defer 属性
async 属性
动态创建 DOM 方式
使用 setTimeout 延迟方法
让 JS 最后加载
《JS 延迟加载的几种方式》
《HTML 5 <code><script></code> <code>async</code> 属性》
2005 年 2 月,AJAX 这个词第一次正式提出,它是 Asynchronous JavaScript and XML 的缩写,指的是通过 JavaScript 的
异步通信,从服务器获取 XML 文档从中提取数据,再更新当前网页的对应部分,而不用刷新整个网页。
具体来说,AJAX 包括以下几个步骤。
1.创建 XMLHttpRequest 对象,也就是创建一个异步调用对象
2.创建一个新的 HTTP 请求,并指定该 HTTP 请求的方法、URL 及验证信息
3.设置响应 HTTP 请求状态变化的函数
4.发送 HTTP 请求
5.获取异步调用返回的数据
6.使用 JavaScript 和 DOM 实现局部刷新
一般实现:
《XMLHttpRequest 对象》
《从 ajax 到 fetch、axios》
《Fetch 入门》
《传统 Ajax 已死,Fetch 永生》
《浅谈浏览器缓存》
《前端优化:浏览器缓存技术介绍》
《请求头中的 Cache-Control》
《Cache-Control 字段值详解》
1.在 ajax 发送请求前加上 anyAjaxObj.setRequestHeader("If-Modified-Since","0")。
2.在 ajax 发送请求前加上 anyAjaxObj.setRequestHeader("Cache-Control","no-cache")。
3.在 URL 后面加上一个随机数: "fresh=" + Math.random();。
4.在 URL 后面加上时间戳:"nowtime=" + new Date().getTime();。
5.如果是使用 jQuery,直接这样就可以了$.ajaxSetup({cache:false})。这样页面的所有 ajax 都会执行这条语句就是不需要保存缓存记录。
《Ajax 中浏览器的缓存问题解决方法》
《同步和异步的区别》
1.通过 jsonp 跨域
2.document.domain + iframe 跨域
3.location.hash + iframe
4.window.name + iframe 跨域
5.postMessage 跨域
6.跨域资源共享(CORS)
7.nginx 代理跨域
8.nodejs 中间件代理跨域
9.WebSocket 协议跨域
《前端常见跨域解决方案(全)》
《浏览器同源政策及其规避方法》
《跨域,你需要知道的全在这里》
《为什么 form 表单提交没有跨域问题,但 ajax 提交有跨域问题?》
《深入浅出 Nginx》
《HTTP cookies》
《聊一聊 cookie》
《浅谈模块化开发》
《Javascript 模块化编程(一):模块的写法》
《前端模块化:CommonJS,AMD,CMD,ES6》
《Module 的语法》
它们之间的主要区别有两个方面。
(1)第一个方面是在模块定义时对依赖的处理不同。AMD 推崇依赖前置,在定义模块的时候就要声明其依赖的模块。而 CMD 推崇
就近依赖,只有在用到某个模块的时候再去 require。
(2)第二个方面是对依赖模块的执行时机处理不同。首先 AMD 和 CMD 对于模块的加载方式都是异步加载,不过它们的区别在于
模块的执行时机,AMD 在依赖模块加载完成后就直接执行依赖模块,依赖模块的执行顺序和我们书写的顺序不一定一致。而 CMD
在依赖模块加载完成后并不执行,只是下载而已,等到所有的依赖模块都加载好后,进入回调函数逻辑,遇到 require 语句
的时候才执行对应的模块,这样模块的执行顺序就和我们书写的顺序保持一致了。
《前端模块化,AMD 与 CMD 的区别》
1.CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。ES6 模块的运行机制与 CommonJS 不一样。JS 引擎对脚本静态分析的时候,遇到模块加载命令 import,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。
2.CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。CommonJS 模块就是对象,即在输入时是先加载整个模块,生成一个对象,然后再从这个对象上面读取方法,这种加载称为“运行时加载”。而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。
《requireJS 的用法和原理分析》
《requireJS 的核心原理是什么?》
《从 RequireJs 源码剖析脚本加载原理》
《requireJS 原理分析》
《JS 模块加载器加载原理是怎么样的?》
《ECMAScript 6 实现了 class,对 JavaScript 前端开发有什么意义?》
《Class 的基本语法》
《简述 document.write 和 innerHTML 的区别。》
(1)创建新节点
(2)添加、移除、替换、插入
(3)查找
(4)属性操作
《DOM 概述》
《原生 JavaScript 的 DOM 操作汇总》
《原生 JS 中 DOM 节点相关 API 合集》
《apply、call 的区别和用途》
常见的类数组转换为数组的方法有这样几种:
(1)通过 call 调用数组的 slice 方法来实现转换
(2)通过 call 调用数组的 splice 方法来实现转换
(3)通过 apply 调用数组的 concat 方法来实现转换
(4)通过 Array.from 方法来实现转换
详细的资料可以参考:
《JavaScript 深入之类数组对象与 arguments》
《javascript 类数组》
《深入理解 JavaScript 类数组》
《JavaScript 深入理解之 Array 类型详解》
《Array.prototype.fill()》
《尾后逗号》
《JavaScript 深入理解之变量对象》
1.使用位运算代替一些简单的四则运算。
2.避免使用过深的嵌套循环。
3.不要使用未定义的变量。
4.当需要多次访问数组长度时,可以用变量保存起来,避免每次都会去进行属性查找。
《如何编写高性能的 Javascript?》
《深入理解 V8 的垃圾回收原理》
《JavaScript 中的垃圾回收》
1.意外的全局变量
2.被遗忘的计时器或回调函数
3.脱离 DOM 的引用
4.闭包
《JavaScript 内存泄漏教程》
《4 类 JavaScript 内存泄漏及如何避免》
《杜绝 js 中四种内存泄漏类型的发生》
《javascript 典型内存泄漏及 chrome 的排查方法》
《pushState + ajax 实现浏览器无刷新前进后退》
《Manipulating the browser history》
《为什么把 script 标签放在 body 结束标签之后 html 结束标签之前?》
《从 Chrome 源码看浏览器如何加载资源》
有三种办法来解决这个问题:
1.通过 meta 标签禁用网页的缩放。
2.通过 meta 标签将网页的 viewport 设置为 ideal viewport。
3.调用一些 js 库,比如 FastClick
《移动端 300ms 点击延迟和点击穿透》
《什么是“前端路由”》
《浅谈前端路由》
《前端路由是什么东西?》
《浅谈前端单元测试》
《JavaScript 判断浏览器类型》
《Web 开发中的“黑话”》
《Polyfill 为何物》
《如何更有效的获取文件扩展名》
《轻松理解 JS 函数节流和函数防抖》
《JavaScript 事件节流和事件防抖》
《JS 的防抖与节流》
《escape,encodeURI,encodeURIComponent 有什么区别?》
《字符编码详解》
《字符编码笔记:ASCII,Unicode 和 UTF-8》
《浏览器事件循环机制(event loop)》
《详解 JavaScript 中的 Event Loop(事件循环)机制》
《什么是 Event Loop?》
《这一次,彻底弄懂 JavaScript 执行机制》
相关资料:
《JavaScript 专题之深浅拷贝》
《前端面试之道》
call 函数的实现步骤:
1.判断调用对象是否为函数,即使我们是定义在函数的原型上的,但是可能出现使用 call 等方式调用的情况。
2.判断传入上下文对象是否存在,如果不存在,则设置为 window 。
3.处理传入的参数,截取第一个参数后的所有参数。
4.将函数作为上下文对象的一个属性。
5.使用上下文对象来调用这个方法,并保存返回结果。
6.删除刚才新增的属性。
7.返回结果。
apply 函数的实现步骤:
3.将函数作为上下文对象的一个属性。
4.判断参数值是否传入
4.使用上下文对象来调用这个方法,并保存返回结果。
5.删除刚才新增的属性
6.返回结果
bind 函数的实现步骤:
2.保存当前函数的引用,获取其余传入参数值。
3.创建一个函数返回
4.函数内部使用 apply 来绑定函数调用,需要判断函数作为构造函数的情况,这个时候需要传入当前函数的 this 给 apply 调用,其余情况都传入指定的上下文对象。
《手写 call、apply 及 bind 函数》
《JavaScript 深入之 call 和 apply 的模拟实现》
《JavaScript 专题之函数柯里化》
《十进制的 0.1 为什么不能用二进制很好的表示?》
《十进制浮点数转成二进制》
《浮点数的二进制表示》
《js 浮点数存储精度丢失原理》
《浮点数精度之谜》
《JavaScript 浮点数陷阱及解法》
《0.1+0.2 !== 0.3?》
《JavaScript 中奇特的~运算符》
《关于 2 的补码》
《前端安全系列(一):如何防止 XSS 攻击?》
《内容安全策略(CSP)》
《前端安全系列之二:如何防止 CSRF 攻击?》
《[ HTTP 趣谈] origin, referer 和 host 区别》
《web 安全之--点击劫持攻击与防御技术简介》
《Web 安全漏洞之 SQL 注入》
《如何防范常见的 Web 攻击》
《浅析前端开发中的 MVC/MVP/MVVM 模式》
《MVC,MVP 和 MVVM 的图示》
《MVVM》
《一篇文章了解架构模式:MVC/MVP/MVVM》
《Vue.js 双向绑定的实现原理》
《Object.defineProperty()》
《Virtual DOM》
《理解 Virtual DOM》
《深度剖析:如何实现一个 Virtual DOM 算法》
《网上都说操作真实 DOM 慢,但测试结果却比 React 更快,为什么?》
《你需要知道的 requestAnimationFrame》
《CSS3 动画那么强,requestAnimationFrame 还有毛线用?》
《不聊 webpack 配置,来说说它的原理》
《前端工程化——构建工具选型:grunt、gulp、webpack》
《浅入浅出 webpack》
《前端构建工具发展及其比较》
《最全的获取元素宽高及位置的方法》
《用 Javascript 获取页面元素的位置》
《函数式编程初探》
1.HTTP 协议未规定 GET 和 POST 的长度限制
2.GET 的最大长度显示是因为浏览器和 web 服务器限制了 URI 的长度
3.不同的浏览器和 WEB 服务器,限制的最大长度不一样
4.要支持 IE,则最大长度为 2083byte,若只支持 Chrome,则最大长度 8182byte
《HTTP 协议中 URI 和 URL 有什么区别?》
《你知道 URL、URI 和 URN 三者之间的区别吗?》
《URI、URL 和 URN 的区别》
《HTML 关于 post 和 get 的区别以及缓存问题的理解》
《懒加载和预加载》
《网页图片加载优化方案》
《基于用户行为的图片等资源预加载》
《mouseenter 与 mouseover 为何这般纠缠不清?》
《原生 js 实现拖拽功能基本思路》
《用 setTimeout 实现 setInterval》
《setInterval 有什么缺点?》
1.声明的变量只在声明时的代码块内有效
2.不存在声明提升
3.存在暂时性死区,如果在变量声明前使用,会报错
4.不允许重复声明,重复声明会报错
1.Symbol 函数前不能使用 new 命令,否则会报错。
2.Symbol 函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。
3.Symbol 作为属性名,该属性不会出现在 for...in、for...of 循环中,也不会被 Object.keys()、Object.getOwnPropertyNames()、JSON.stringify() 返回。
4.Object.getOwnPropertySymbols 方法返回一个数组,成员是当前对象的所有用作属性名的 Symbol 值。
5.Symbol.for 接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建并返回一个以该字符串为名称的 Symbol 值。
6.Symbol.keyFor 方法返回一个已登记的 Symbol 类型值的 key。
1.ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
2.WeakSet 结构与 Set 类似,也是不重复的值的集合。但是 WeakSet 的成员只能是对象,而不能是其他类型的值。WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,
1.Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
2.WeakMap 结构与 Map 结构类似,也是用于生成键值对的集合。但是 WeakMap 只接受对象作为键名( null 除外),不接受其他类型的值作为键名。而且 WeakMap 的键名所指向的对象,不计入垃圾回收机制。
1.将 Object 对象的一些明显属于语言内部的方法(比如 Object.defineProperty,放到 Reflect 对象上。
2.修改某些 Object 方法的返回结果,让其变得更合理。
3.让 Object 操作都变成函数行为。
4.Reflect 对象的方法与 Proxy 对象的方法一一对应,只要是 Proxy 对象的方法,就能在 Reflect 对象上找到对应的方法。这就让 Proxy 对象可以方便地调用对应的 Reflect 方法,完成默认行为,作为修改行为的基础。也就是说,不管 Proxy 怎么修改默认行为,你总可以在 Reflect 上获取默认行为。
《require() 源码解读》
《Promises/A+ 规范》
《Promise》
更多关于设计模式的资料可以参考:
《JavaScript 设计模式》
《JavaScript 中常见设计模式整理》
《观察者模式和发布订阅模式有什么不同?》
《vue 生命周期深入》
《Vue 实例》
《VUE 组件之间数据传递全集》
《做面试的不倒翁:浅谈 Vue 中 computed 实现原理》
《深入理解 Vue 的 watch 实现原理及其实现方式》
《导航守卫》
《Vue 面试中,经常会被问到的面试题 Vue 知识点整理》
《Vue2.0 v-for 中 :key 到底有什么用?》
《vue 中 key 的作用》
《混入》
《常用的几种 Content-Type》
《JavaScript 专题之类型判断(上)》
《js 判断一个 object 对象是否为空》
《原生 jsonp 具体实现》
《jsonp 的原理与实现》
《前端程序员经常忽视的一个 JavaScript 面试题》
《一道考察运算符优先级的 JavaScript 面试题》
《一道常被人轻视的前端 JS 面试题》
根据上面这些属性,可以计算出网页加载各个阶段的耗时。比如,网页加载整个过程的耗时的计算方法如下:
《Performance API》
《ECMAScript 变量》
《JavaScript 前端倒计时纠偏实现》
1.管道通信
2.消息队列通信
3.信号量通信
4.信号通信
5.共享内存通信
6.套接字通信
《进程间 8 种通信方式详解》
《进程与线程的一个简单解释》
最后如果文章和笔记能带您一丝帮助或者启发,请不要吝啬你的赞和收藏,你的肯定是我前进的最大动力 😁
更多内容请关注:https://github.com/Wscats