整理面试题更新(...ing)

面试题

二级目录

1. 说说你对盒子模型的理解

CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:外边距(margin)、边框(border)、内边距(padding)、实际内容(content)四个属性,分为标准模型和IE模型,标准盒模型的宽度不包括内边距,IE模型的宽度要包括内边距。
content:即实际内容,显示文本和图像;
border:即边框,围绕元素内容的内边距的一条或多条线,由粗细、样式、颜色三部分组成;
padding:即内边距,清除内容周围的区域,内边距是透明的,取值不能为负,受盒子的background属性影响;
margin:即外边距,在元素外创建格外的空白,空白通常指不能放其他元素的区域。
这些部分相互之间有一定的关系,例如,盒子的总宽度可以通过内容宽度、内边距宽度、边框宽度和外边距宽度的和来计算。
盒子模型在网页布局中非常重要,通过设置不同的尺寸和样式,可以实现元素的定位、大小调整和间距控制等。CSS中提供了一系列的属性,用于控制和调整盒子模型的各个部分,例如width、height、padding、border、margin等。
盒模型分为W3C标准盒模型和怪异盒模型
标准盒模型和IE盒模型的区别在于设置width和height时,所对应的范围不同:
标准盒模型中width和height属性的范围指的就是content部分的
IE盒模型中width和height属性的范围指的就是content+border+padding在三个加起来的
切换盒模型的时候,可以借助CSS中的属性box-sizing属性
box-sizing:content-box是W3C盒子模型
box-sizing:border-box是IE盒模型
怪异盒模型的使用场景:
兼容性问题:一些旧版本的浏览器可能不正确地解析标准盒模型,导致页面的布局出现问题。在这种情况下,可以通过设置怪异盒模型来解决兼容性问题
维护旧代码:如果正在维护一个旧的网站,该网站使用怪异盒模型,而你并不想或无法修改现有代码,那么你可能需要继续使用怪异盒模型以保持页面的一致性和正确性。

2. css选择器有哪些?优先级?哪些属性可以继承?

id选择器>类选择器>属性选择器>伪类选择器>标签选择器>伪元素选择器>相邻兄弟选择器>子选择器>后代选择器>通配符选择器
对于选择器的优先级:
标签选择器、伪元素选择器:1
类选择器、伪类选择器、属性选择器:10
Id选择器:100
内联样式:1000;
PS:
!Important声明的样式优先级最高;
如果优先级相同,则最后出现的样式生效;
继承得到的样式的优先级最低;
通用选择器、子选择器和相邻兄弟选择器并不在这四个等级中,所以他们的权值都为0;
样式表的来源不同时,优先级顺序为:内联样式>内部样式>外部样式>浏览器用户自定义样式>浏览器默认样式
继承的属性
字体系列属性
font-family:字体系列
font-weight:字体的粗细
font-size:字体的大小
font-style:字体的风格
文本系列属性
text-index:文本缩进
text-align:文本水平对齐
line-height:行高
word-spacing:单词之间的间距
letter-spacing:中位或者字母之间的间距
text-transform:控制文本大小写(就是uppercase、lowercase、capitalize)
color:文本颜色
元素可见性
visibility:控制元素显示隐藏
列表布局属性
list-style:列表风格,包括list-style-type、list-style-image等
光标属性
cursor:滚滚表显示为何种形态

定位属性

伪类选择器和伪元素选择器的区别?
两者都是CSS中用于选择文档中特定状态或位置的元素的特殊选择器。它们之间有一些重要的区别:
伪类选择器
伪类选择器用于选择处于特定状态的元素,如鼠标悬停状态、被点击状态、第一个子元素等
伪类选择器以冒号(:)开头,后面跟着伪类的名称,如:hover,:active,:first-child等。
伪类选择器可以与其他选择器(如元素选择器、类选择器、ID选择器等)组合使用,以缩小选择范围。例如,a:hover选择所有被鼠标悬停的链接元素
伪元素选择器
用于选择元素的特定部分或生成额外的内容,如元素的第一个字母、元素的第一行等
以双冒号(::)开头,后面跟着伪元素的名称,如::first-letter、::first-line等
可以在元素中生成额外的内容,并对其进行样式化
一般只能与元素选择器配合使用,不能与其他选择器(如类选择器、ID选择器)组合使用

3. 元素水平垂直居中的方法有哪些?如果元素不定宽高呢?

