HTML
1:如何理解HTML语义化
- 让人更容易读懂(增加代码可读性)
- 让搜索引擎更容易读懂(SEO)
2:块状元素&内联元素?
display:block/table;有div h1 h2 table ul ol p等
display:inline-block/inline;有span img input button 等
CSS
1:请问div1的offsetWidth是多大?
#div1{
width:100px;
padding:10px;
border:1px solid #ccc;
margin:10px;
}
<div id="div1"></div>
offsetWidth=(内容宽度+内边距+边框),无外边距。
所以答案为122px
1-1:如果让offsetWidth等于100px?
答:加box-sizing:border-box
2:AAA和BBB之间的距离是多少?(margin纵向重叠问题)
p{
font-size:16px;
line-height:1;
margin-top:10px;
margin-bottom:15px;
}
<p>AAA</p>
<p></p>
<p></p>
<p></p>
<p>BBB</p>
说明:相邻元素的margin-top和margin-bottom会重叠
空白内容的<p></p>也会重叠
答案:15px
3:margin负值问题?
- margin-top和margin-left负值,元素向上,向左移动
- margin-right负值,右侧元素左移,自身不受影响
- margin-bottom负值,下方元素上移,自身不受影响
4-1:BFC理解与应用
- block format context,块级格式化上下文
- 一块独立渲染区域,内部元素的渲染不会影响边界以外的元素
4-2:形成BFC的常见条件
- float不是none
- position是absolute或fixed
- overflow不是visible
- display是flex inline-block等
4-3:BFC常见应用
清除浮动
5:float布局
5-1:圣杯布局和双飞翼布局的目的?
- 三栏布局,中间一栏最先加载和渲染(内容最重要)
- 两侧内容固定,中间内容随着宽度自适应
- 一般用于PC网页
5-2:圣杯布局和双飞翼布局的技术总结
- 使用float布局
- 两侧使用margin负值,以便和中间内容横向重叠
- 防止中间内容被两侧覆盖,一个用padding(圣杯),一个用margin(双飞翼)
5-3:手写clear fix
.clearfix:after{
content:'';
display:table;
clear:both;
}
.clearfix{
*zoom:1;/*兼容IE低版本*/
}
6:flex布局
6-1:flex实现一个三点的色子
常用语法回顾:
- flex-direction:row|row-reverse|column|column-reverse|initial|inherit;
- justify-content : flex-start|flex-end|center|space-between|space-around|initial|inherit;左右
- align-items :stretch|center|flex-start|flex-end|baseline|initial|inherit;上下
- flex-wrap :nowrap|wrap|wrap-reverse|initial|inherit;换行
- align-self:auto|stretch|center|flex-start|flex-end|baseline|initial|inherit;
7:定位
7-1:absolute和relative定位
- relative依据自身定位
- absolute依据最近一层的定位元素定位,没有最近定位位置就以body定位
7-2:定位元素
- absolute relative fixed
- body
8:居中对齐的实现
- 水平居中
- inline元素:text-align:center
- block元素:margin:auto;
- absolute元素:left:50%+margin-left负值
- 垂直居中
- inline元素:line-height的值等于height值
- absolute元素:transform(-50%,-50%)
- absolute元素:top:50%+margin-top负值
- absolute元素:top,left,bottom,right=0+margin:auto
9:line-heightr如何继承
- 写具体数值,如30px,则继承30px
- 写比列,如2/1.5,则继承该比例
body{
font-size:20px;
line-height:1.5;
}
p{
font-size:16px;
}
<p>sss</p>
p的line-height为1.5X16
- 写百分比,如200%,则继承父级计算出来的值
body{
font-size:20px;
line-height:200%;
}
p{
font-size:16px;
}
<p>sss</p>
p的line-height为200%X20
CSS的响应式
1:rem是什么
rem是一个长度单位
- px,绝对长度单位,最常用
- em,相对长度单位,相对于父元素,不常用
- rem,相对长度单位,相对于根元素,常用于响应式布局
2:响应式布局的常用方法
- media-query,,根据不同的屏幕宽度设置根元素font-size
- rem,基于根元素的相对单位
3:vw与vh
- rem的弊端:阶梯性
- 网页视口尺寸
- window.screen.height //屏幕高度
- window.innerHeight //网页视口高度
- document.body.clientHeight //body高度
- vw/vh
- vh网页视口高度的1/100
- vw网页视口宽度的1/100
- vmax取两者最大值;vmin取两者最小值
Javascript
1:typeof运算符
- 识别所有值类型
- 识别函数
- 判断是否是引用类型
2:深拷贝
var obj = {
name:"zs",
age:"18",
gender:"男",
friends:{
1:'aa',
2:'bb',
3:'cc'
},
hobby:["吃饭","唱歌","爬山"]
};
var obj2 = extendDeep(obj );
function extendDeep (source) {
var target;
if (typeof source !== 'object') {
target = source;
return target
}
target = Array.isArray(source) ? [] : {} ;
for (var key in source) {
if (typeof source[key] !== 'object') {
target[key] = source[key]
} else {
target[key] = extendDeep(source[key])
}
}
return target
}
参考:Ⅶ期Day6---实现javascript 中深拷贝和浅拷贝的方法
3:变量计算-类型转换
- 字符串拼接
- ==
- if语句
- truly变量:!!a===true的变量
- falsely变量:!!a===false的变量
- 逻辑运算
4:class
- constructor
- 属性
- 方法
4-1:继承
- extends
- super
- 扩展或重写方法
继承
class People{
constructor(name){
this.name=name
}
eat(){
console.log(`${this.name} eat`)
}
}
class Student extends People{
constructor(name,number){
super(name)
this.number=number
}
sayHi(){
console.log(`${this.name} say`)
}
}
const xx = new Student('livia',27)
console.log(xx.name)
console.log(xx.number)
xx.sayHi()
xx.eat()
结果:
livia
27
livia say
livia eat
4-2:类型判断 - instanceof
如何准确判断一个变量是数组
a instanceof Array
4-3:原型
- 每个class都有显示原型prototype
- 每个实例都有隐式原型__proto__
- 实例的__proto__指向对应class的prototype
4-4:基于原型的执行规则
- 获取属性xialuo.name或执行方法xialuo.sayhi()时
- 先在自身属性和方法寻找
- 如果找不到则自动去__proto__中查找
4-5:原型链
重要提示
- class是ES6语法规范,由ECMA委员会发布
- ECMA只规定语法规则,即我们代码的书写规范,不规定如何实现
- 以上实现方式都是V8引擎的实现方式,也是主流的
4-6:class的原型本质
- 原型和原型链的图示
- 属性和方法的执行规则
5:闭包
创建10个’<a>‘标签,点击的时候弹出对应的序号
5-1:作用域
- 全局作用域
- 函数作用域
- 块级作用域(ES6新增)
5-2:自由变量
- 一个变量在当前作用域没有定义,但被使用了
- 向上级作用域,一层一层依次寻找,直到找到为止
- 如果到全局作用域都没有找到,则报错xx is not defined
5-3:闭包
作用域应用的特殊情况,有两种表现:
1:函数作为参数被传递
function print(fn){
let a = 200
fn()
}
let a=100
function fn(){
console.log(a)
}
print(fn)//100
2:函数作为返回值被返回
function creat(){
const a=100
return function(){
console.log(a)
}
}
const fn =create();
const a = 200
fn()//100
说明:闭包:自由变量的查找,是在函数定义的地方,向上级作用域查找,不是在执行的地方!!!
6:this
- 作为普通函数
- 使用call apply bind
- 作为对象方法被调用
- 在class方法中调用
- 箭头函数
this的值是在this函数执行的时候定义的,不是在函数定义的时候执行的
function fn1(){
console.log(this)
}
fn1()//window
fn1.call({x:100})//{x:100}
const fn2=fn1.bind({x:200})
fn2()//{x:200}
call是立即执行,bind是返回一个新的函数
6-1:手写bind函数
参考:JavaScript 中 call()、apply()、bind() 的用法
6-2:实际开发中闭包的应用
- 隐藏数据
function createCache(){
const data={}//闭包中的数据,被隐藏,不被外界访问
return {
set:function(key,val){
data[key] = val
},
get:function(){
return data[key]
}
}
}
const c= createCache()
c.set('a',100)
console.log(c.get('a'))
key is not defined
- 如做一个简单的cache工具
7:单线程和异步
- JS是单线程语言,只能同时做一件事儿
- 浏览器和node.js已支持JS启动进程,如Web Worker
- JS和DOM渲染共用一个线程,因为JS可修改DOM结构
- 遇到等待(网络请求,定时任务)不能卡住
- 需要异步
- 回调callback函数形式
7-1:异步和同步
- 基于JS是单线程语言
- 异步不会阻塞代码执行
- 同步会阻塞代码执行
7-2 应用场景
网络请求,如ajax图片加载
定时任务,如setTimeout(执行一次)
7-3:Promise的基本使用
7-4 JS异步相关的面试
网络请求(图片加载)
当有2张图片时:
setTimeout定时任务
1 3 5 4 2
8:JS异步进阶
event loop(事件循环/事件轮询)
- JS是单线程运行的
- 异步要基于回调来实现
- event loop就是异步回调的实现原理
请描述event loop(事件循环/事件轮询)的机制,可画图
上面代码执行过程为:
在Call Stack中出现Hi->Browser console输出Hi->Call Stack中出现setTimeout cb1->因为还没到5s无法输出,则出现在web APIs中timer cb1->Call Stack中setTimeout cb1消失->Call Stack中出现Bye->Browser console输出Bye->5秒到了timer则出现在Callback Queue中->通过Event Loop轮询->cb1出现在Call Stack中->cb1在Browser console中输出
总结event loop过程1
- 同步代码,一行一行放在Call Stact执行
- 遇到异步,会先’记录‘下,等待时机(定时,网络请求等)
- 时机到了,就移动到Callback Queue
总结event loop过程2
- 如Call Stack为空(即同步代码执行完)event loop开始工作
- 轮询查找Callback Queue,如有则移动到Call Stack执行
- 然后继续轮询查找(永动机一样)
JS如何执行?
- 从前到后,一行一行执行
- 如果某一行执行报错,则停止下面代码的执行
- 先把同步代码执行完,在执行异步
hi bye cb1
DOM事件和event loop
触发的时机不一样
8-2:Promise
- 三种状态
- pending resolved rejected
- pending->resolved 或pending ->rejected
- 变化不可逆
const p1 = new Promise((resolve,reject)=>{})
console.log('p1',p1)//pending
const p2 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve()
})
})
console.log('p2',p2)//pending一开始打印时
setTimeout(()=>console.log('p2-setTimeout',p2))//resolved
const p3 = new Promise((resolve,reject)=>{
setTimeout(()=>{
reject()
})
})
console.log('p3',p3)//pending一开始打印时
setTimeout(()=>console.log('p3-setTimeout',p3)//reject
- 状态的表现和变化
- pending状态,不会触发then和catch
- resolved状态,会触发后续的then回调函数
- rejected状态,会触发后续的catch回调函数
下面p1不会触发catch,p2不会触发then
- then和catch对状态的影响
- then正常返回resolved,里面有报错则返回rejected
2.catch正常返回resolved,里面有报错则返回rejected
面试题一
Promise.resolve().then(()=>{
console.log(1)
}).catch(()=>{
console.log(2)
}).then(()=>{
console.log(3)
})
面试题2
Promise.resolve().then(()=>{
console.log(1)
throw new Error('erro1')
}).catch(()=>{
console.log(2)//没报错,所以是resolved,触发then回调
}).then(()=>{
console.log(3)
})
面试题3
Promise.resolve().then(()=>{//rejected触发catch回调
console.log(1)
throw new Error('erro1')
}).catch(()=>{
console.log(2)//没报错,所以是resolved,触发then回调
}).catch(()=>{
console.log(3)
})
1 2
Promise总结
- 三种状态,状态的表现和变化
- then和catch对状态的影响(重要)
- then和catch的链式调用(常考)
8-3 async/await
- 异步回调callback hell
- Promise then catch链式调用,但也是基于回调函数
- async/await是同步语法,彻底消灭回调函数
第二种写法
8-4 async/await和Promise的关系
- async/await是消灭异步回调的终极武器
- 但和Promise并不互斥
- 反而,两者相铺相成
- 执行async函数,返回的是Promise对象
- await相当于Promise的then
- try...catch可捕获异常,代替了Promise的catch
列子1:
列子2:Promise
打印出data,100
可看出async相当于返回一个Promise对象的,直接返回一个Promise则会直接输出data 200
列子3-1:await相当于Promise的then
列子3-2:await相当于Promise的then
列子3-3:await相当于Promise的then
列子4:
异步的本质
- async/await是消灭异步回调的终极武器
- JS还是单线程,还得是有异步,还是基于event loop
- async/await只是一个语法糖
列子1:
列子2:
for...of
- for...in(以及forEach for)是常规的同步遍历
- for...of常用于异步的遍历
列子1:
同时1s后出来1 4 9(同步循环)
列子二:如果想有间隔的输出1 4 9(异步循环)
async/await总结
- async/await解决了异步回调,是一个很香语法糖
- async/await和Promise的关系,重要
- for...of的使用
宏任务macroTask和微任务microTask
- 什么是宏任务,什么是微任务
- event loop和DOM渲染
- 微任务和宏任务的区别
列子1:
宏任务和微任务
- 宏任务:setTimeout setInterval,ajax DOM事件
- 微任务:Promise async/await
- 微任务执行时机比宏任务要早(先记住)
event loop和DOM渲染
- 再次回归一遍event loop的过程
- JS是单线程的,而且和DOM渲染共用一个线程
- JS执行的时候,得留一些时机供DOM渲染
- 每次Call Stack清空(即每次轮询结束),即同步任务执行完
- 都是DOM重新渲染的机会,DOM结构如有改变则重新渲染
- 然后再去触发下一次Event loop
微任务和宏任务的区别
- 宏任务:DOM渲染后触发,如setTimeout
- 微任务:DOM渲染前触发,如Promise
- 先演示现象,稍后再追究原理
从event loop解释,为何微任务执行的早
为什么?
- 微任务是ES6语法规定的
- 宏任务是由浏览器规定的
微任务和宏任务-总结
- 宏任务有哪些?微任务有哪些?微任务触发时机更早
- 微任务,宏任务和DOM渲染的关系
- 微任务,宏任务和DOM渲染,在event loop的过程
面试题:
1:描述event loop机制(可画图)
- 自行回顾event loop的过程
- 和DOM渲染的关系
- 微任务和宏任务在event loop过程中的不同处理
2:什么是宏任务和微任务,两者区别
- 宏任务:setTimeout setInterval,ajax DOM事件
- 微任务:Promise async/await
- 微任务执行时机比宏任务要早(先记住)
3:Promise的三种状态,如何变化
- pending resolved rejected
- pending->resolved或pending->rejected
- 变化不可逆
4:promise then和catch的连接
第一题:1 3 第二题 123 第三题12
5:async/await语法
left:第一个是一个promise,第二个100
right:依次输出start 100 200 后面报错(因为await是then,然后后面跟着reject,所以后面代码不执行)
6:promise和setTimeout的顺序
7:async/await的顺序问题
//同步执行结束完毕(event loop-call stack被清空)
//执行微任务
//尝试触发DOM渲染
//触发Event Loop,执行宏任务
JS异步进阶总结
- event loop
- promise进阶
- async/await
- 微任务/宏任务
DOM事件和Event loop
- JS是单线程的
- 异步(setTimeout,ajax等)使用回调,基于event loop
- DOM事件也使用回调,基于event loop
Promise进阶
- 三种状态,状态的表现和变化
- then和catch对状态的影响(重要)
- then和catch的链式调用(常考)
async/await总结
- async/await解决了异步回调,是一个很香语法糖
- async/await和Promise的关系,重要
- for...of的使用
微任务和宏任务-总结
- 宏任务有哪些?微任务有哪些?微任务触发时机更早
- 微任务,宏任务和DOM渲染的关系
- 微任务,宏任务和DOM渲染,在event loop的过程