
面试笔记(二)【JavaScript】篇
文章平均质量分 54
前端面试题的整合,尽量写全又简洁易懂的风格。
此篇为【JavaScript】相关知识的整理。
面试笔记系列专栏共7个篇章,会不定期更新。
敲起来blingbling
挺秃然的
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
ES6新增数据类型 Symbol和BigInt
目录SymbolBigIntSymbol(ES6 新增数据类型)Symbol 本质上是一种唯一标识符,可用作对象的唯一属性名,这样其他人就不会改写或覆盖你设置的属性值。声明方法:let id = Symbol("id");Symbol 数据类型的特点是唯一性,即使是用同一个变量生成的值也不相等。 let id1 = Symbol('id'); let id2 = Symbol('id'); console.log(id1 == id2); //falseSymbol 数据类型的另一原创 2021-09-08 21:49:07 · 741 阅读 · 0 评论 -
ES6 Module
目录ModuleCommonJs和es6的Module的区别Module“模块”是为完成某一功能所需的一段程序,是系统中“职责单一”且“可替换”的部分。所谓的模块化就是指把系统代码分为一系列职责单一且可替换的模块。模块化开发是指如何开发新的模块和复用已有的模块来实现应用的功能。按需加载 按需加载需要从时间和空间两方面理解:空间上:只加载当前页面的模块;时间上:只有当用户需要某一功能时,才去加载相关模块。模块化开发与按需加载的适用场景应用复杂:不止一个功能部分,这些部分可能共享一些底层代码原创 2021-09-08 21:47:29 · 229 阅读 · 0 评论 -
ES6 class类
传统的javascript中只有对象,没有类的概念。它是基于原型的面向对象语言。原型对象的特点就是将自身的属性共享给新对象。如果要生成一个对象实例,需要先定义一个构造函数,然后通过new操作符来完成。构造函数示例:function Person(name, age) { this.name = name; this.age = age;}Person.prototype.say = function () { return "我的名字叫" + this.name + "今年"原创 2021-09-08 21:44:47 · 154 阅读 · 0 评论 -
ES5和ES6的区别
JavaScriptJavaScript是基于原型的客户端脚本语言,用来给HTML网页增加动态功能。JavaScript由三部分组成:ECMAScript(核心)+ DOM(文档对象模型)+ BOM(浏览器对象模型)ES全称就是ECMAScript,作为JavaScript语言的核心,规定了语言的组成部分:语法、类型、语句、关键字、保留字、操作符、对象。ES5和ES6的不同之处1 系统库的引用ES5中的引用需要先使用require导入包,成为对象,再去进行真正引用// ES5var Reac原创 2021-09-08 21:43:52 · 4301 阅读 · 1 评论 -
ES6箭头函数(主要是this指向)
使用箭头函数语法定义函数,将关键字function删掉,并使用“=>”连接参数列表和函数体:var fn1 = (a, b) => { return a + b }参数只有一个,括号可以省略;无参数时括号不可以省略:// 无参var fn1 = function () { }var fn1 = () => { }// 单个参数var fn2 = function (a) { }var fn2 = a => { }// 多个参数var fn3 = functi原创 2021-09-07 09:35:33 · 163 阅读 · 0 评论 -
...扩展运算符
使用场景和作用1 可以替代apply方法当参数为一个数组,我们需要返回这个参数数组中所有元素之和,普通做法:function f1(x, y, z) { return x + y + z;}var args = [1, 2, 3];// 两种调用方式// 1,这种方式在参数较少的情况下还能应付,但是参数一旦过多就不靠谱了,addFun(args[0], args[1], args[2]) // 6// 2,用apply方法直接传递数组f1.apply(null, args); /原创 2021-09-07 09:31:18 · 233 阅读 · 0 评论 -
ES6 解构赋值
解构赋值是对赋值运算符的扩展。是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。代码书写简洁易读,语义清晰明了;方便复杂对象中数据的获取。1 数组模型的解构(Array)(1)基本let [a, b, c] = [1, 2, 3];console.log(a, b, c); // 1 2 3 (2)可嵌套let [a, [[b], c]] = [1, [[2], 3]];(3)可忽略let [a, , b] = [1, 2, 3];console.log(a, b); /原创 2021-09-07 09:26:53 · 80 阅读 · 0 评论 -
let、const、var
1 前言在ES6出现之前,JavaScript中声明变量就只有通过 var 关键字,函数声明是通过 function 关键字;而在ES6之后,声明的方式有 var 、 let 、 const 、 function 、 class 。2 块级作用域 {}ES5 中作用域有:全局作用域、函数作用域。没有块作用域的概念;ES6 中新增了块级作用域。块作用域由 { } 包括,if 语句和 for 语句里面的{ }也属于块作用域。var不存在块级作用域。let和const存在块级作用域。通过var定义的变原创 2021-09-07 09:24:18 · 86 阅读 · 0 评论 -
async/await
async 标识的函数返回一个promise对象,所以该函数内部,可以添加任何的异步操作代码。而 await 就是then的语法糖。async function f1() { }const res = f1();console.log(res); // Promise { undefined } (返回一个promise对象)async function f1() { return 'aaa'}const res = f1();console.log(res); // Promise原创 2021-09-07 09:22:33 · 188 阅读 · 0 评论 -
Generator函数
Generator函数是ES6提供的一种异步编程解决方案,形式上也是一个普通函数,但有几个显著的特征:– function关键字与函数名之间有一个星号 "*"– 函数体内使用 yield 表达式,定义不同的内部状态 (可以有多个yield)– 直接调用 Generator函数并不会执行,也不会返回运行结果,而是返回一个遍历器对象(Iterator Object)– 依次调用遍历器对象的next方法,遍历 Generator函数内部的每一个状态// 传统函数function foo() {原创 2021-09-07 09:21:59 · 94 阅读 · 0 评论 -
ES6 Promise
目录1 简介2 语法3 Promise的几种状态4 resolve5 reject6 catch7 all8 race9 Promise的作用10 注意1 简介Promise 是异步编程的一种解决方案。所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。在控制台打印Promise:可以发现,Promise是一个构造函数,自身有all、race、reject、resolve等方法;原创 2021-09-07 09:20:46 · 163 阅读 · 0 评论 -
js数组拍平
数组拍平也称数组扁平化,就是将数组里面的数组打开,最后合并为一个数组。var arr = [1,2,[3,4,5,[6,7,8],9],10,[11,12]];1 递归法function fn(arr) { let arr1 = [] arr.forEach((val) => { if (val instanceof Array) { arr1 = arr1.concat(fn(val)) } else {原创 2021-09-07 09:14:08 · 573 阅读 · 0 评论 -
js事件循环
目录1 简介2 栈和队列3 JavaScript单线程4 同步任务和异步任务5 宏任务和微任务1 简介事件循环(Event Loop),是指浏览器或Node的解决JS单线程运行时不会阻塞的一种机制,也就是js实现异步的原理。2 栈和队列栈是一种 LIFO(Last In, First Out)的数据结构,特点即后进先出。(举例:桶装薯片。最下面的要先装进去,但是吃的时候从最上面开始吃。)队列是一种 FIFO(First In, First Out)的数据结构,它的特点就是先进先出。(举例:排队原创 2021-09-07 09:10:38 · 120 阅读 · 0 评论 -
自定义事件
JavaScript 和 HTML 之间往往通过 事件 来实现交互。其中多数为内置事件。在日常开发中,有许多事件,比如:点击事件( click )、鼠标移动事件( mousemove )、元素失去焦点事件( blur )等等。当某些基础事件无法满足我们业务,就可以使用自定义事件来解决。目前实现自定义事件的两种主要方式是 Event() 构造函数 和 CustomEvent() 构造函数 来创建。1 Event()Event() 构造函数,创建一个新的事件对象 Event。1.1 语法let m原创 2021-09-07 09:08:27 · 1402 阅读 · 0 评论 -
== 和 ===
== 代表相同, ===代表严格相同当进行双等号比较时候: 先检查两个操作数数据类型,如果相同, 则进行=比较, 如果不同, 则愿意为你进行一次类型转换, 转换成相同类型后再进行比较, 而===比较时, 如果类型不同,直接就是false。比较过程双等号==(1)如果两个值类型相同,再进行三个等号(===)的比较(2)如果两个值类型不同,需根据以下规则进行类型转换在比较:1)如果一个是null,一个是undefined,那么相等2)如果一个是字符串,一个是数值,把字符串转换成数值之后再进行比较原创 2021-09-06 21:53:05 · 90 阅读 · 0 评论 -
函数柯里化
函数柯里化是指把一个接受多个参数的函数拆解为多个接受单一参数的函数依次调用。function add(x, y) { return x + y}function curryingAdd(x) { // 柯里化后 return function (y) { return x + y }}add(1, 2) // 3curryingAdd(1)(2) // 3用途1 参数复用// 正常正则验证字符串 reg.test(txt)function c原创 2021-09-06 21:51:15 · 106 阅读 · 0 评论 -
防抖和节流
函数防抖:触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。所以如果n秒内一直触发,那么时间一直重新计算,那么函数就一直不会被执行,直到停止触发。简单来说就是将多次操作合并为一次操作进行。函数节流:高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率。一定时间内必然会触发并且只触发一次。节流(throttle)与 防抖(debounce)都是为了限制函数的执行频次,以优化触发频率过高导致的响应速度跟不上而出现延迟或卡顿的现象。1 函数防抖(debounc原创 2021-09-06 21:50:38 · 102 阅读 · 0 评论 -
数组迭代方法
1 forEach 对数组的每个元素执行一次提供的函数。var arr = [1, 2, 3];arr.forEach(function (element, index, array) { console.log(element, index, array)})// output 1 0 [ 1, 2, 3 ] 2 1 [ 1, 2, 3 ] 3 2 [ 1, 2, 3 ]forEach方法还可以传入第二个参数,这个参数是可选的。如果给forEach传递了第二个参数,callb原创 2021-09-06 21:48:57 · 459 阅读 · 0 评论 -
js事件流
27 事件流页面触发一个事件时,会按照一定的顺序来响应事件,事件的响应过程为事件流。当一个节点产生一个事件时,该事件会在元素结点与根节点之间按特定的顺序传播,路径所经过的节点都会收到该事件,这个传播过程称为事件流。事件流的三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。在dom事件流中,事件的目标在捕获阶段不会接受到事件,这意味着在捕获阶段,事件从 document 到 div 后就停止了。下一个阶段是目标阶段,于是事件在 div 上发生,并在事件处理中被看成是冒泡阶段的一部分, 然后,原创 2021-09-06 21:46:51 · 100 阅读 · 0 评论 -
深拷贝和浅拷贝
如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,如果B没变,那就是深拷贝。1 如果是基本数据类型,名字和值都会储存在栈内存中var a = 1;b = a; // 栈内存会开辟一个新的内存空间,此时b和a都是相互独立的b = 2;console.log(a); // 1a = 3console.log(b); // 2当然,这也算不上深拷贝,因为深拷贝本身只针对较为复杂的object类型数据。var a = [1原创 2021-09-06 21:44:17 · 398 阅读 · 1 评论 -
arguments
调用函数时,js会把传入的全部参数存储在arguments里。arguments也是一个对象,而且是一个特殊的对象,它的属性名是按照传入参数的序列来的:第1个参数的属性名是’0’,第2个参数的属性名是’1’,以此类推;并且它还有length属性(就是参数的个数),我们把这种对象叫做类数组对象。function f(a, b) { console.log(a + b); // 3 console.log(arguments) // [Arguments] { '0': 1, '1': 2 }}原创 2021-09-06 21:38:51 · 108 阅读 · 0 评论 -
this的指向
由于严格模式下,禁止this指向全局对象,所以以下示例均运行在非严格模式下(1)全局 & 调用普通函数在全局环境中,this 永远指向 window。console.log(this === window); // true普通函数在调用时候(注意不是构造函数,前面不加 new),其中的 this 也是指向 window。【因为构造函数中的 this 指向实例对象】console.log(this); // windowvar a = thisfunction f1() { c原创 2021-09-06 21:35:41 · 93 阅读 · 0 评论 -
实现异步操作的方法
排在异步任务后面的代码,不等待异步任务结束,而是会马上运行。也就是说,异步不会阻塞后面的任务。这种不连续的执行,就叫做异步(setTimeout、ajax请求都是常见的异步操作);连续的执行,就叫做同步:通常情况下,浏览器向服务器发送请求,服务器返回数据,浏览器执行异步操作。在这里使用定时函数模拟异步请求数据。方法一 使用回调函数function doSomething(callback) { setTimeout(function () { console.log('执行结束原创 2021-09-06 21:29:05 · 939 阅读 · 0 评论 -
call、apply、bind
目录call、apply、bind手写call,apply,bind方法call、apply、bindcall、apply、bind都是改变this指向的方法这三个方法都继承自Function.prototype,所以所有的函数都可以调用这三个方法。function A() { this.flag = 'A'; this.tip = function () { console.log(this.flag); };}function B() { this.flag = 'B原创 2021-09-06 21:27:31 · 78 阅读 · 0 评论 -
Map和Set
1 MapMap对象是键值对的集合,具有极快的查找速度。举个例子,假设要根据同学的名字查找对应的成绩,如果用Array实现,需要两个Array:var names = ['Michael', 'Bob', 'Tracy']; var scores = [95, 75, 85];给定一个名字,查找对应的成绩,先要在names中找到对应的位置,再从scores取出对应的成绩,Array越长,耗时越长。如果用Map实现,只需要一个「名字 - 成绩」的对照表,直接根据名字查找成绩,无论这个表有多大,查原创 2021-09-05 16:24:18 · 212 阅读 · 0 评论 -
原型和原型链
1 函数和对象的关系:对象都是通过函数创建的。对于下面这种类型的代码,一般叫做“语法糖”var obj = {a:10,b:20};var arr = [5, 'x'];但是,其实上面这段代码的实质是下面这样的: var obj = new Object(); obj.a = 10; obj.b = 20; var arr = new Array(); arr[0] = 5; arr[1] = 'x';上述代码中Object和Array都是函数。2 原型prototype每个函原创 2021-09-05 16:21:17 · 81 阅读 · 0 评论 -
构造函数,new实例化对象
1 定义:通过 new来实例化对象的函数叫构造函数。对new理解:new 申请内存, 创建对象。当调用new时,后台会隐式执行new Object()创建对象,所以new创建的字符串、数字是引用类型。2 构造函数的作用:需要创建多个有相同属性/方法的对象时,就需要用到构造函数,它可以方便创建多个对象实例。3 常用的构造函数:var arr = [] 为 var arr = new Array() 的语法糖var obj = {} 为 var obj = new Object原创 2021-09-05 16:12:30 · 3214 阅读 · 0 评论 -
变量提升、函数提升
1 变量提升js创建变量的过程:var a = 1;var b = 2;js在解析上面的代码的时候,其实会按照下面的方式进行解析的:var a;var b;a = 1;b = 2;所以 js 定义一个变量的时候,并不是声明后立即赋值,而是全部声明之后,再到变量的定义的地方赋值。变量声明的过程就是变量的提升。function foo() { var a = 1; console.log(a); console.log(b); var b = 2;}foo();原创 2021-09-05 16:10:18 · 192 阅读 · 0 评论 -
递归函数(阶乘、累加、斐波那契)
1 什么是函数的递归函数反复调用自己,直到最终结果。2 举例阶乘函数function fn(n) { if (n <= 1) { return 1 } else { return n * fn(n - 1) }}累加求和function f(n) { if (n <= 0) { return 0 } else { return n + f(n - 1) }}Fibonacci数列 1,1,2,3,5,8,13,原创 2021-09-05 16:09:29 · 244 阅读 · 0 评论 -
闭包相关以及内存回收
目录闭包内存回收闭包function f1() { var a = 1 function f2() { return a } return f2 // return为了让f2函数能够被使用}var b = f1()b() // 1 b作为全局变量获取到了局部变量a的值在上方代码中,函数 f2 被包括在函数 f1 内部,这时 f1 内部的所有局部变量,对 f2 都是可见的。既然 f2 可以读取 f1 中的局部变量,那么只要把 f2 作为返回值,就可以在 f1 外部原创 2021-09-05 16:05:33 · 563 阅读 · 0 评论 -
立即执行函数
立即执行函数模式是一种语法,可以让函数在定义后立即执行。整个函数包裹在一对括号中,在结尾加上一对括号让函数立即执行。(function () { console.log("123")})()作用:创建一个独立的作用域,这个作用域里面的变量,外面访问不到(即避免「变量污染」)。for (var i = 0; i < 6; i++) { setTimeout(() => { console.log(i) })}上方代码输出6次6,原因: i原创 2021-09-05 16:01:52 · 606 阅读 · 0 评论 -
域和作用域链
在 js中,作用域分为全局作用域和函数作用域作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。一般情况下,变量取值在当前作用域下取,如果在当前作用域中没有该值,就会向上级作用域去查,直到查到全局作用域,这么一个查找过程形成的链条就叫做作用域链。var a = 10function fn() { var b = 20 function bar() { console.log(a + b); } return bar}var x = fn()b = 200x原创 2021-09-05 15:58:30 · 75 阅读 · 0 评论 -
匿名函数作用及应用场景
匿名函数,就是没有名字的函数。声明一个普通函数,然后将函数的名字去掉即是匿名函数;但是单独运行一个匿名函数会报错,此时外面套一层括号即可;执行的话后面加个( )即可。(function () { console.log(123);})倘若需要传值,直接将参数写到括号内即可:(function (msg) { console.log(msg);})('Hello')匿名函数的应用场景1 事件 (比如给按钮增加点击事件)btn.onclick = function () { /原创 2021-09-05 15:56:29 · 3401 阅读 · 0 评论 -
js数据类型
1 js的8种数据类型number、string、boolean、null、undefined、object、symbol、bigInt(object中包含Data、function、Array等)基本类型:除object以外的类型都为基本类型;引用类型:Object2 NaN(Not a Number)NaN 是 Number 中的特殊数值:typeof(NaN) 输出为number3 判断数据类型使用 typeof 判断数据类型:typeof(1) 输出 number(返回一个表示类原创 2021-09-05 15:54:01 · 172 阅读 · 0 评论 -
JavaScript简介
js简介Javascript是一种基于对象的语言,我们遇到的所有东西几乎都是对象。但是它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有 class(类)【虽然后来es6新增了class,但这个class是构造函数语法糖】。基于对象和面向对象的区别面向对象的三大特点(封装,继承,多态)缺一不可。通常基于对象无法利用现有的对象模板产生新的对象类型,继而产生新的对象;也就是说基于对象没有继承。而多态是指父类对象可以产生多个不同的子类对象,没有了继承的概念也就无从谈论多态了。**==js原创 2021-09-04 14:21:31 · 85 阅读 · 0 评论