通过flex布局
使用flex布局可以很方便地实现元素的垂直和水平居中,只需要在父容器上设置display:flex和justify-content:center,align-items:center(主轴方向)即可
元素不定宽高时垂直居中的方法
使用table-cell布局同样可以实现元素的垂直和水平居中
ps:需要在父容器上加上display:table来使display:table-cell生效
使用grid布局
可以将display:flex改写成 display:grid,并添加place-items:center
使用绝对定位和transform属性
通过将子元素的position属性设置为absolute,left和top值都为50%,然后通过transform:translate函数将其往左和往上移动子元素宽高一半的距离
Margin和绝对定位 四个值为0 margin:0 auto

4. 怎么理解回流跟重绘?什么场景下会触发?

回流:
当渲染树中部分或者全部元素的尺寸、结构或者属性发生变化时,浏览器会重新渲染部分或者全部文档的过程就称为回流。
触发场景:
页面的首次渲染;
浏览器的窗口大小发生变化;
元素的内容发生变化;
元素的尺寸或者位置发生变化;
元素的字体大小发生变化;
激活CSS伪类;
查询某些属性或者调用某些方法;
添加或者删除可见的DOM元素;
在触发回流重排的时候,由于浏览器渲染页面是基于流失布局的,所以当触发回流时,会导致周围的DOM元素重新排列,它的影响范围有两种:
全局范围:从根节点开始,对整个渲染树进行重新布局
局部范围:对渲染树的某个部分或者一个渲染对象进行重新布局

浏览器渲染页面的流程?回答蓝色字
构建DOM树:浏览器从服务器获取HTML文档,并解析HTML代码,构建DOM树结构。DOM树表示文档的结构和层次关系
构建CSSOM树:浏览器解析CSS样式表,构建CSSOM树。CSSOM表示文档的样式信息
合并DOM树和CSSOM树:将DOM树和CSSOM树合并成一个渲染树,渲染树只包含需要显示的文档节点和其样式信息
布局计算:根据渲染树的节点和其样式信息,进行布局计算,确定每个节点在页面中的位置和大小
绘制页面:根据布局计算的结果,使用绘图命令将页面的内容绘制到屏幕上
栅格化:即那个页面划分为一个一个小的矩形区域,称为栅格,然后将栅格中的内容转换为位图
合成和显示:将位图发送给GPU进行合成,最终显示在屏幕上
在这个过程中,浏览器还会进行优化措施,如异步加载资源、缓存机制、样式预处理等,以提高页面的加载速度和渲染性能。
需要注意的是,以上流程是一个简化的描述,实际中还会涉及到一些细节和优化策略,例如重绘和回流的优化、异步加载脚本的执行等。不同浏览器可能有一些差异,但总体流程是相似的。
当触发回流时,一定会触发重绘,但是重绘不一定会引发回流

transform会触发重绘和回流吗?
transform属性可以应用于元素来进行旋转、缩放、平移或倾斜德恩变换效果,而不会引起重绘和回流
使用transform属性进行变换时,浏览器会将元素的渲染层与其他层分离,将变换应用于独立的“合成层”,而不会影响其他元素的布局和渲染。这种独立的渲染过程不会触发重绘和回流,因此transform属性对于性能优化非常有用。
然而,值得注意的是,如果在
transform 属性之后的操作(如修改元素的尺寸或位置)需要触发回流的话,会导致浏览器重新计算元素布局,从而可能引起回流。因此,在使用
transform 属性时,最好避免与具有回流效果的操作同时进行。

transform原理?
是通过创建一个变换矩阵来实现元素的变化。变化矩阵是一个33或44的矩阵,其中包含了旋转、缩放、平移和倾斜等变换的参数

重绘:
当页面中某些元素的样式发生变化,但是不会影响其在文档流中的位置时,浏览器就会对元素进行重新绘制,这个过程就是重绘。
触发场景:
color、background相关属性:background-color、background-image等
outline相关属性:outline-color、outline-width、text-decoration
border-radius、visibility、box-shadow
PS:当触发回流时,一定会触发重绘,但是重绘不一定会引发回流
减少回流与重绘的措施:
操作DOM时,尽量在低层级的DOM节点进行操作;
不要使用table布局,一个小的改动可能会使整个table进行重新布局;
使用CSS的表达式;
不要频繁操作元素的样式,对于静态页面,可以修改类名,而不是样式;
使用absolute或者fixed,使元素脱离文档流,这样他们发生变化就不会影响其他元素;
避免频繁操作DOM,可以创建一个文档片段documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中
将元素先设置display:none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘。
将DOM的多个读操作(或者写操作)放在一起,而不是读写操作穿插着写。这得益于浏览器的渲染队列机制

5. 什么是响应式设计?响应式设计的基本原理是什么?如何做?

