前端面试题汇总(持续更新)-程序员宅基地

技术标签: css  前端  html  javascript  

一、CSS

1、说一下CSS的盒模型

在HTML页面中的所有元素都可以看成是一个盒子
盒子的组成:内容(content)、内边距(padding)、边框(border)、外边距(margin)
盒模型的类型:
标准盒模型:
margin + border + padding + content
IE盒模型:
margin + content( border + padding)
控制盒模型的模式:
box-sizing:content-box(默认值,标准盒模型) 、border-box(IE盒模型)

2、CSS选择器的优先级

CSS的特性:继承性、层叠性、优先级
优先级:写CSS样式的时候,会给同一个元素添加多个样式,此时谁的权重高就显示谁
标签选择器、类选择器/伪类选择器/属性选择器、全局选择器、行内样式、id选择器、!important
优先级:
!important > 行内样式 > id > 类选择器/伪类选择器/属性选择器 > 标签选择器 > 全局选择器

3、隐藏元素的方法有哪些

display: none;
元素在页面上消失,不占据空间
opacity: 0;
设置元素的透明度为0,元素不可见,占据空间位置
visibility: hidden;
让元素消失,占据空间位置,一种不可见的状态
position: absolute; 从当前位置踢出去
clip-path: 待隐藏的元素剪切掉

4、px和rem的区别是什么

px: 是像素,显示器上给我们呈现画面的像素,每个像素的大小是一样的,绝对单位长度
rem: rem 是所有 DOM 节点对于根节点 html 的相对值。
1、浏览器默认的字号是16px,因此如果没有设置根节点 html 的字号,这将会是一个默认基数
2、rem 与 px 的换算为 px = rem * 设置的根节点字号。

		1.设置了根节点 html 字体大小
			html{
    font-size:12px}
			div{
    width:4rem;}
			//div 的宽度换算为 px 为 4rem*12px = 48px
		2.没有设置根节点 html 字体大小
			div{
    width:4rem;}
			//div 的宽度换算为 px 为 4rem*16px = 64px
			注意,html 字体大小最小为 12px;如果设置为10px,则换算后的 px 依然按照 12px 计算
		3.设置根节点 html 字体大小小于12px
			html{
    font-size:10px}
			div{
    width:4rem;}
			//div 的宽度换算为 px 为 4rem*12px = 48px

5、重绘和重排有什么区别

重绘:重新绘制;计算好盒模型的位置大小和其他一些属性之后,浏览器就会根据每个盒模型的特性进行绘制
重排(回流):重新排列;布局引擎会根据所有的样式计算出盒模型在页面上的位置和大小
浏览器的渲染机制:
对DOM的大小、位置进行修改后,浏览器需要重新计算元素的这些几何属性,就叫重排
对DOM的样式进行修改,比如color和background-color,浏览器不需要重新计算几何属性的时候,直接绘制了该元素的新样式,那么这里就只触发了重绘

6、让一个元素水平垂直居中的方式有哪些

1、定位 + margin

<div class="father">
    <div class="son"></div>
</div>
<style>
*{
    
    margin: 0;
    padding: 0;
}
.father{
    
    width: 400px;
    height: 400px;
    border: 1px solid;
    // 父元素要加上相对定位
    position: relative;
}
.son{
    
    //子元素要加上绝对定位
    position:absolute;
    width:200px;
    heihgt:200px;
    background-color:red;
    top:0;
    right:0;
    bottom:0;
    left:0;
    margin: auto;
}
</style>
2、定位 + transform
<div class="father">
    <div class="son"></div>
</div>
<style>
*{
    
    margin: 0;
    padding: 0;
}
.father{
    
    width: 400px;
    height: 400px;
    border: 1px solid;
    // 父元素要加上相对定位
    position: relative;
}
.son{
    
    //子元素要加上绝对定位
    position:absolute;
    width:200px;
    heihgt:200px;
    background-color:blue;
    top:50%;
    left:50%;
    transform: translate(-50%,-50%)
}
</style>
3、flex布局
<div class="father">
    <div class="son"></div>
</div>
<style>
*{
    
    margin: 0;
    padding: 0;
}
.father{
    
    display:flex;
    justify-content:center;
    align-items:center
    width: 400px;
    height: 400px;
    border: 1px solid;
}
.son{
    
    width:200px;
    height:200px;
    background-color:blue;
}
</style>

