问题类型汇总
- ES6:全看
- CSS3:新特性、div盒子居中、清除浮动、动画、canvas、画三角形、定位的种类和区别
- Html:html5新特性、弹性盒子(怪异盒子)、
- Js:各种数据类型的处理方法、原型链、闭包、浅拷贝、深拷贝
- react:hooks、生命周期、组件之间的通信、高阶组件
- 打包工具:webpack
- 其他:https协议、webStorage(localStorage和SessionStorage)和Cookie、跨域
具体问题:
ES6
var、let、const区别?
var定义的变量,没有块的概念,可以跨块访问,不能跨函数访问;let和const都只能猜块级作用域访问,不能跨块或者函数访问。const声明时必需赋值,且不能修改(不赋值,你后面又不能修改,那不是废了)
var存在变量提升
const保证的是变量名指向的地址不变,而不是内容不变,所以const声明的数组,也是可能会被篡改的
使用箭头函数应该注意什么?
- this指向会变成指向父级
- 不能使用
arguments
对象,不能用作构造函数,不能使用yield命令=>不能作为generator
函数
forEach、for in、for of三者的区别?
for in 遍历出来的是key(对象和数组都能遍历),
for of 便利出来的是value(for of只能遍历数组,不能遍历对象)
(Symbol作为属性名,循环时是拿不到的)
rest参数需要注意的地方
- 只能作为函数的最后一个参数
- 函数的length属性,不包括rest参数
Object.is()、==、===的区别
== | === | Object.is() | |
---|---|---|---|
+0、-0 | true | true | false |
NaN,Nan | false | false | true |
undefined,undefined | true | true | true |
null,null | true | true | true |
null,undefined | true | false | false |
null,NaN | false | false | false |
undefined,NaN | false | false | false |
===在==的基础上,认为null和undefined是不相等的,Object.is()在===的基础上,认为+0和-0不相等,但是Nan和Nan想等
JS处理异步函数的方法
回调、事件发布与订阅、Promise、Generator函数、async/await
如何监听数组被写入或者读取?
使用Proxy
ES6新增的特性
- let、const。
var有变量提升、可以跨块访问,不能跨函数访问。let、const没有变量提升,必须先声明再使用,不能跨块访问,也不能跨函数访问 - 箭头函数
箭头函数无需关键字function创建,更简洁;箭头函数没有自己的this、arguments、不能用作构造函数、不能用作generator函数 - 模板字符串
用反引号包裹,再基础字符串的基础上,可以定义多行字符串,可以使用${}
进行字符串的拼接 - 解构赋值
按照一定的语法可以从数组、字符串和对象中取值,然后赋值给变量。对于数组来说,相同位置的值会赋给相同位置的变量。对于对象来说相同键名的值会赋给同名变量。都支持赋默认值
https://www.runoob.com/w3cnote/deconstruction-assignment.html - for of与for in
可以循环数组、set、map、对象、字符串。for of循环出来的是key,for in循环出来的是value - export和import
只是将代码模块化,分成不同文件。然后通过export和import的方式在其他地方使用 - Set数据结构
Set是集合,一如它的数学定义,它内部是没有重复值的。我们可以利用这个属性对数组进行去重,以含有重复值的数组为参数实例化一个Set,得到的结果中将不会包括重复值 - 展开运算符
...
数组可以展开为数组和对象;
对象可以展开为对象;不能展开为数组
Set可以展开为数组,但是如果展开为对象的话,会得到一个空对象。 - Map数据类型
最直观的感受是,从Object的string——值
对,变成了值——值
对 - 修饰器@decorator
修饰器可以在编译阶段执行代码。用于修改类甚至于方法的行为
//修饰器函数1:为类加上静态属性isTestable
//修饰器函数的第一个参数,就是所要修饰的目标类
function testable(target) {
target.isTestable = true;
}
//修饰类的行为。写在类上方,表示修饰器的目标是这整个类
@testable
class MyTestableClass {}
console.log(MyTestableClass.isTestable) // true
解释:
@decorator
class A {}
// 等同于
class A {}
A = decorator(A) || A;
core-decorators.js core-decorators.js是一个第三方模块,提供了几个常见的修饰器,通过它可以更好地理解修饰器
@autobind:使得方法中的this对象,绑定原始对象
@readonly:使得属性或方法不可写
@override:检查子类的方法是否正确覆盖了父类的同名方法,如果不正确会报错
@deprecate (别名@deprecated):在控制台显示一条警告,表示该方法将废除.
https://blog.csdn.net/aaaaapipi/article/details/108040002
class
class就是es5中原型链实现的一个语法糖Promise
三种状态:pending(进行中,初始化)、fulfilled(已成功)和rejected(已失败)
https://blog.csdn.net/qq_34645412/article/details/81170576
function asyncFun3(a){
let p=new Promise(function(resolve,reject){
setTimeout(function(){
console.log("内3")
console.log(a)
resolve("异步,333333333333秒")
},3000)
})
return p
}
asyncFun1().then(function(a){
return asyncFun2(a)
}).then(function(a){
return asyncFun3(a)
})
Symbol
https://www.jianshu.com/p/cad25435f5a4
Symbol 作为属性名,遍历对象的时候,该属性不会出现在for...in、for...of循环中,也不会被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回。
但是,它也不是私有属性,有一个Object.getOwnPropertySymbols()方法,可以获取指定对象的所有 Symbol 属性名。该方法返回一个数组,成员是当前对象的所有用作属性名的 Symbol 值。Proxy监听对象操作
区分变量类型的方法
对于原型链的理解
深拷贝的方法:
共有:展开运算符、JSON转字符串
Object:
Object.assign(obj1,obj2,obj3......)
注意这里克隆的是引用,而该引用指向的内存空间是没有被拷贝的,
Array:[ ].concat(arr1,arr2,arr3......)
各种拷贝方法详解
对象拷贝方法:
let obj={...a}
是深拷贝,但是只拷贝指向。对于属性指向的数组、对象,只拷贝指针,其内容不重新开辟空间
let obj=Object.assign({},a)
跟上面这种方式是一样的
let obj=JSON.parse(JSON.stringify(a))
这个倒是深拷贝了,缺点在于它在转换时会丢失函数类型的属性
自己写工具方法,多层迭代。这个应该是最靠谱的了
import { cloneDeep } from 'loadsh'
loadsh是一个使用工具库,deepClone仅仅是其中的一个方法,还有很多其他方法可用数组深拷贝
JSON,[].concat,slice等
数据类型
String(字符串类型)、Number(数字类型)、Boolean(布尔类型)、Array(数组类型)、Date(日期类型)。
ES6新增的数据类型有:
基本类型:Symbol
复杂类型:Set、Map、WeakSet、WeakMap、TypedArray
ES6中module能否使模块按需加载
不能,因为es6中的module是静态加载的,所以不能用于按需加载。静态加载又叫编译时加载,与运行时加载相反,那么react中import无法使用变量、import之前不能存在语句,也就可以解释为:因为import是在编译的时候加载的,这个时候 程序还没运行,语句也就不会执行,变量也不会被运算和赋值。
https://www.aisoutu.com/a/581405
async\await函数和generator函数相比,有哪些优点
https://www.jianshu.com/p/a0e6b9755129
- generator函数需要调用next()指令来向下执行,async不需要,async有内置的执行器,可以向运行正常函数一样运行就可以了
- 像将于generator的*和yield,async/await的语义化更加明确。async是“异步的简写,await可以视为async wait。
- 适应性更广,yield 命令后面只能是 Thunk 函数或 Promise 对象,而 async 函数的 await 命令后面,可以跟 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)。await是一个表达式,它有返回值
- async返回一个promise对象,可以调用catch和then
字符串模板、DOM模板、模板字符串
es6交换两个变量的值
let a=1
let b=2; //这个分号必须要有,虽然还不太明白原因,但是没有就会报错
[a, b] = [b, a]
console.log(a,b)
模板字符串的好处
- 可以多行,无需使用反斜杠
- 使用${}就能进行拼接,更加简洁优美
arguments和rest参数的区别
- arguments对应的是全部的参数,而rest只对应那些没有形参的参数。
- arguments不是真正的数组,而rest却是数组的实例,所以可以使用数组所有的方法。arguments如果想用数组的地方法,还需要经过一次转换
- auguments有自己特有的属性,如callee
es5与es6继承的区别是什么?
1.ES5的继承实质上是先创建子类的实例对象,然后再将父类的方法添加到this上(Parent.apply(this)).
2.ES6的继承机制完全不同,实质上是先创建父类的实例对象this(所以必须先调用父类的super()方法),然后再用子类的构造函数修改this。
3.ES5的继承时通过原型或构造函数机制来实现。
4.ES6通过class关键字定义类,里面有构造方法,类之间通过extends关键字实现继承。
手写4种继承
- 原型继承
Son.prototype=father;
function Father(){
this.firstName="李";
}
var father=new Father();
Father.prototype.lastName="名";
function Son(){
this.firstName="张";
this.sex="男";
}
// 子类原型继承父类的实例
Son.prototype=father;
var son=new Son();
console.log(son.firstName,son.lastName,son.sex); //张 名 男
核心是子类原型继承父类实例
firstName子类有,直接输出张。lastName自己没有,去原型链上找到并输出名
1.实例既是父类的实例也是子类的实例
2.父类新增原型方法或是原型属性子类都可以访问到。
3.简单易实现。
缺点:
1.无法实现多继承(多继承就是将多个对象和成员交给当前对象);
2.创建子类实例时,无法向父类传参.
- 构造继承
Father.call(this,name,age,sex)
function Father(name,age,sex){
this.name=name;
this.age=age;
this.sex=sex;
}
function Son(name,age,sex,gf){
// call方法第一个值写this指向
Father.call(this,name,age,sex)
this.gf=gf;
}
var son=new Son("李飞",20,"男","张晓丽");
console.log(`${son.name}今年${son.age}岁,性别${son.sex},女朋友叫${son.gf}`);//李飞今年20岁,性别男,女朋友叫张晓丽
核心是把子类用父类的构造函数作为自己的构造函数
Father.call(this,name,age,sex)是调用父类的构造函数,但是使用的是子类的this。通过父类构造函数构造完毕后,子类的name、age、sex等属性已经具备。再在此基础上添加this.gf=gf;去修改父类没有处理的属性即可
特点:
1.只继承了父类的构造函数的属性,没有继承父类原型的属性
2.可以实现多继承(多次使用call)
3.可以向父类传参
4.无法实现构造函数的复用(每次都要从新调用)
5.每个新实例都有父类构造函数的副本。
- 组合继承
//就是构造继承加一句
Son.prototype=new Father();
特点:
1.可以继承父类原型的属性,可以传参,可以复用。
2.每个新实例引入的构造函数是私有的
3.调用了两次父类构造函数(耗内存)
寄生继承
寄生组合继承
es6 class extend继承
CSS3
新特性、div盒子居中、清除浮动、动画、canvas、画三角形、定位的种类和区别、弹性布局
transform 变换:分为2d转换和3d转换
transition 过渡:控制变换的速度
translate 变换的一种:简单位移变化
keyframe{ from to} 也可以是百分比
渐变:线性渐变与径向渐变
用纯css3实现等边三角形
等边三角形
#triangle{
border-style: solid;
width: 0px;
border-width: 173px 100px 0px 100px;
border-color: aqua transparent transparent transparent;
}
30-60°直角三角形
#triangle{
border-style: solid;
width: 0px;
border-width: 173px 100px 0px 0px;
border-color: aqua transparent transparent transparent;
}
div盒子居中的方法
垂直水平都能居中:
-
方法一:margin:auto
关键就在于,子元素设置绝对定位,上下左右一定都要设置为0,然后把margin设置auto就好了
上下都取0,可以实现垂直居中
左右都取0,实现水平居中
.chl_box {
width: 100px;
height: 100px;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
background: #00FFFF;
}
+方法二:知道子元素宽高的情况下
子元素top:50%,margin:-50px(假设子元素高度为100)
- 方法三:父子元素宽高都知道的情况下
子元素margin:50px(假设父元素高-子元素高=100px) -
方法四:弹性布局居中:需要被操作的是父容器
1、flex-direction 用于定义弹性布局的主轴,默认值就是横向从左向右
2、 justify-content 定义主轴上面的对其方式,设为center。(此时默认水平居中)
3、align-items 定义交叉轴上的对齐方式,设为center。(此时默认垂直居中)
.box {
width: 200px;
height: 200px;
border: 1px solid #000000;
display: flex;
justify-content: center;
align-items: center;
}
.chl_box {
width: 100px;
height: 100px;
background: #00FFFF;
}
-
方法五:translate居中 ie9一下浏览器不支持
首先我们让子元素左侧距离父元素左边为父元素的50%,再用translate倒退子元素的50%
translate的作用是转换。转换的锚点是整个div的中心
.box {
width: 200px;
height: 200px;
border: 1px solid #000000;
position: relative;
}
.chl_box {
width: 100px;
height: 100px;
background: #00FFFF;
position: relative;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
+方法六: table-cell居中
这种的话就是将父元素转换成表格单元格显示,然后使用垂直居中实现
.box {
width: 200px;
height: 200px;
border: 1px solid #000000;
display: table-cell;
vertical-align: middle;
}
.chl_box {
width: 100px;
height: 100px;
background: #00FFFF;
margin: 0 auto;
}
-
方法七:不确定宽高居中
这种的原理其实相当于在子元素周围加了一圈边框,致使子元素只能有这么宽和这么高,是没有办法去改变子元素宽高的。例如这里left的值一改变成5%,整个子元素的宽也会改变
子元素要设置为绝对定位
.box {
width: 200px;
height: 200px;
border: 1px solid #000000;
position: relative;
}
.chl_box {
background: #00FFFF;
position: absolute;
left: 25%;
right: 25%;
top: 25%;
bottom: 25%;
}
仅能水平居中
+方法一:子元素relative定位是,margin:auto