响应式设计是一个网站能够兼容多个终端,而不是为每一个终端做一个特定的版本;
页面的设计与开发应当根据用户行为以及设备环境(系统平台,屏幕尺寸,屏幕定向等)进行相应的响应和调整
关于原理:
基本原理是通过媒体查询(@media)查询检测不同的设备屏幕尺寸做处理,页面头部必须有meta声明viewport
如何做?
媒体查询
百分比
百分比布局缺陷:
依赖于父元素的尺寸:百分比布局的子元素尺寸是相对于父元素的尺寸来计算的,因此,如果父元素的尺寸不稳定或无法确定,子元素的布局可能会受到影响。这可能导致在某些情况下布局出现混乱或不符合预期
对于复杂布局的限制:百分比布局适用于相对简单的布局场景,当对于复杂的布局需求,例如多列布局或嵌套布局,百分比布局可能变得复杂且难以管理。在这些情况下,使用其他布局技术(如弹性布局或网格布局)可能更加灵活和方便
对于固定大小元素的限制:百分比布局适用于自适应布局,但对于具有固定大小的元素,如背景图像或像素精确的UI元素,百分比布局可能不适用。在这些情况下,需要使用其他单位(如像素或rem)来确保元素的准确尺寸
兼容性问题:尽管百分比布局在现代浏览器中得到广泛支持,但在某些旧版本的浏览器中可能存在兼容性问题。在设计百分比布局时,需要进行兼容性测试,并根据需要提供备用方案或使用其他布局技术
vw/vh
rem
实现rem布局
设置的字体大小,在css中,rem单位是相对于根元素(即)的字体大小来计算的。因此,首先需要设置元素的字体大小。
使用rem单位进行布局:使用rem单位来替代传统的像素单位进行布局。1rem等于根元素的字体大小。
例如,如果要设置一个元素的宽度为根元素字体大小的2倍,可以这样写:

使用rem单位进行布局时,所有的尺寸都将根据根元素的字体大小进行相对调整。
响应式布局:通过设置根元素的字体大小,可以实现响应式布局。随着浏览器窗口大小的变化,根元素的字体大小也会相应调整,从而影响整个页面的布局。
.my-element {
width: 2rem;
}

例如,可以使用媒体查询(media queries)来根据不同的屏幕宽度设置不同的根元素字体大小,以实现响应式布局:
@media (max-width: 768px) {
html {
font-size: 14px;
}
}

@media (min-width: 769px) and (max-width: 1024px) {
html {
font-size: 16px;
}
}

@media (min-width: 1025px) {
html {
font-size: 18px;
}
}

js实现rem的实现方式
a. 获取根据根元素的字体大小:在JavaScript中,可以使用document.documentElement来获取根元素(即HTML),然后使用getComputedStyle方法获取其计算后的样式。从中可以提取出根元素的字体大小
var rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize);

b. 设置rem单位的值:将需要使用rem单位的元素的尺寸除以根元素的字体大小,即可得到使用rem单位的值
var elementWidth = 200; // 假设需要设置的元素宽度为200px
var remWidth = elementWidth / rootFontSize + ‘rem’;

c. 动态设置样式:使用JavaScript动态设置元素的样式,将计算得到的rem值赋给相应的属性
var element = document.getElementById(‘my-element’); // 假设需要设置样式的元素的ID为’my-element’
element.style.width = remWidth;

6. 如果要做优化,CSS提高性能的方法有哪些?

减少选择器的复杂性:过于复杂的选择器会增强CS解析和匹配的时间。尽量使用简单的选择器,并避免使用通配符(*)选择器和嵌套选择器。
避免使用昂贵的属性和值:某些CSS属性和值的计算成本较高,例如使用box-shadow、text-shadow等。在性能敏感的情况下,尽量避免使用这些属性和值。
压缩和合并CSS文件:将多个CSS文件合并为一个文件,可以减少HTTP请求的数量,并通过压缩CSS文件大小来加快加载速度。
使用缩写属性:使用缩写属性可以减少CSS文件大小,并降低解析时间。例如,使用margin和padding的缩写属性,可以将四个方向的值合并为一个值。
避免使用!important:过多地使用!important会增加CSS解析的复杂性,尽量避免使用它,除非确实需要覆盖特定的样式。
避免使用CSS表达式:CSS表达式是一种强大但性能较差的特性,应尽量避免使用。通常可以使用其他方式来实现相同的效果。
使用CSS预处理器:CSS预处理器如Sass和Less提供了更高级的功能和语法,可以帮助提高CSS的可维护性和性能。预处理器可以将CSS代码编译为最终的优化版本。
使用媒体查询:使用媒体查询可以根据设备的特性和屏幕尺寸动态加载不同的CSS样式,从而避免不必要的样式加载和渲染。
延迟加载CSS:将不影响首次渲染的CSS代码延迟加载,可以加快页面的加载速度。可以使用异步加载、懒加载或通过JavaScript动态加载CSS。
使用CSS动画和过渡效果:CSS动画和过渡效果通常比使用JavaScript实现的动画性能更好。尽量使用CSS动画和过渡来提高性能和流畅度。