4、grid布局

设置父元素为grid容器,然后设置单元格内容的水平垂直位置即可实现水平垂直居中(因为没有设置行和列所以整个wrap元素为一个单元格)
    .wrap{
    
        width: 200px;
        height: 200px;
        background: aqua;
        display: grid;  // 设置grid容器
        justify-items:center;
        align-items: center ;

    }
    .center{
    
        display: inline-block;
        width: 50px;
        height: 50px;
        background: red;

    }

    <div class="wrap">
        <div class="center">

        </div>
    </div>

5、table布局

display:table-cell属性的作用是让标签元素以表格单元格的形式呈现,类似于td标签,
vertical:middle设置元素垂直居中,
text-align:center设置水平居中
    .wrap{
    
        width: 200px;
        height: 200px;
        background: aqua;
        display: table-cell;
        vertical-align: middle;
        text-align: center;
    }
    .center{
    
        display: inline-block; // 如果是内联元素则不需要设置
        width: 50px;
        height: 50px;
        background: red;
    }
    
    <div class="wrap">
        <div class="center">

        </div>
    </div>

7、CSS的属性哪些可以继承?哪些不可以继承

CSS三大特性:继承、层叠、优先级
子元素可以继承父类元素的样式就叫继承
可以继承的:
1、字体的一些属性可以继承;font
2、文本的一些属性;line-height
3、元素的可见性;visibility:hidden
4、表格布局的属性;border-spacing
5、列表的属性;list-style
6、页面样式属性;page
7、声音的样式属性;
8、有没有用过预处理器
预处理器语言增加了变量、函数、混入等强大的功能
两种预处理器:SASS LESS

二、Javascript

1、JS有哪三部分组成

ECMAScript + 文档对象模型(DOM) + 浏览器对象模型(BOM)
ECMAScript:JS核心内容,描述了语言的基础语法,比如var,for循环,数据类型(字符串、数组、布尔值等等)
文档对象模型(DOM):DOM把整个HTML页面规划为元素构成的文档,
浏览器对象模型(BOM):对浏览器窗口进行访问和操作

2、JS有哪些内置对象

String、Boolean、Number、Array、Object、Function、Math、Date、RegExp、JSON…
常用的内置对象:Math : abs() sqrt() max() min()
var num = new Number(15);
Math.random()
生成一个0~1之间的随机小数
如果要生成0-54之间的随机整数:Math.floor(Math.random() * 54)
Math.floor(num)向上取整
Math.ceil(num)向下取整
Math.pow(x, y)求X的Y次方
Math.sqrt(x)求X的开平方
Math.trunc() - - 用于去除一个数的小数部分,返回整数部分。
Math.sign()方法判断一个数是正数、负数、零或者NaN。对于非数值,会将其转换 为数值。他会返回五种值:
参数为正数,返回+1;
参数为负数,返回-1;
参数为 0,返回0;
参数为-0,返回-0;
其他值,返回NaN。
Date: new Date()、 getYear()
let date = new Date(); //系统当前时间
let date = new Date(value); //value是距1970-1-1 0:0:0(UTC)依赖的毫秒值
let date = new Date(dateString); //dateString表示日期时间字符串“yyyy-MM-ddThh:mm:ss”
let date = new Date(year,month[, hour[, minutes[, seconds[, milliseconds]]]]);; //传递日期时间数字。month合理取值为0~11;
获取时间:
getFullYear() //获取四位年份
getMonth() //获取月份,返回值是0~11
getDate() //获取日期
getDay() //获取星期,返回值是0~6
getHours() //获取小时
getMinutes() //获取分钟
getSeconds() //获取秒
getMilliseconds() //获取毫秒
getTime() //获取距 1970-1-1 0:0:0 以来的毫秒值
设置时间:
setFullYear() //设置四位年份
setMonth() //设置月份,传值是0~11
setDate() //设置日期
setHours() //设置小时
setMinutes() //设置分钟
setSeconds() //设置秒
setMilliseconds() //设置毫秒
setTime() //设置距1970-1-1 0:0:0多少毫秒是什么时间(取负值的话就是1970年之前)
时间转换:
Date.parse() //解析,将日期时间字符串转换为表示时间的毫秒值
toString() //将日期时间字符串转换为字符串
toUTCString() //将日期时间转换为世界标准时间的字符串
valueOf() //返回Date对象的原始值。与getTime()一致。
tolSOString() //将日期时间转为格式为 YYYY-MM-DDTHH:mm:ss.sssZ 的字符串
toJSON() //返回 Date 对象的字符串形式。
获取日期时间毫秒值:
new Date.getTime()
Date.parse()
new Date().valueOf()
+new Date() //隐式类型转换的方法
Date.now() //ES5的方法
Array: 第三题有答案
String:
charAt(index) - - 获取index位置处的字符
charCodeAt(index) - - 获取index位置处字符的unicode编码
String.fromCharCode(code) - - 将unicode编码转换为对应的字符串
concat() - - 字符串连接
indexOf(sub) - - 查找符合条件的第一个字符串所在下标
lastIndexOf(sub) - - 查找符合条件的第一个字符串所在下标(从后往前查)
slice(start, end) - - 截取子字符串
subString(start, end) - - 截取子字符串
split() - - 切割字符串不传值的话就是直接把字符串用数组包起来,传值就是以值为分割
replace(oldString, newString) - - 替换
toUpperCase() - - 转换为大写
toLowerCase() - - 转换为小写
trim() - - 去掉前后空白
trimStart() - - 去除头部空白
trimLeft() - - 去除头部空白【trimStart的别名】
trimEnd() - - 去除尾部空白
trimRight() - - 去除尾部空白【trimEnd的别名】
replace(/^\s+|\s+$/g, ‘’) - - 去掉前后空白的兼容写法
includes(sub) - - 返回布尔值,表示是否找到了参数字符串。
startsWith(sub) - - 返回布尔值,表示参数字符串是否在原字符串的头部。
endsWith(sub) - - 返回布尔值,表示参数字符串是否在原字符串的尾部

