文末
js前端的重头戏,值得花大部分时间学习。
推荐通过书籍学习,《 JavaScript 高级程序设计(第 4 版)》你值得拥有。整本书内容质量都很高,尤其是前十章语言基础部分,建议多读几遍。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
另外,大推一个网上教程 现代 JavaScript 教程 ,文章深入浅出,很容易理解,上面的内容几乎都是重点,而且充分发挥了网上教程的时效性和资料链接。
学习资料在精不在多,二者结合,定能构建你的 JavaScript 知识体系。
面试本质也是考试,面试题就起到很好的考纲作用。想要取得优秀的面试成绩,刷面试题是必须的,除非你样样精通。
这是288页的前端面试题
在 ES6 之前,ES 的作用域只有两种:全局作用域和函数作用域。
-
全局作用域中的对象在代码中的任何地方都能访问,其生命周期伴随着页面的生命周期。
-
函数作用域就是在函数内部定义的变量或者函数,并且定义的变量或者函数只能在函数内部被访问。函数执行结束之后,函数内部定义的变量会被销毁。
ES6 出现了块级作用域,块级作用域就是使用一对大括号包裹的一段代码,比如函数、判断语句、循环语句,甚至单独的一个{}都可以被看作是一个块级作用域。
===============================================================================
在 JavaScript 中,根据词法作用域的规则,内部函数总是可以访问其外部函数中声明的变量,当通过调用一个外部函数返回一个内部函数后,即使该外部函数已经执行结束了,但是内部函数引用外部函数的变量依然保存在内存中,我们就把这些变量的集合称为闭包。
如果闭包使用不正确,会很容易造成内存泄漏,所以在使用闭包的时候,你要尽量注意一个原则:如果该闭包会一直使用,那么它可以作为全局变量而存在;但如果使用频率不高,而且占用内存又比较大的话,那就尽量让它成为一个局部变量。
任何闭包的使用场景都离不开这两点:
-
创建私有变量
-
延长变量的生命周期
场景:
- 柯里化函数
点击JavaScript的执行机制——作用域链和闭包查看详解
========================================================================================
-
函数执行时首先看函数名前面是否有".“,有的话,”."前面是谁,this就是谁;没有的话this就是window
-
自执行函数中的this永远是window
-
在构造函数模式中,类中(函数体中)出现的this.xxx=xxx中的this是当前类的一个实例
-
call、apply和bind,可以改变this的指向,为函数的第一个参数
-
箭头函数的this看外层的是否有函数,如果有,外层函数的this就是内部箭头函数的this,如果没有,则this是window。
====================================================================================
操作方法:
-
增:push()、unshift()、splice()、concat()
-
删:pop()、shift()、splice()、slice()
-
改:splice()
-
查:indexOf()、includes()、find()
排序方法:
-
数组本身有两个方法:reverse()、sort()
-
定义排序函数:冒泡排序、插入排序、递并排序、计数排序
转换方法:
- join()
迭代方法:
-
some()
-
every()
-
forEach()
-
filter()
-
map()
点击Javscript数组中最常用的方法(建议收藏)查看详解
==========================================================================
冒泡排序:
var arr = [3,4,1,2,21,5,15,6,63];
function BubbleSort(ary){
for(var i = 0; i < ary.length - 1; i++){
for(var j = i + 1; j < ary.length; j++){
var current = ary[i];
if(current > ary[j]){
var tmp = ary[j];
ary[j] = current;
ary[i] = tmp;
}
}
}
return ary;
}
1
BubbleSort(arr); // [1, 2, 3, 4, 5, 6, 15, 21, 63]
点击Javscript数组中最常用的方法(建议收藏)查看详解
=====================================================================================
操作方法:
-
增:concat()、
-
删:slice()、substr()、substring()
-
改:trim()、trimLeft()、trimRight()、repeat()、toLowerCase()、 toUpperCase()
-
查:chatAt()、indexOf()、startWith()、includes()
转换方法:
- split
模板匹配方法:
-
match()
-
search()
-
replace()
点击Javascript字符串常见的方法查看详解
===================================================================================
常见的类型转换有:
-
强制转换(显示转换)
-
自动转换(隐式转换)
点击js的六种数据类型、强制类型转换和隐式类型转换查看详解
==================================================================================
等于操作符:
等于操作符用两个等于号( == )表示,如果操作数相等,则会返回 true;
等于操作符(==)在比较中会先进行类型转换,再确定操作数是否相等;
-
两个都为简单类型,字符串和布尔值都会转换成数值,再比较
-
简单类型与引用类型比较,对象转化成其原始类型的值,再比较
-
两个都为引用类型,则比较它们是否指向同一个对象
-
null 和 undefined 相等
-
存在 NaN 则返回 false
全等操作符:
全等操作符由 3 个等于号( === )表示,只有两个操作数在不转换的前提下相等才返回 true。即类型相同,值也需相同
区别:
-
相等操作符(==)会做类型转换,再进行值的比较,全等运算符不会做类型转换
-
null 和 undefined 比较,相等操作符(==)为true,全等为false
除了在比较对象属性为null或者undefined的情况下,我们可以使用相等操作符==,其他情况建议一律使用全等操作符===;
====================================================================================
事件模型可以分为三种:
-
原始事件模型(DOM0级)
-
标准事件模型(DOM2级)
-
IE事件模型(基本不用)
点击Javascript中的事件模型查看详情
============================================================================
多线程可以并行处理任务,但是线程是不能单独存在的,它是由进程来启动和管理的。
一个进程就是一个程序的运行实例。详细解释就是,启动一个程序的时候,操作系统会为该程序创建一块内存,用来存放代码、运行中的数据和一个执行任务的主线程,我们把这样的一个运行环境叫进程。
关系:
-
进程中的任意一线程执行出错,都会导致整个进程的崩溃。
-
线程之间共享进程中的数据。
-
当一个进程关闭之后,操作系统会回收进程所占用的内存。
-
进程之间的内容相互隔离。
点击到底什么是Event Loop?查看详解
=====================================================================================
JavaScript 在设计之初便是单线程,即指程序运行时,只有一个线程存在,同一时间只能做一件事;为了解决单线程运行阻塞问题,JavaScript用到了计算机系统的一种运行机制,这种机制就叫做事件循环(Event Loop)
在JavaScript中,所有的任务都可以分为:
-
同步任务:立即执行的任务,同步任务一般会直接进入到主线程中执行
-
异步任务:异步执行的任务,比如ajax网络请求,setTimeout定时函数等
同步任务与异步任务的运行流程图如下:
从上面我们可以看到,同步任务进入主线程,即主执行栈,异步任务进入任务队列,主线程内的任务执行完毕为空,会去任务队列读取对应的任务,推入主线程执行。上述过程的不断重复就是事件循环;
点击对Javascript中的事件循环机制的探索和详解查看详解
==========================================================================
===============================================================================
是什么:
事件代理,俗地来讲,就是把一个元素响应事件(click、keydown…)的函数委托到另一个元素;
事件流的都会经过三个阶段:捕获阶段 -> 目标阶段 -> 冒泡阶段,而事件委托就是在冒泡阶段完成;
事件委托,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,而不是目标元素
当事件响应到目标元素上时,会通过事件冒泡机制从而触发它的外层元素的绑定事件上,然后在外层元素上去执行函数
应用场景:
如果我们有一个列表,列表之中有大量的列表项,我们需要在点击列表项的时候响应一个事件,如果给每个列表项一一都绑定一个函数,那对于内存消耗是非常大的,这时候就可以事件委托,把点击事件绑定在父级元素ul上面,然后执行事件的时候再去匹配目标元素
点击事件代理和应用场景查看详情
========================================================================
是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。
把接受多个参数的函数转换成接受一个单一参数的函数
// 普通函数
var add = function(x, y) {
return x + y;
}
add(3, 4) //7var foo = ‘bar’;
// 柯里化
var foo = function(x) {
return function(y) {
return x + y
}
}
foo(3)(4) // 7
===============================================================================
是什么:
AJAX全称(Async Javascript and XML)
即异步的JavaScript 和XML,是一种创建交互式网页应用的网页开发技术,可以在不重新加载整个网页的情况下,与服务器交换数据,并且更新部分网页
Ajax的原理简单来说通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用JavaScript来操作DOM而更新页面
流程图如下:
实现过程:
-
创建 Ajax的核心对象 XMLHttpRequest对象
-
通过 XMLHttpRequest 对象的 open() 方法与服务端建立连接
-
构建请求所需的数据内容,并通过XMLHttpRequest 对象的 send() 方法发送给服务器端
-
通过 XMLHttpRequest 对象提供的 onreadystatechange 事件监听服务器端你的通信状态
-
接受并处理服务端向客户端响应的数据结果
-
将处理结果更新到 HTML页面中
点击Ajax的原理、实现步骤和封装查看详解
==================================================================================
作用:
call、apply、bind作用是改变函数执行时的上下文,简而言之就是改变函数运行时的this指向;
区别:
-
apply、call、bind 三者都是可以改变函数的this指向的
-
apply 和 call 都是改变函数this指向,并传入参数后立即调用执行该函数
-
bind 是在改变函数this指向,并传入参数后返回一个新的函数,不会立即调用执行
-
apply 传入的参数是数组形式的;call 传入的参数是按顺序的逐个传入并以逗号隔开; bind 传入的参数既可以是数组形式,也可以是按顺序逐个传入。
点击bind、call和apply的区别查看详情
===================================================================================
DOM全称为The Document Object Model,即文档对象模型。应该理解为是一个规范,是一种跨平台的、独立于编程语言的API,它把HTML、XHTML或XML文档当作一个树结构,而每个节点视为一个对象,这些对象可以被编程语言操作,进而改变文档的结构,映射到文档的显示。
简单来说,DOM就是我们为了方便编程语言对HTML等文档进行操作,所以啊,把HTML文档中的节点全部视为一个个的对象,然后这些对象依照层级关系形成一棵树,这棵树就命名为DOM树。有了对象,编程就方便多了,只要一层层拿到对象就可以优雅地改变对象的属性进而动态地改变HTML等文档的展示。
下面就来分析DOM常见的操作,主要分为:
-
创建节点
-
查询节点
-
更新节点
-
添加节点
-
删除节点
点击DOM的理解和常见的操作查看详解
========================================================================================
是什么:
BOM (Browser Object Model),浏览器对象模型,提供了独立于内容与浏览器窗口进行交互的对象
其作用就是跟浏览器做一些交互效果,比如如何进行页面的后退,前进,刷新,浏览器的窗口发生变化,滚动条的滚动,以及获取客户的一些信息如:浏览器品牌版本,屏幕分辨率;
BOM对象:
-
window
-
location
-
navigator
-
screen
-
history
点击对BOM的理解和常见的BOM对象查看详解
========================================================================================
是什么:
内存泄漏(Memory leak)是在计算机科学中,由于疏忽或错误造成程序未能释放已经不再使用的内存;
对于持续运行的服务进程,必须及时释放不再用到的内存。否则,内存占用越来越高,轻则影响系统性能,重则导致进程崩溃;
所以大多数语言提供自动内存管理,减轻程序员的负担,这被称为"垃圾回收机制"
常见内存泄露情况:
-
意外的全局变量
-
定时器也常会造成内存泄露
-
还有闭包,延长了函数内部变量的生命周期,调用不当和不及时释放也会造成内存泄漏
JavaScript中本地存储的方式有哪些?区别及应用场景?
=============================================================================================
本地存储的方式:
-
cookie
-
sessionStorage
-
sessionStorage
区别:
-
存储大小:cookie数据大小不能超过4k,sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大
-
有效时间:localStorage存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;sessionStorage数据在当前浏览器窗口关闭后自动删除;cookie设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
-
数据与服务器之间的交互方式,cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端;sessionStorage和localStorage不会自动把数据发给服务
应用场景:
-
标记用户与跟踪用户行为的情况,推荐使用cookie
-
适合长期保存在本地的数据(令牌),推荐使用localStorage
-
敏感账号一次性登录,推荐使用sessionStorage
点击本地存储的方式介绍查看详解
===========================================================================================
是什么:
函数缓存,就是将函数运算过的结果进行缓存
本质上就是用空间(缓存存储)换时间(计算过程)
缓存只是一个临时的数据存储,它保存数据,以便将来对该数据的请求能够更快地得到处理
实现方法:
-
闭包
-
柯里化
-
高阶函数
以下几种情况下,适合使用缓存:
-
对于昂贵的函数调用,执行复杂计算的函数;
-
对于具有有限且高度重复输入范围的函数
-
对于具有重复输入值的递归函数
-
对于纯函数,即每次使用特定输入调用时返回相同输出的函数
点击如何实现函数缓存查看详解
====================================================================================
节流(throttle):
- n 秒内只运行一次,若在 n 秒内重复触发,只有一次执行
防抖(debounce):
- n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时
白话文理解:
把电梯完成一次运送,类比为一次函数的执行和响应
假设电梯有两种运行策略 debounce(防抖) 和 throttle(节流),超时设定为15秒,不考虑容量限制
电梯第一个人进来后,15秒后准时运送一次,这是节流;
电梯第一个人进来后,等待15秒。如果过程中又有人进来,15秒等待重新计时,直到15秒后开始运送,这是防抖
区别:
相同点:
-
都可以通过使用 setTimeout 实现
-
目的都是,降低回调执行频率。节省计算资源
不同点:
- 函数防抖,在一段连续操作结束后,处理回调,利用clearTimeout和 setTimeout实现。函数节流,在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能
总结
三套“算法宝典”
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
算法刷题LeetCode中文版(为例)
人与人存在很大的不同,我们都拥有各自的目标,在一线城市漂泊的我偶尔也会羡慕在老家踏踏实实开开心心养老的人,但是我深刻知道自己想要的是一年比一年有进步。
最后,我想说的是,无论你现在什么年龄,位于什么城市,拥有什么背景或学历,跟你比较的人永远都是你自己,所以明年的你看看与今年的你是否有差距,不想做咸鱼的人,只能用尽全力去跳跃。祝愿,明年的你会更好!