7. 对前端工程师这个职位是怎么样理解的?它的前景会怎么样

作为一名前端工程师,主要负责开发和维护网页前端部分,即用户在浏览器中直接交互的界面。前端工程师需要熟悉 HTML、CSS 和 JavaScript 等前端技术,掌握相关的框架和工具,如 React、Vue.js、Webpack 等。同时,前端工程师还需要具备良好的设计和用户体验意识,能够将设计师提供的视觉设计转化为交互流畅、用户友好的网页界面。
前端工程师的主要职责包括:
实现网页前端界面:将设计师提供的视觉设计转化为网页界面,使用 HTML、CSS 和 JavaScript 等技术进行开发。

优化用户体验:关注用户体验,提升网页的加载速度和响应性能,确保用户能够顺畅地浏览和操作网页。

跨平台和跨浏览器兼容性:确保网页在不同的浏览器和设备上都能正常显示和运行,优化兼容性。

与后端接口对接:与后端开发人员进行合作,对接后端接口,实现数据的获取和交互。

前端工程师的前景非常广阔。随着互联网的快速发展,越来越多的企业和组织需要开发和维护网站和网页应用程序。同时,移动互联网的普及和技术的进步,也催生了大量的移动端和响应式网页的需求。前端工程师的技术栈和能力要求也在不断扩展,例如移动端开发、PWA(Progressive Web App)、前端性能优化、前端框架和工具的使用等等。
未来,前端工程师的前景依然较为乐观。随着云计算、人工智能、物联网等技术的快速发展,前端工程师有机会参与更多领域的开发,如大数据可视化、人机交互界面、虚拟和增强现实应用等。同时,前端工程师的职位也与设计、产品、运营等职能有着密切的联系,具备良好的团队合作和沟通能力可以在职场中获得更多的机会。总体来说,前端工程师的岗位前景较为广阔,并且持续不断地更新和进化。

8. 说说JavaScript中的数据类型?存储上的差别?

基本数据类型:
数字number用于表示数值,包括整数和浮点数
字符串 string:用于表示文本数据,使用单引号或双引号阔气来
布尔值Boolean:表示真或假
空值null:表示一个空的活不存在的值
未定义undefined:表示未定义的值
符号symbol:表示唯一的表示符。这些基本数据类型在存储上都是以固定大小的方式存储,他们是不可变的,也就是说,每次对其进行操作时,都会创建一个新的值。
复杂数据类型:
对象object:表示对个值的集合,可以存储键值对。对象可以存储任意类型的数据,并且可以通过键访问值。对象是引用类型,存储的是指向实际数据的引用,而不是数据本身。这意味着当多个变量引用同一个对象时,他们实际上引用的是同一个对象
数组array:表示一个有序的集合,可以存储多个值。数组可以存储任意类型的数据,并且可以通过索引访问值。数组也是引用类型,存储的是指向实际数据的引用。
在内存中,基本数据类型的值会直接存储在变量所分配的内存空间中。而引用类型的值(对象和数组)存储在堆内存中。变量实际上存储的是在指向堆内存中实际数据的地址
当复制基本数据类型的值时,会将值复制到新的变量中。而复制引用类型的值时,实际上只是复制了指向堆内存中数据的地址,多个变量引用的是同一个对象或数组。
存储差别:
基本数据类型在内存中占据固定大小的空间,退出直接存储在栈中
复杂数据类型的大小不固定,通常存储在堆中,而在栈中存储的是指向堆内存地址的引用
基本数据类型的存储是按值进行的,每个变量都有自己的独立存储空间,他们之间互不影响。当一个变量的值被赋给另一个变量时,会创建一个新的副本。
复杂数据类型的存储是按引用进行的。当复杂数据类型赋值给一个变量时,实际上是将内存中的引用地址赋给了变量,而不是复制整个数据。因此,多个变量可以引用同一个对象,对其中一个变量的修改会影响到其他引用了相同对象的变量。

9. typeof 与 instanceof 区别