3、操作数组的方法有哪些

push()
pop()
sort()
splice()
unshift()
shift()
reverse()
concat()
join()
map()
filter()
every()
some()
reduce()
isArray()
findIndex()

哪些方法会改变原数组:
push() pop() unshift() shift() sort() reverse() splice()

4、JS对数据类的检测方法有哪些

typeof()
对于基本数据类型没问题,遇到引用数据类型就不管用

console.log(typeof 666)//number
console.log(typeof [1,2,3])//object

instanceof()
只能判断引用数据类型,不能判断基本类型

console.log([] instanceof Array)//true
console.log('abc' instanceof String)//false

constructor()
几乎可以判断基本数据类型和引用数据类型;

console.log(('abc').constructor === String)//true
如果声明了一个构造函数并把他的原型指向了Array的时候,这时候就判断不出来了
let arr = []
Array.prototype.constructor = 'a'  //更改constructor
console.log(arr.constructor === Array)//false

Object.prototype.toString.call()最完美的解决方案

var opt = Object.prototype.toString
console.log(opt.call(2))//[object Number]
console.log(opt.call(true))[object Boolean]
console.log(opt.call('aaa'))[object String]
console.log(opt.call([]))[object Array]
console.log(opt.call({
    }))[object Object]

5、说一下闭包,闭包有什么特点

什么是闭包:函数嵌套函数,内部函数被外部函数返回并保存下来时,就会产生闭包
特点:可以重复利用变量,并且这个变量不会污染全局的一种机制;这个变量一直保存在内存中,不会被垃圾回收机制回收
缺点:闭包较多的时候会消耗内存,导致页面的性能下降,在IE浏览器中才会导致内存泄漏
使用场景:防抖、节流、函数嵌套函数避免全局污染的时候

function fn(a){
    
    return function(){
    
        console.log(a)    
    }
}
var fo = fn('abcd')
fo()

6、前端的内存泄漏怎么理解

JS里已经分配内存地址的对象,但是由于长时间没有释放或者没办法清除,造成长期占用内存的现象,会让内存资源大幅防雷,最终导致运行速度慢,甚至崩溃的情况。(内存泄漏是指在程序运行时,分配的内存没有被正确释放,导致内存空间的浪费,最终可能会导致程序崩溃或运行缓慢。)
垃圾回收机制
会导致内存泄漏的因素:一些为声明直接赋值的变量;一些未清空的定时器;过度的闭包;一些引用元素没有被清除

7、事件委托是什么

