对象篇
模块化编程-自研模块加载器
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
大厂面试题分享 面试题库
后端面试题库 (面试必备) 推荐:★★★★★
地址:前端面试题库
html语义化的理解
-
代码结构: 使页面在没有css的情况下,也能够呈现出好的内容结构
-
有利于SEO: 爬虫根据标签来分配关键字的权重,因此可以和搜索引擎建立良好的沟通,帮助爬虫抓取更多的有效信息
-
方便其他设备解析: 如屏幕阅读器、盲人阅读器、移动设备等,以有意义的方式来渲染页面
-
便于团体的开发和维护: 语义化使代码更具有可读性,让其他开发人员更加理解你的html结构,减少差异化。遵循 W3C 标准的团队都遵循这个标准。
常用的语义元素有:header、nav、main、footer、article、section、aside
iframe
iframe称之为嵌入式框架、嵌入式框架可以把完整的网页内容嵌入到现有的网页中。
优点
-
重载页面时不需要重载整个页面只需要重载页面中的一个框架页
-
可以使脚本、可以并行下载
-
可以实现跨子域通信
缺点
-
会产生很多页面,不容易管理
-
调用外部页面,需要额外调用 CSS,给页面带来额外的请求次数
-
iframe 会阻塞主页面的 onload 事件
-
浏览器的后退按钮无效
-
无法被一些搜索引擎索引识别
-
多数小型的移动设备无法完全显示框架
BOM和DOM分别是什么
BOM是浏览器对象模型: 用来获取或设置浏览器的属性、行为。例如:新建窗口、获取屏幕分辨率、浏览器版本号等
DOM是文档对象模型: 用来获取或设置文档中标签的属性、例如获取或者设置input表单的value值
CSS盒模型
盒模型都是由四个部分组成的,分别是margin、border、padding和content
标准盒模型和IE盒模型的区别在于设置width和height时,所对应的范围不同:
-
标准盒模型的width和height属性的范围只包含了content,
-
IE盒模型的width和height属性的范围包含了border、padding和content。
可以通过修改元素的box-sizing属性来改变元素的盒模型:
-
box-sizeing: content-box表示标准盒模型(默认值)
-
box-sizeing: border-box表示IE盒模型(怪异盒模型)
怎么让一个 div 水平垂直居中
-
通过 verticle-align:middle 实现垂直居中
-
通过父元素设置伪元素 :before ,然后设置子元素 verticle-align:middle 实现垂直居中
-
通过绝对定位实现垂直居中
-
通过 transform 实现垂直居中
-
使用弹性盒子居中
BFC
所谓 BFC,指的是一个独立的布局环境,BFC 内部的元素布局与外部互不影响。
触发 BFC 的方式有很多,常见的有:
-
设置浮动
-
overflow 设置为 auto、scroll、hidden
-
positon 设置为 absolute、fixed
常见BFC的应用
-
解决浮动元素令父元素高度坍塌的问题
-
解决非浮动元素被浮动元素覆盖问题
-
解决外边距垂直方向重合问题
JS 的基本数据类型有哪些?基本数据类型和引用数据类型的区别
基本数据类型
JavaScript共有八种数据类型,分别是 Undefined、Null、Boolean、Number、String、Object、Symbol、BigInt
这些数据可以分为原始数据类型和引用数据类型:
-
栈:原始数据类型(Undefined、Null、Boolean、Number、String)
-
堆:引用数据类型(对象、数组和函数)
基本数据类型和引用数据类型的区别
-
访问方式:
-
原始值:访问到的是值
-
引用值:访问到的是引用地址 (js不允许直接访问保存在堆中的对象、首先得到在堆中的地址,然后按照这个地址去获得对象的值)
-
比较方式:
-
原始值:比较的是值
-
引用值: 比较的是引用的地址
-
变量赋值:
-
原始值赋值:赋值的是新值,与原来互不影响
-
引用值赋值:赋值的是地址,指向原值所在堆内存中的地址
-
动态属性:
-
原始值:赋值的是值
-
引用值:赋值的是地址
ES6 新增哪些东西
-
箭头函数
-
字符串模板
-
支持模块化(import、export)
-
类(class、constructor、extends)
-
let、const 关键字
-
新增一些数组、字符串等内置构造函数方法,例如 Array.from、Array.of 、Math.sign、Math.trunc 等
-
新增一些语法,例如扩展操作符、解构、函数默认参数等
-
新增一种基本数据类型 Symbol
-
新增元编程相关,例如 proxy、Reflect
-
Set 和 Map 数据结构
-
Promise
-
Generator 生成器
let const var 的区别?什么是块级作用域?如何用?
-
var 定义的变量,是函数作用域,没有块的概念,可以跨块访问, 不能跨函数访问,有变量提升。
-
let 定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问,无变量提升,不可以重复声明。
-
const 用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改,无变量提升,不可以重复声明。
-
var不存在暂时性死区,let和const存在暂时性死区
-
let和const创建的全局变量没有给window设置相应的属性
暂时性死区:使用
let / const 命令声明变量之前,该变量都是不可用的
箭头函数与普通函数的区别
-
箭头函数没有自己的this、会捕获其所在的上下文的this值,作为自己的this值
-
箭头函数继承来的this指向永远不会改变
-
call()、apply()、bind()等方法不能改变箭头函数中this的指向
-
箭头函数是匿名函数,不能作为构造函数,不能使用new
-
箭头函数没有自己的arguments
-
箭头函数没有prototype(原型)
-
箭头函数不能用作Generator函数,不能使用yeild关键字
bind,apply,call三者的区别
-
三者都可以改变函数的this对象指向
-
三者第一个参数都是this要指向的对象,如果如果没有这个参数或参数为undefined或null,则默认指向全局window
-
三者都可以传参,但是apply是数组,而call是参数列表,且apply和call是一次性传入参数,而bind可以分为多次传入
-
bind是返回绑定this之后的函数,apply、call 则是立即执行
是否了解 JavaScript 中的包装类型?
包装对象 : 就是当基本类型以对象的方式去使用时,JavaScript 会转换成对应的包装类型,相当于 new 一个对象,内容和基本类型的内容一样,然后当操作完成再去访问的时候,这个临时对象会被销毁,然后再访问时候就是 undefined
代码理解:
var str = 'hello';
str.number = 10; //假设我们想给字符串添加一个属性 number ,后台会有如下步骤
(
var _str = newString('hello'); // 1 找到对应的包装对象类型,然后通过包装对象创建出一个和基本类型值相同的对象
_str.number = 10; // 2 通过这个对象调用包装对象下的方法 但结果并没有被任何东西保存
_str =null; // 3 这个对象又被销毁
)
console.log(str.number); // undefined 当执行到这一句的时候,因为基本类型本来没有属性,后台又会重新重复上面的步骤
(
var str = newString('hello');// 1 找到基本包装对象,然后又新开辟一个内存,创建一个值为 hello 对象
str.number = undefined;// 2 因为包装对象下面没有 number 这个属性,所以又会重新添加,因为没有值,所以值是未定义;然后弹出结果
str =null; // 3 这个对象又被销毁
)
复制代码
JS 中如何进行数据类型的转换?
类型转换可以分为两种,隐性转换和显性转换
显性转换
主要分为三大类:数值类型、字符串类型、布尔类型
三大类的原始类型值的转换规则我就不一一列举了,更多详情文章链接
👉
juejin.cn/post/695617…
数值类型(引用类型转换)
Number({a: 1}) // NaNNumber([1, 2, 3]) // NaNNumber([5]) // 5
第一步,调用对象自身的`valueOf`方法。如果返回原始类型的值,则直接对该值使用`Number`函数,不再进行后续步骤。
第二步,如果`valueOf`方法返回的还是对象,则改为调用对象自身的`toString`方法。如果`toString`方法返回原始类型的值,
则对该值使用`Number`函数,不再进行后续步骤。
第三步,如果`toString`方法返回的是对象,就报错。
补充一点:`valueOf`和`toString`方法,都是可以自定义的
复制代码
字符串类型(引用类型转换)
String({a: 1}) // "[object Object]"String([1, 2, 3]) // "1,2,3"`String`方法背后的转换规则,与`Number`方法基本相同,只是互换了`valueOf`方法和`toString`方法的执行顺序。
复制代码
隐性转换
类型 | 转换前 | 转换后 |
number | 4 | 4 |
string | “1” | 1 |
string | “” | 0 |
boolean | true | 1 |
boolean | false | 0 |
undefined | undefined | NaN |
null | null | 0 |
详情看上方👆文章链接
闭包
闭包是指有权访问另一个函数作用域中的变量的函数 ———— 《JavaScript高级程序设计》
- 闭包用途:
-
能够访问函数定义时所在的词法作用域(阻止其被回收)
-
私有变量化
-
模拟块级作用域
-
创建模块
-
闭包缺点:闭包调用函数的变量,并且这个变量在函数执行完之后,不能释放,会导致函数的变量一直保存在内存中,过多的闭包可能会导致内存泄漏。
-
解决:变量设置成null
原型和原型链
原型
-
每个对象都有一个 proto 属性,该属性指向自己的原型对象
-
每个构造函数都有一个 prototype 属性,该属性指向实例对象的原型对象
-
原型对象里的 constructor 指向构造函数本身
原型链
当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾null
作用域和作用域链的理解
作用域
(1)全局作用域
-
最外层函数和最外层函数外面定义的变量拥有全局作用域
-
所有未定义直接赋值的变量自动声明为全局作用域
-
所有window对象的属性拥有全局作用域
-
全局作用域有很大的弊端,过多的全局作用域变量会污染全局命名空间,容易引起命名冲突。
(2)函数作用域
-
函数作用域声明在函数内部的变零,一般只有固定的代码片段可以访问到
-
作用域是分层的,内层作用域可以访问外层作用域,反之不行
(3)块级作用域
-
使用ES6中新增的let和const指令可以声明块级作用域,块级作用域可以在函数中创建也可以在一个代码块中的创建(由{ }包裹的代码片段)
-
let和const声明的变量不会有变量提升,也不可以重复声明
-
在循环中比较适合绑定块级作用域,这样就可以把声明的计数器变量限制在循环内部。
作用域链
-
在当前作用域中查找所需变量,但是该作用域没有这个变量,那这个变量就是自由变量。
-
如果在自己作用域找不到该变量就去父级作用域查找,依次向上级作用域查找,直到访问到window对象就被终止,这一层层的关系就是作用域链。
作用域链有一个非常重要的特性,那就是作用域中的值是在函数创建的时候,就已经被存储了,是静态的。
防抖和节流
我们在平时开发的时候,会有很多场景会频繁触发事件,比如说搜索框实时发请求,onmousemove、resize、onscroll 等,有些时候,我们并不能或者不想频繁触发事件,这时候就应该用到函数防抖和函数节流。
函数防抖(debounce),指的是短时间内多次触发同一事件,只执行最后一次,或者只执行最开始的一次,中间的不执行。
数据结构与算法
这一块在笔试、面试的代码题中考核较多,其中常考的数据结构主要有:数组、链表、队列、栈、Set、Map、哈希表等,不同数据结构有不同的方法以及储存原理,这些算是技术岗的必备知识。算法部分主要分为两大块,排序算法与一些其他算法题。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
排序算法根据考频高低主要有:快速排序、归并排序、堆排序、冒泡排序、插入排序、选择排序、希尔排序、桶排序、基数排序、Timsort这十种,这类考核点要么是算法的时间、空间复杂度、稳定度,要么是直接手写代码,故在理解算法原理的同时,对JS语言版的排序算法代码也要加强记忆。
- 二叉树层序遍历
- B 树的特性,B 树和 B+树的区别
- 尾递归
- 如何写一个大数阶乘?递归的方法会出现什么问题?
- 把多维数组变成一维数组的方法
- 知道的排序算法 说一下冒泡快排的原理
- Heap 排序方法的原理?复杂度?
- 几种常见的排序算法,手写
- 数组的去重,尽可能写出多个方法
- 如果有一个大的数组,都是整型,怎么找出最大的前 10 个数
- 知道数据结构里面的常见的数据结构
- 找出数组中第 k 大的数组出现多少次,比如数组【1,2, 4,4,3,5】第二大的数字是 4,出现两次,所以返回 2
- 合并两个有序数组
- 给一个数,去一个已经排好序的数组中寻找这个数的位 置(通过快速查找,二分查找)
视频】](https://bbs.csdn.net/topics/618166371)**
排序算法根据考频高低主要有:快速排序、归并排序、堆排序、冒泡排序、插入排序、选择排序、希尔排序、桶排序、基数排序、Timsort这十种,这类考核点要么是算法的时间、空间复杂度、稳定度,要么是直接手写代码,故在理解算法原理的同时,对JS语言版的排序算法代码也要加强记忆。
- 二叉树层序遍历
- B 树的特性,B 树和 B+树的区别
- 尾递归
- 如何写一个大数阶乘?递归的方法会出现什么问题?
- 把多维数组变成一维数组的方法
- 知道的排序算法 说一下冒泡快排的原理
- Heap 排序方法的原理?复杂度?
- 几种常见的排序算法,手写
- 数组的去重,尽可能写出多个方法
- 如果有一个大的数组,都是整型,怎么找出最大的前 10 个数
- 知道数据结构里面的常见的数据结构
- 找出数组中第 k 大的数组出现多少次,比如数组【1,2, 4,4,3,5】第二大的数字是 4,出现两次,所以返回 2
- 合并两个有序数组
- 给一个数,去一个已经排好序的数组中寻找这个数的位 置(通过快速查找,二分查找)
[外链图片转存中…(img-nYm5Bh1S-1715021315547)]