两者都是JavaScript中用于检查数据类型的运算符,typeof无法判断对象和数组还有null因为返回的都是object
instanceof 检测构造函数的prototype属性是否出现在某个实例对象的原型链上,用来区分自定义对象类型返回一个布尔值,不能直接判断类型,因为实例是一个对象或函数创建的是引用类型 所以需要通过基本类型对应的包装对象来判断所以对于null和undefined就检测不了
区别:
typeof运算符用于检查一个值的数据类型,返回一个表示数据类型的字符串;typeof运算符适用于检查基本数据类型、函数和未定义的变量
instanceof运算符用于检查一个对象是否是某个特定类的实例。它检查一个对象的原型链,如果原型链中存在指定类的构造函数,则返回true,否则返回false。
总结:
typeof用于检查数据类型,返回一个字符串,适用于基本数据类型、函数和未定义的变量
instanceof 用于检查对象是否为某个特定类的实例,返回一个布尔值,适用于对象类型。
如果想要通过检测数据类型还可以使用Object.prototype.toString.call()会返回一个[object xxx]的字符串(xxx就是类型)但是不能准确判断是否是实例,也就无法区分对象类型
Array.isArray()是一个静态方法 判断是否为一个数组 返回一个布尔值

10. 说说你对闭包的理解?闭包使用场景

闭包是指在一个函数内部创建的函数,该函数可以访问并持有外部函数的变量,即使外部函数已经执行完毕,这个函数依然可以访问到那些变量。换句话说,闭包可以使函数访问其词法作用域之外的变量。换句话说,闭包可以使函数访问其词法作用域之外的变量。
闭包可以让你在一个内层函数中访问到其外层函数的作用域 , 也可以说是函数 + 上下文调用。
闭包的优缺点:
优点:可以重复使用变量,避免全局变量的污染和私有变量的存在
缺点:常驻内存增大内存的使用量,使用不当会造成内存泄漏。
闭包会使函数中的变量都被保存在内存中,内存消耗很大,不能滥用
使用场景:
保护变量:闭包可以用于创建私有变量,将变量封装在函数内部,外部无法直接访问和修改,只能通过闭包提供的接口来操作变量
计数器和累加器:闭包可以用于创建计数器和累加器,通过闭包持有一个变量,并提供增加或减少的方法,每次调用方法都可以得到变量的更新结果
延迟执行和回调:闭包可以用于创建延迟执行的函数,将需要延迟执行的代码包裹在闭包中,并设置定时器,从而实现延迟执行的效果。闭包还可以用于实现回调函数,将函数传递给其他函数,在合适的时机调用。
模块化开发:闭包可以用于创建模块化的代码结构,通过闭包可以将一组相关的函数和变量封装在一个作用域内,避免全局变量污染和命名冲突
创建闭包的最常见的方式是在一个函数内创建另一个函数,创建的函数可以访问到当前函数的局部变量

两个常用的用途:
使我们在函数外部访问到函数内部的变量。通过使用闭包,可以通过在外部调用闭包函数,从而在外部访问到函数内部的变量,可以使用这种方法来创建私有变量
使已经运行结束的函数上下文中的变量对象继续留在内存中,因为闭包函数暴露了这个变量对象的引用,所以这个变量对象不会被回收
垃圾回收机制和内存泄露?
导致内存泄露的原因:
意外的全局变量:由于使用未声明的变量,而意外的创建了一个全局变量,而使这个变量一直留在内存中无法被回收
被遗忘的计时器或回调函数:设置了setInterval定时器,而忘记取消它,如果循环函数有对外部变量的引用的话,那么这个变量会被一直留在内存中,而无法被回收
脱离DOM的引用:获取一个DOM元素的引用,而后面这个元素被删除,由于一直保留对这个元素的引用,所以它也无法被回收。
闭包:不合理的使用闭包,从而导致某些变量一直被留在内存当中。
垃圾回收概念:
JavaScript代码运行时,需要分配内存空间来存储变量和值。当变量不在参与运行时,就需要系统收回被占用的内存空间
回收机制:
JavaScript具有自动回收机制,会定期对哪些不再使用的变量、对象所占用的内存进行释放,原理就是找到不再使用的变量,然后释放掉其所占用的内存
JavaScript中存在两种变量:局部变量和全局变量。全局变量的生命周期会持续要页面卸载;而局部变量声明在函数中,它的生命周期从函数执行开始,直到函数执行结束,在这个过程中,局部变量会在堆或栈中存储他们的值,当函数执行结束后,这些局部变量不再使用,他们所占的空间就会被释放
不过,当局部变量被外部函数使用时,其中一种情况就是闭包,在函数执行结束后,函数外部的变量依然指向函数内部的局部变量,此时局部变量依然在被使用,所以不会回收
垃圾回收的方式:
浏览器通常使用的垃圾回收方法有两种:标记清除,引用计数
标记清除
引用计数
减少垃圾回收
对数组进行优化:
对object进行优化:对象尽量复用,对于不再使用的对象,就将其设置为null,尽快被回收
对函数进行优化:在循环中的函数表达式,如果可以复用,尽量放在函数的外面