又叫事件代理。原理:利用事件冒泡的机制来实现,也就是说把子元素的事件绑定到了父元素的身上。如果子元素阻止了事件冒泡,那么委托也就不成立。
阻止事件冒泡:event.stoPropagation()
addEventLisenter(‘click’,函数名,true/false) 默认是false(事件冒泡),true(事件捕获)
好处:提高性能,减少事件的绑定;减少内存的占用

8、基本数据类型和引用数据类型的区别

基本数据类型:String Numebr Boolean undefined null
引用数据类型(复杂数据类型):Object Array function 、正则、日期对象
区别:
基本数据类型保存在栈内存中,保存的是一个具体的值;
引用数据类型保存在堆内存中,保存的是一个地址,(声明一个引用类型的变量的时候保存的是引用类型数据的地址。)eg:假如声明两个引用类型同时指向一个地址的时候,修改其中一个那么另外一个也会改变

9、说一下原型链

原型:一个普通对象,它是为构造函数的实例共享属性和方法,所有实例中引用的原型都是同一个对象
使用prototype可以把方法挂在原型上,内存只保存一份
__proto__可以理解为指针,实例对象()p1,p2)中的属性,指向了构造函数(Person)的原型(prototype)
原型链:一个实例对象在调用属性和方法的时候依次从实例本身到构造函数原型再到原型的原型上去查找的过程称为原型链

<script>
function Person(){
    
    this.say = function(){
    
        console.log('sing')    
    }
}
Person.prototype.look = function(){
    
    conole.log('look')
}
// 两个实例对象
var p1 = new Person()
var p2 = new Person()
p1.say()//sing
p2.say()//sing
p1.look()//look
p2.look()//look
console.log(p1.__proto__ === Person.prototype)//true
</script>

10、new操作符具体做了什么

<script>
function newFun(Fun,...args){
    
1、先创建空对象
    let newObj = {
    }
2、把空对象和构造函数通过原型链进行链接
    newObj.__proto__ = Fun.prototype
3、把构造函数的this指针绑定到新的空对象身上
    const result = Fun.apply(newObj,args)
4、根据构建的函数返回的类型判断,如果是值类型则返回对象,如果是引用类型,就要返回引用类型
    return result instanceof Object ? result : newObj
}
eg:
function Person(name){
    
    this.name = name
}
Person.prototype.say = function(){
    
    console.log('123456')
}
const p1 = newFun(Person,'zhangsan')
p1.say()//123456
console.log(p1)//Person{name:'zhangsan'}
</script>

11、JS是如何实现继承的

1、通过原型链
特点:继承父类原型上的属性和方法。
缺点:创建子类实例时,不能向父类构造函数中传参数,无法实现多继承

//父类
function Person(name) {
    
     this.name = name;
      this.sleep = function(){
    
        console.log(this.name + '正在睡觉')
   }
}
Person.prototype.change = "123木头人"
Person.prototype.sayHi = function () {
    
     console.log("您好啊!");
};
//子类
function Child(age) {
    
     this.age = age
}
Child.prototype = new Person()
Child.prototype.constructor = Child
let child = new Child(10)
console.dir(child)

2、通过借用构造函数继承
特点:解决了子类构造函数向父类构造函数中传递参数,可以实现多继承(call或者apply多个父类)
缺点:方法都在构造函数中定义,无法复用,不能继承原型上的属性和方法

//父类
function Person(name) {
    
     this.name = name;
      this.sleep = function(){
    
        console.log(this.name + '正在睡觉')
   }
}
Person.prototype.change = "123木头人"
Person.prototype.sayHi = function () {
    
     console.log("您好啊!");
};
//子类
function Child(name,age) {
    
    Person.call(this, name) 
 // Person.apply(this, [name]) //=> apply后面的参数是个数组.
    this.age = age;
}
let child = new Child("校长",10)
console.dir(child)

3、组合式继承
特点:把1和2的方法相结合,函数可以复用,可以继承属性和方法,并且可以继承原型的属性和方法
缺点:会挂载两次父类的属性和方法(有两个name和sleep),产生小bug,

//父类
function Person(name) {
    
     this.name = name;
      this.sleep = function(){
    
        console.log(this.name + '正在睡觉')
   }
}
Person.prototype.change = "123木头人"
Person.prototype.sayHi = function () {
    
     console.log("您好啊!");
};
//子类
function Child(name,age) {
    
    Person.call(this, name) 
 // Person.apply(this, [name]) //=> apply后面的参数是个数组.
    this.age = age;
}
Child.prototype = new Person()
Child.prototype.constructor = Child
let child = new Child("校长",10)
console.dir(child)