循环中使用闭包解决var定义函数的问题?
for (var i = 1; i <= 5;i++){
setTimeout(function timer() {
console.log(i)
},i1000)
}
首先因为setTimeout是一个异步函数,所以会先把循环全部执行完毕,这时候i=6,所以会输出一堆6。三种解决方法
for (var i = 1; i <= 5;i++){
;(function (j){
setTimeout(function timer() {
console.log(i)
},i
1000)
})(i)
}
在上述代码中,首先使用了立即执行函数将i传入函数内部,这个时候值就被固定在了参数j上面不会该笔那,当下次执行timer这个闭包的时候,就可以使用外部函数的变量j,从而达到目的。
使用setTimeout的第三个参数,这个参数会被当成timer函数的参数传入。
使用let定义i来解决问题

词法作用域是什么,以及它的特点?
也称为静态作用域,是指在代码编写阶段确定变量和函数作用域的规则。它是根据变量和函数在源代码中的位置来确定其作用域的。
在词法作用域中,作用域是由代码的结构和嵌套关系决定的,而不是由代码的执行过程决定的。当代码嵌套时,内部作用域可以访问外部作用域中定义的变量,而外部作用域无法访问内部作用域中定义的变量
这个作用域的形成是因为在词法分析阶段,编译器就已经确定了每个变量在哪个作用域中被声明,当代码执行时,根据作用域链来查找变量的值。
特点:
变量的作用域在代码编写阶段就已经确定,不会受到函数的调用顺序影响
内部作用域可以访问外部作用域中的变量,但外部作用域无法访问内部作用域中的变量
变量的查找是沿着作用域链向上查找的,知道找到第一个匹配的变量

11. bind、call、apply 区别?如何实现一个bind?

在js中,所有的函数再被调用的时候都会默认传入两个参数,一个是this,还有一个是arguments。在默认情况下this都是指当前的调用函数的对象。但是有时候我们需要改变this的指向,我们可以使用如下方法:
使用ES6中箭头函数
函数内部使用_this=this
使用这三种方法
new实例化一点对象
call,apply和bind都是Function原型中的方法,而所有的函数都是Function的实例
call和apply的作用一模一样,区别仅在于传入的参数形式不同。
apply接收两个参数,第一个参数指定了函数体内this对象的指向,第二个参数为一个带下标的集合,这个集合可以为数组,也可以是伪类数组,apply方法把这个集合中的元素作为参数传递给被调用的函数
call传入的参数数量不固定,跟apply相同的是,第一个参数也是一个代表函数体内的this指向,从第二个参数开始往后,每个参数被依次传入函数
bind方法通过传入一个对象,返回一个this绑定了传入对象的新函数,这个函数的this指向除了使用new时会被改变,其他情况下都不会改变
实现bind步骤:
判断调用对象是否为函数,即使是定义在函数的原型上的但是可能出现使用call等方式调用的情况
保存当前函数的引用,获取其余传入参数值
创建一个函数返回
函数内部使用apply来绑定函数调用,需要判断函数作为构造函数的情况,这个时候需要传入当前函数的this给apply调用,其余情况都传入指定的上下文对象
Function.prototype.myBind = function (context){
if(typeof this !== ‘function’){
throw new TypeError(‘Error’)
}
var args = […arguments].slice(1),
fn = this;
return function Fn() {
return fn.apply(
this instanceof Fn ? this :context,
args.concat(…arguments)
)
}
}

12. 说说你对事件循环的理解

事件循环是JavaScript引擎处理异步操作的机制。它是一种用于协调和处理事件、回调函数和其他异步操作的方式。
在JavaScript中,通常使用异步操作来处理耗时的任务,如网络请求、文件读写、定时器等。而为了保证主线程的响应性,避免阻塞,JavaScript引擎采用了事件循环的机制。
事件循环的基本原理如下:
执行同步代码:首先,JavaScript引擎会执行当前线程上的同步任务,这些任务按照代码的顺序依次执行。
处理异步任务:当遇到异步任务(如回调函数、定时器回调等)时,JavaScript引擎会将这些任务交给相应的web API(如DOM API、定时器API等)处理,并立即返回主线程继续执行后续的同步任务
将完成的任务添加到任务队列:当异步任务完成时,它会被添加到任务队列中
事件循环:当主线程的同步任务执行完毕,JavaScript引擎会检查任务队列,如果队列中有任务,就会将其中的任务依次取出,并将其相关的回调函数放入主线程执行。
这个过程会不断重复,从而形成了事件循环。事件循环使得JavaScript能够处理大量的异步操作,而不会阻塞主线程,保证了JavaScript的非阻塞特性。
需要注意的是,事件循环中的任务队列分为宏任务(macrotask)和微任务(microtask)两种类型。宏任务包括 I/O 操作、定时器回调等,而微任务包括 Promise 回调、MutationObserver 回调等。微任务的执行优先级高于宏任务,在每次事件循环的过程中,会先清空微任务队列,然后再执行宏任务。这种机制可以保证微任务的及时执行,提高页面响应速度和用户体验。
总结起来,事件循环是 JavaScript 处理异步操作的核心机制,通过事件循环,JavaScript 引擎可以高效地处理各种异步任务,并保持主线程的响应性。
使用场景:
用户交互事件:当用户在网页上进行点击等操作时,这些事件会被捕捉并加入到事件队列中。事件循环会在适当的时机将这些事件处理,并更新相应的用户界面
网络请求:在进行异步网络请求时,事件循环可以通过回调函数的方式处理请求的响应。当响应返回时,事件循环会调用相应的回调函数来处理返回的数据。
定时器:事件循环可以管理定时器,通过设置定时器来执行一些延时操作。当定时器到期时,事件循环会将相应的回调函数加入事件队列,以便在合适的时机执行。
异步操作:事件循环可以管理定时器,通过设置定时器来执行一些延时操作。当定时器到期时,事件循环会将相应的回调函数加入事件队列,以便在合适的时机执行。
优势:
在于可以实现非阻塞的异步操作,提高程序的性能和响应能力,使得JavaScript可以处理大量的并发操作,而不需要等待每个操作的完成。

13. DOM常见的操作有哪些

14. 说说你对BOM的理解,常见的BOM对象你了解哪些?

15. Javascript本地存储的方式有哪些?区别及应用场景?

16. 什么是防抖和节流?有什么区别?如何实现?

17. 如何通过JS判断一个数组

18. 说说你对作用域链的理解

在JavaScript中的作用域有哪些?
全局作用域,函数作用域,块级作用域,模块作用域
全局作用域:
最外层函数和最外层函数外面定义的变量拥有全局作用域;
所有未定义直接赋值的变量自动声明为全局作用域;
所有window对象的属性拥有全局作用域
全局作用域有很大的弊端,过多的全局作用域变量会污染全局命名空间,容易引起命名冲突
函数作用域:
声明在函数内部的变量,一般那只有固定的代码片段可以访问到;
作用域是分层的,内部作用域可以访问外部作用域,反之不行
块级作用域:
使用ES6中新增的let和const指令可以声明块级作用域,苦自己作用域可以在函数中创建也可以在一个代码块中出创建(由{}包裹的代码片段)
let和const声明的变量不会有变量提升,也不可以重复声明
在循环中比较适合绑定块级作用域,这样就可以把声明的计数器变量限制在循环内部
作用域链:
在当前作用域中查找所需变量,但是该作用域没有这个变量,那这个变量就是自由变量。如果在自己作用域找不到该变量就去父级作用域查找,依次向上级作用域查找,直到访问到window对象就被终止,这一层层的关系就是作用域链。
作用:
保证对执行环境有权访问的所有变量和函数的有序访问,通过作用域链,可以访问到外层环境的变量和函数
本质:
是一个变量对象的指针列表。变量对象是一个包含了执行环境中所有变量和函数的对象。

19. JavaScript原型,原型链 ? 有什么特点?

20. 请解释什么是事件代理

21. 谈谈This对象的理解

this是执行上下文中的一个属性,它指向最后一次调用这个方法的对象。在实际开发中,this的指向可以通过四种调用模式来判断
函数调用模式,当一个函数不是一个对象的属性时,直接作为函数来调用时,this指向全局对象。
方法调用模式,如果一个函数作为一个对象的方法来调用时,this指向这个对象
构造器调用模式,如果一个函数用new调用时,函数执行前会新创建一个对象,this指向这个新创建的对象
apply、call和bind调用模式,这三个方法都可以显示的指定调用函数的this指向
其中 apply方法接收两个参数:一个是 this 绑定的对象,一个是参数数组。call 方法接收的参数,第一个是 this 绑定的对象,后面的其余参数是传入函数执行的参数。也就是说,在使用 call0 方法时,传递给函数的参数必须逐个列举出来。bind 方法通过传入一个对象,返回一个 this 绑定了传入对象的新函数。这个函数的 this 指向除了使用 new 时会被改变,其他情况下都不会改变。