4、ES6的class类继承

//class 相当于es5中构造函数
//class中定义方法时,前后不能加function,全部定义在class的protopyte属性中
//class中定义的所有方法是不可枚举的
//class中只能定义方法,不能定义对象,变量等
//class和方法内默认都是严格模式
//es5中constructor为隐式属性
class People {
    
    constructor(name, age) {
    
        this.name = name;
        this.age = age;
    }
    sleep() {
    
        console.log(`${
      this.name} ${
      this.age} 正在睡觉`)
    }
}
//继承父类
class Child extends People {
    
    constructor(name, age) {
    
        //继承父类属性
        super(name, age);
    }
    sleep() {
    
        console.log(this);
        //继承父类方法
        super.sleep()
    }
} 
let child = new Child('小红',18); 
console.log(child);
child.sleep();    //小红 18 正在睡觉
总结:ES5继承和ES6继承的区别
ES5的继承实质上是先创建子类的实例对象,然后再将父类的方法添加到this上(Parent.call(this).
ES6的继承有所不同,实质上是先创建父类的实例对象this,然后再用子类的构造函数修改this。因为子类没有自己的this对象,所以必须先调用父类的super()方法,否则新建实例报错。

12、JS的设计原理是什么?

JS引擎、运行上下文、调用栈、事件循环、回调

13、JS中关于this指向的问题

1、全局对象中的this指向:指向的是window
2、全局作用域或者普通函数中的this:指向的是全局window
3、this永远指向最后调用他的那个对象(在不是箭头函数的情况下)
4、new关键词改变了this的指向
5、apply、call、bind可以改变this指向,不是箭头函数
6、箭头函数中的this:他的指向在定义的时候就已经确定了,箭头函数它没有this,看外层是否有函数,有就是外层函数的this,没有就是window
7、匿名函数中的this:永远指向了window,匿名函数的执行环境具有全局性,因此this指向window

14、script标签里的async和defer有什么区别?

当没有async和defer时候:浏览器会立刻加载并执行指定的脚本
有async:加载和渲染后面元素的过程将和script的加载和执行并行进行(异步)
有defer:加载和渲染后面元素的过程将和script的加载并行进行,但是他的执行事件要等所有元素解析完成之后才会执行

15、setTimeout最小执行时间是多少?

HTML5规定的内容:
setTimeout最小执行时间是4ms
setInterval最小执行时间是10ms

16、ES6和ES5有什么区别

JS的组成:ECMAScript BOM DOM
ES5: 全称ECMAScript5,2009年ECMAScript第五次修订,ECMSScript2009
ES6:全程ECMAScript6,2015年ECMAScript第六次修订,也成为ECMAScript2015,JS的下一个版本标准,解决ES5的不足

17、ES6的新特性有哪些

1、新增块级作用域:(let const)
let const :
不存在变量提升
存在暂时性死区的问题
多了块级作用域的内容
不能在同一个作用域内重复声明
2、新增定义类的语法糖(class)
3、新增了一种基本数据类型(symbol:独一无二的值)
4、新增解构赋值
从数组或者对象中取值,然后给变量赋值的过程叫解构赋值。
5、新增了函数参数的默认值
6、给数组新增了API
7、对象和数组新增了扩展运算符
8、promise(异步编程的一种方案,主要解决异步的计算)

1、解决回调地狱的问题
	2、自身有all ,reject,resolved,race方法
	3、原型上才有then或者catch
	4、把异步操作队列化
	5、三种状态:pending(初始状态)、fulfilled(操作成功)、rejected(操作失败)
	6、状态是pending --> fulfilled(pending) --> rejected;一旦发生,状态就会凝固,不会再变
	asyncawait:同步代码做异步的操作,两者必须搭配使用
	async表明函数内有异步操作,调用函数会返回promise
	await是组成async的表达式,结果是取决于它等待的内容,如果是promise那就是	promise的结果,如果是普通函数就进行链式调用
	await后的promise如果是reject状态,那么整个async函数都会中断,后面代码不执行

9、新增了模块化(import,export)
10、新增了set和map数据结构
set就是不重复
map的key的类型不受限制
11、新增了generator
12、新增了箭头函数

箭头函数与普通函数有什么区别:
1、不能作为构造函数使用,不能用new关键字,箭头函数没有原型
2、箭头函数没有arguments
3、箭头函数不能用call,apply,bind去改变this指向
4this指向外层第一个函数的this

18、call,apply,bind三者有什么区别

都是改变this指向和函数的调用,call和apply的功能类似,只是传参的方法不同而已
call方法:传的是一个参数列表
apply:传递的是一个数组
bind:传参后不会立刻执行,会返回一个改变了this指向的函数,这个函数还是可以传参的,bind()()
call方法的性能要比apply好一些,所以call用更多一点

19、用递归的时候有没有遇到什么问题

如果一个函数内可以调用函数本身,这个就是递归函数。(函数内部调用自己)
特别注意:写递归必须要有退出条件return

20、如何实现一个深拷贝?

深拷贝就是完全拷贝一份新的对象,会在堆内存中开辟新的空间,拷贝的对象被修改后,原对象不受影响。
主要针对的是引用数据类型
方法:
1、扩展运算符
2、JSON.parse(JSON.stringify())
3、利用递归函数实现
1、扩展运算符

<script>
        let obj = {
    
            name: '张三',
            age: 18        
        }
        let obj1 = {
    ...obj}
        obj1.name = '王五'
        console.log(obj)//{name:'张三',age:18}
        console.log(obj1)//{name:'王五',age:18}
        缺点:这个方法只能实现第一层,当有多层的时候还是浅拷贝

2、JSON.parse(JSON.stringify())

let obj = {
    
            name: '张三',
            age: 18,
            say(){
    
                console.log('say hello')            
            }      
        }
        let obj1 = JSON.parse(JSON.stringify(obj))
        obj1.name = '王五'
        console.log(obj)//{name:'张三',age:18,say:f}
        console.log(obj1)//{name:'王五',age:18}
        缺点:该方法并不会拷贝内部函数

3、利用递归函数实现

 let origin = {
    
            name: '张三',
            age: 18,
            say(){
    
                console.log('say hello')            
            },
            arr:[[1,2],3,4,5]  
        }
        function exten(origin,deep){
    
            let obj = {
    }
            if(origin instanceof Array){
    
                obj = []            
            }        
            for(let key in origin){
    
                let value = origin[key]
                obj[key] = (!!deep && typeof value === 'object' && value !== null) ? exten(value,deep) : value     
            }
            return obj
        }
        const oo = exten(origin,true)
        oo.arr[0].push(888)
        console.log(origin)//{age:18,arr:[[1,2],3,4],name:'张三',say:f}
        console.log(oo)//{age:18,arr:[[1,2,888],3,4],name:'张三',say:f}
    <script>

21、说一下事件循环?

JS是一个单线程的脚本语言
主线程、执行栈、任务队列、宏任务、微任务
主线程先执行同步任务,然后才去执行任务队列里的任务,如果在执行宏任务之前有微任务,那么要先执行微任务。全部执行完之后等待主线程的调用,调用完之后再去任务队列中查看是否有异步任务,这样一个循环往复的过程就是事件循环。

22、ajax是什么?怎么实现的

ajax是创建交互式网页应用的网页开发技术
在不重新加载整个网页的前提下,与服务器交换数据并更新部分内容
原理:通过XmlHttpRequest对象向服务器发送异步请求,然后从服务器拿到数据,最后通过JS操作DOM的形式更新页面
1、创建XmlHttpRequest对象 简称为xmh
2、通过xmh对象里的open()方法和服务器建立链接
3、构建请求所需的数据,并通过xmh对象的send()方法发送给服务器
4、通过xmh对象的onreadystate 里的change事件来监听服务器和你的通信状态
5、接收并处理服务器响应的数据结果
6、把处理的数据更新到HTML页面上

23、get和post有什么区别?

1、get一般是获取数据,post一般是提交数据
2、get参数会放在url上,所以安全性比较差,post是放在body中
3、get请求刷新服务器或退回是没有影响的,post请求退回时会重新提交数据
4、get请求是会被缓存,post请求不会被缓存
5、get请求会被保存在浏览器历史记录中,post不会
6、get请求只能进行url编码,post请求支持很多种(文件,表单。。。)
7、底层原理(面试的时候不会就不用提,要不然就尴尬了)

24、promise的内部原理是什么?他的优缺点是什么?

Promise是一个对象,封装了一个异步操作并且还可以获取成功或者失败的结果
Promise主要是解决回调地狱的问题,之前如果异步任务比较多,同时他们之间有相互依赖的关系,就只能使用回调函数处理,这样就容易形成回调地狱,代码的可读性差,可维护性也很差。
Promise有三种状态:pending初始状态、 fulfilled成功状态、 rejected失败状态
状态改变只会有两种情况,1、penging–>fulfilled
2、pending–>rejected
缺点:1、我们无法取消promise,一旦创建会立即执行,不能中途取消
2、如果不设置回调,promise内部抛出的错误就无法反馈到外面
3、若当前处于pending状态时,无法得知目前在哪个阶段。
原理:
构造一个Promise实例,实例需要传递函数的参数,这个函数有两个形参,分别都是函数类型,一个是resolve一个是reject;
Promise身上还有then方法,这个方法就是来指定状态改变时的确定操作,resolve是执行第一个函数,reject是执行第二个函数

25、promise和async await的区别是什么?

1、两个都是处理异步请求的方式
2、Promise是ES6的语法,async是ES7的语法
3、async await是基于Promise实现的,他和Promise都是非阻塞性的
优缺点:
1、Promise是返回对象我们要用then 和 catch方法去处理和捕获异常,并且书写方式是链式,容易造成代码重叠,不好维护,async await是通过try catch进行捕获异常
2、async await最大的优点就是能让代码看起来同步一样,只要遇到await就会立刻返回结果,然后在执行后面的操作,Promise是通过.then()的方式返回,会出现请求还没返回,就执行了后面的操作。

26、浏览器的存储方式有哪些?

1、cookies
H5标准前的本地存储方式
优点:兼容性好,请求头自带cookie
缺点:存储量小,资源浪费,使用麻烦(需要进行封装)
2、localstorage
H5加入的以键值对为标准的方式
优点:操作方便,永久存储,兼容性较好
缺点:保存值的类型被限定,浏览器在隐私模式下不可读取,不能被爬虫
3、sessionstorage
当前页面关闭后就会立刻清理,会话级别的存储方式
4、indexedDB
H5标准的存储方式

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_44740072/article/details/131464545

智能推荐

class和struct的区别-程序员宅基地

文章浏览阅读101次。4.class可以有⽆参的构造函数,struct不可以,必须是有参的构造函数,⽽且在有参的构造函数必须初始。2.Struct适⽤于作为经常使⽤的⼀些数据组合成的新类型,表示诸如点、矩形等主要⽤来存储数据的轻量。1.Class⽐较适合⼤的和复杂的数据,表现抽象和多级别的对象层次时。2.class允许继承、被继承,struct不允许,只能继承接⼝。3.Struct有性能优势,Class有⾯向对象的扩展优势。3.class可以初始化变量,struct不可以。1.class是引⽤类型,struct是值类型。

android使用json后闪退,应用闪退问题:从json信息的解析开始就会闪退-程序员宅基地

文章浏览阅读586次。想实现的功能是点击顶部按钮之后按关键字进行搜索,已经可以从服务器收到反馈的json信息,但从json信息的解析开始就会闪退,加载listview也不知道行不行public abstract class loadlistview{public ListView plv;public String js;public int listlength;public int listvisit;public..._rton转json为什么会闪退

如何使用wordnet词典,得到英文句子的同义句_get_synonyms wordnet-程序员宅基地

文章浏览阅读219次。如何使用wordnet词典,得到英文句子的同义句_get_synonyms wordnet

系统项目报表导出功能开发_积木报表 多线程-程序员宅基地

文章浏览阅读521次。系统项目报表导出 导出任务队列表 + 定时扫描 + 多线程_积木报表 多线程

ajax 如何从服务器上获取数据?_ajax 获取http数据-程序员宅基地

文章浏览阅读1.1k次,点赞9次,收藏9次。使用AJAX技术的好处之一是它能够提供更好的用户体验,因为它允许在不重新加载整个页面的情况下更新网页的某一部分。另外,AJAX还使得开发人员能够创建更复杂、更动态的Web应用程序,因为它们可以在后台与服务器进行通信,而不需要打断用户的浏览体验。在Web开发中,AJAX(Asynchronous JavaScript and XML)是一种常用的技术,用于在不重新加载整个页面的情况下,从服务器获取数据并更新网页的某一部分。使用AJAX,你可以创建异步请求,从而提供更快的响应和更好的用户体验。_ajax 获取http数据

Linux图形终端与字符终端-程序员宅基地

文章浏览阅读2.8k次。登录退出、修改密码、关机重启_字符终端

随便推点

Python与Arduino绘制超声波雷达扫描_超声波扫描建模 python库-程序员宅基地

文章浏览阅读3.8k次,点赞3次,收藏51次。前段时间看到一位发烧友制作的超声波雷达扫描神器,用到了Arduino和Processing,可惜啊,我不会Processing更看不懂人家的程序,咋办呢?嘿嘿,所以我就换了个思路解决,因为我会一点Python啊,那就动手吧!在做这个案例之前先要搞明白一个问题:怎么将Arduino通过超声波检测到的距离反馈到Python端?这个嘛,我首先想到了串行通信接口。没错!就是串口。只要Arduino将数据发送给COM口,然后Python能从COM口读取到这个数据就可以啦!我先写了一个测试程序试了一下,OK!搞定_超声波扫描建模 python库

凯撒加密方法介绍及实例说明-程序员宅基地

文章浏览阅读4.2k次。端—端加密指信息由发送端自动加密,并且由TCP/IP进行数据包封装,然后作为不可阅读和不可识别的数据穿过互联网,当这些信息到达目的地,将被自动重组、解密,而成为可读的数据。不可逆加密算法的特征是加密过程中不需要使用密钥,输入明文后由系统直接经过加密算法处理成密文,这种加密后的数据是无法被解密的,只有重新输入明文,并再次经过同样不可逆的加密算法处理,得到相同的加密密文并被系统重新识别后,才能真正解密。2.使用时,加密者查找明文字母表中需要加密的消息中的每一个字母所在位置,并且写下密文字母表中对应的字母。_凯撒加密

工控协议--cip--协议解析基本记录_cip协议embedded_service_error-程序员宅基地

文章浏览阅读5.7k次。CIP报文解析常用到的几个字段:普通类型服务类型:[0x00], CIP对象:[0x02 Message Router], ioi segments:[XX]PCCC(带cmd和func)服务类型:[0x00], CIP对象:[0x02 Message Router], cmd:[0x101], fnc:[0x101]..._cip协议embedded_service_error

如何在vs2019及以后版本(如vs2022)上添加 添加ActiveX控件中的MFC类_vs添加mfc库-程序员宅基地

文章浏览阅读2.4k次,点赞9次,收藏13次。有时候我们在MFC项目开发过程中,需要用到一些微软已经提供的功能,如VC++使用EXCEL功能,这时候我们就能直接通过VS2019到如EXCEL.EXE方式,生成对应的OLE头文件,然后直接使用功能,那么,我们上篇文章中介绍了vs2017及以前的版本如何来添加。但由于微软某些方面考虑,这种方式已被放弃。从上图中可以看出,这一功能,在从vs2017版本15.9开始,后续版本已经删除了此功能。那么我们如果仍需要此功能,我们如何在新版本中添加呢。_vs添加mfc库

frame_size (1536) was not respected for a non-last frame_frame_size (1024) was not respected for a non-last-程序员宅基地

文章浏览阅读785次。用ac3编码,执行编码函数时报错入如下:[ac3 @ 0x7fed7800f200] frame_size (1536) was not respected for anon-last frame (avcodec_encode_audio2)用ac3编码时每次送入编码器的音频采样数应该是1536个采样,不然就会报上述错误。这个数字并非刻意固定,而是跟ac3内部的编码算法原理相关。全网找不到,国内音视频之路还有很长的路,音视频人一起加油吧~......_frame_size (1024) was not respected for a non-last frame

Android移动应用开发入门_在安卓移动应用开发中要在活动类文件中声迷你一个复选框变量-程序员宅基地

文章浏览阅读230次,点赞2次,收藏2次。创建Android应用程序一个项目里面可以有很多模块,而每一个模块就对应了一个应用程序。项目结构介绍_在安卓移动应用开发中要在活动类文件中声迷你一个复选框变量

推荐文章

热门文章

相关标签