22. new操作符具体干了什么

首先创建了一个新的空对象
设置原型,将对象的原型设置为函数的prototype对象
让函数的this指向这个对象,执行构造函数的代码(为这个新对象添加属性)
判断函数的返回值类型,如果是值类型,防护创建的对象。如果是引用类型,就返回这个引用类型的对象

23. null,undefined 的区别

首先两者都是基本数据类型,这两个基本数据类型分别都只有一个值,就是undefined和null
undefined代表的含义是未定义,null代表的含义是空对象。一般变量声明了但还没有定义的时候会返回undefined,null主要用于赋值给一些可能会返回对象的变量,作为初始化。
undefined在JavaScript中不是一个保留字,这意味着可以使用undefined来作为一个变量名,但是这样的做法是非常危险的,它会影响对undefined值的判断。我们可以通过一些方法获得安全的undefined值,比如说void 0。

24. javascript 代码中的"use strict";是什么意思

use strict 是一种ECMAscript5添加的(严格模式)运行模式,这种模式使得JavaScript在更严格的条件下运行。设立严格模式的目的如下:
消除JavaScript语法的不合理、不严谨之处,减少怪异行为;
消除代码运行的不安全之处,保证代码运行的安全;
提高编译器效率,增加运行速度;
为未来新版本的JavaScript做好铺垫
区别:
禁止使用with语句
禁止this关键字指向全局对象
对象不能有重名的属性

25. 同步和异步的区别

26. 谈一谈箭头函数与普通函数的区别

箭头函数比普通函数更加简洁
箭头函数没有自己的this
箭头函数继承来的this指向永远不会改变
call、apply、bind等方法不能改变箭头函数中this的指向
箭头函数不能作为构造函数使用
箭头函数没有自己的arguments对象,在箭头函数中访问arguments实际上获得到的是它外层函数的arguments
箭头函数没有prototype
箭头函数不能用作Generator函数,不能使用yeild关键字

27. JS 数组和对象的遍历方式,以及几种方式的比较

28. 如何解决跨域问题

29. XML和JSON的区别

30. 谈谈你对webpack的看法

31. webpack的打包原理

32. 如何优化webpack打包速度

33. 说说webpack中常见的Loader?解决了什么问题?

34. 说说webpack中常见的Plugin?解决了什么问题?

35. 说说你对promise的了解

36. async函数是什么,有什么作用

37. 有使用过vue吗?说说你对vue的理解

38. 你对SPA单页面的理解,它的优缺点分别是什么?如何实现SPA应用呢

39. SPA首屏加载速度慢的怎么解决?

40. VUE路由的原理

41. Vue中组件和插件有什么区别?

42. Vue组件之间的通信方式都有哪些

43. 你了解vue的diff算法吗?说说看

44. 为什么需要 Virtual Dom

45. Vue3.0的设计目标是什么?做了哪些优化

46. Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?

47. 说一下Vue数据响应式的原理

48. 说说对 React 的理解?有哪些特性?

49. 说说 Real DOM 和 Virtual DOM 的区别?优缺点?

50. 说说 React 生命周期有哪些不同阶段?每个阶段对应的方法是?

51. 说说 React中的setState执行机制

52. 说说对React中类组件和函数组件的理解?有什么区别?

53. 说说对React Hooks的理解?解决了什么问题?

54. 说说你对Redux的理解?其工作原理?

55. 说说 React 性能优化的手段有哪些

56. vue、react、angular 区别

57. 说说你对 TypeScript 的理解?与 JavaScript 的区别

58. 说说你对 TypeScript 中泛型的理解?应用场景?

59. 说说你对微信小程序的理解?优缺点?

60. 说说你对发布订阅、观察者模式的理解?区别?

61. 项目做过哪些性能优化

62. 描述浏览器的渲染过程,DOM树和渲染树的区别

63. 你认为什么样的前端代码是好的

64. 从浏览器地址栏输入url到显示页面的步骤

65. http 请求报文响应报文的格式

66. Token cookie session 区别

67. CORS跨域的原理

68. 什么是MVVM

69. 说说你对版本管理的理解?常用的版本管理工具有哪些?

70. 说说你对Git的理解?

71. 说说Git常用的命令有哪些

72. 说说 git 发生冲突的场景?如何解决?

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值