html以及css相关的面试题
1、如何理解html语义化
- 增加代码的可读性
- 让搜索引擎更容易读懂(SEO)
2、块状元素和内联元素
块状元素:display:block/table;有div h1 h2 table ul ol p等
内联元素:display:inline-block/inline;有span img input button 等
3、盒模型宽度计算
offsetWidth = (内容宽度+内边距+边框),无外边距
4、margin纵向重叠问题
- 相邻元素的margin-top和margin-bottom会发生重叠
- 空白内容的p标签也会重叠
5、margin负值的问题
margin-top和margin-left负值,元素上移动,左移动
margin-right负值,右侧元素左移,自身不受影响
margin-bottom负值,下方元素上移动,自身不受影响
6、BFC理解与应用
概念:块级格式化上下文
好处:一块独立渲染区域,内部元素的渲染不会影响边界外的元素
常见形成BFC的条件:
- float不是none
- position是absolute或fixed
- overflow不是visible
- display是flex或者inline-block等
BFC的应用:清除浮动
7、absolute、relative、fixed分别依据什么定位
relative依据自身定位
absolute依据最近一层的定位元素(非static)定位 (absolute relative fixed => body)
fixed根据浏览器窗口的位置和大小进行定位
8、css实现居中
六种方式实现居中
九、line-height如何继承
- 学具体值,如30px,则直接继承
- 写比例,如2/1.5,则继承该比例
- 写百分比,如200%,则继承计算出来的值(考点)
十、css响应式
- px,绝对长度单位,最常用
- em,相对长度单位,相对父元素,不常用
- rem,相对长度单位,相对于根元素,常用于响应式布局
十一、响应式布局的常见方案
- media-query,根据不同的屏幕宽度设置根元素font-size
- rem,基于根元素的相对单位
十二、CSS vw和vh
rem的弊端:“阶梯”性
网页视口尺寸
- window.screen.height 屏幕高度
- window.innerHeight 网页视口高度
- doucment.body.clientHeight body高度(内容高度)
vh:网页视口高度的1/100
vw:网页视口宽度的1/100
vmax:取两者最大值
vmin:取两者的最小值
js面试题
1、类型转换
turly变量 : !!a === true
falsely变量 :!!a === false
2、typeof 能判断哪些类型
- 识别所有值类型
- 识别函数
- 判断是否为引用类型(不可细分)
3、何时使用 = = = ,何时使用 = =
除了 = = null之外,其他一律用 = = =
例如:
const obj = { x: 100 }
if (obj.a == null) { }
相当于:
if (obj.a === null || obj.a === undefined) { }
4、手写深拷贝
- 注意判读值类型和引用类型
- 注意判读是数组还是对象
- 递归
// 深拷贝
const obj1 = {
name: 'obj1',
address: {
city: 'cq'
}
}
const obj2 = deepClone(obj1)
obj2.name = 'ojj2'
console.log(obj1.name);
// 深拷贝函数
function deepClone(obj) {
if (typeof obj !== "object" || obj == null) {
return obj
}
let result
// 初始化返回结果
if (obj instanceof Array) {
result = []
} else {
result = {}
}
for (let key in obj) {
// 保证key不是原型的属性
if (obj.hasOwnProperty(key)) {
result[key] = deepClone(obj[key])
}
}
return result
}
5、原型和原型链
- 原型:函数都有prototype属性,称之为原型,也称为原型对象
- 原型对象可以放一些属性和方法,共享给实例对象使用
- 原型也可以做继承。
- 原型链:对象都有__proto__属性,这个属性指向它的原型对象,原型对象也是对象,也有__proto__属性,指向原型对象的原型对象,这样一层一层形成的链式结构称之为原型链,最顶层找不到则返回null
图示:
6、作用域和闭包
作用域:
- 全局作用域(window、document等)
- 函数作用域(函数内部)
- 块级作用域
//es6新增const let 块级作用域
if (1) {
let a = 1
}
//报错
console.log(a)
自由变量:
- 一个变量在当前作用域没有定义,但被使用了
- 向上级作用域,一层一层依次寻找,直到找到为止
- 如果到全局作用域没有找到,则报错 xx is not defined
闭包
- 函数作为返回值被返回
// 函数作为返回值
function create() {
const a = 100
return function () {
console.log(a)
}
}
const fn = create()
const a = 200
fn() //100
2.函数作为参数被传递
// 函数作为参数被传递
function print(fn) {
const a = 200
fn()
}
const a = 100
function fn() {
console.log(a)
}
print(fn) //100
总结:所有自由变量的查找,是在函数定义的地方,向上级作用域查找,不是在执行的地方!!!
7、this
this取什么值是在函数执行的时候确定的,不是在函数定义的时候确定的
- 作为普通函数
function fn() {
console.log(this)
}
fn()//window
- 使用call apply bind
function fn() {
console.log(this)
}
fn.call({ x: 1 }) //{ x: 1 }
const fn2 = fn.bind({ y: 2 }) //{ y: 2 }
fn2() //{ y: 2 } //bind返回的是函数
- 作为对象方法被调用
const lj = {
name: 'lj',
say() {
// this指向的是当前对象
console.log(this);
},
eat() {
setTimeout(function () {
// this === window
console.log(this);
})
}
}
lj.say()
lj.eat()
在class方法中调用
箭头函数
八、同步和异步
- 区别
- 基于JS是单线程语言
- 异步不会阻塞代码的执行
- 同步会阻塞代码执行
异步应用场景
- 网络请求如ajax, 图片加载
- 定时任务, 如setTimeout
题目:
console.log(1);
setTimeout(() => {
console.log(2);
}, 1000)
setTimeout(() => {
console.log(3);
}, 0)
console.log(4);
//1432
九、事件循环(event loop)
- js是单线程运行的
- 异步要基于回调来实现
- event loop 就是异步回调的实现原理
问题:js是如何执行?
- 从前到后,一行一行执行
- 如果某一行执行错误,则停止下面代码的执行
- 先把同步代码执行完,再执行异步
promise状态
三种转态:pending resolved rejected; pending -> resolved 或 pending ->rejected
- pending状态,不会触发then和catch
const p1 = Promise.resolve().then(() => {
return 100
})
console.log('p1', p1) //resolved 状态,会触发后续的then回调函数
p1.then(() => {
console.log(123)
})
const p2 = Promise.resolve().then(() => {
throw new Error('then error')
})
console.log('p2', p2) //rejected 状态,会触发后续的catch回调函数
p2.then(() => {
console.log(456) //不会执行
}).catch((err) => {
console.error('err1000', err)
})
- rejected 状态,会触发后续的catch回调函数
const p3 = Promise.reject('my error').catch((err) => {
console.error(err)
})
console.log('p3', p3); //fulfilled == resolve 注意!触发then回调
p3.then(() => {
console.log(100) //正常打印
})
const p4 = Promise.reject('my error').catch((err) => {
throw new Error('catch error')
})
console.log('p4', p4); //rejected 触发catch回调
p4.then(() => {
console.log(200) //不会打印
}).catch(() => {
console.log(300) //正常打印
})
相关的面试题
Promise.resolve().then(() => {
console.log(1);
}).catch(() => {
console.log(2); //没有报错,不会执行
}).then(() => {
console.log(3);
})
// 打印 1 3
Promise.resolve().then(() => {
console.log(1);
throw new Error('catch error') //返回resolved的状态
}).catch(() => {
console.log(2);
}).then(() => {
console.log(3); //打印,上一个catch没有抛出错误,所有状态为resolved
})
// 打印 1 2 3
Promise.resolve().then(() => {
console.log(1);
throw new Error('error1')
}).catch(() => {
console.log(2);
}).catch(() => {
console.log(3); //没有报错,不会执行
})
// 打印 1 2
async await和promise的关系
- 执行async函数,返回的是promise
async function p() {
return 100 //相当于return promise.resolve(100)
}
console.log(a()); //执行async函数,返回的是promise 对象
p().then((data) => {
console.log(data); //100
})
- await相当于promise的then
!(async function () {
const p1 = Promise.resolve(300)
const data = await p1 //await 相当于promise then
const data1 = await 400 //如果为一个值 则相当于 await promise.resolve(400)
console.log('data', data); //300
console.log('data1', data1); //400
})()
- try…catch可以捕获异常,代替了promise的catch
!(async function () {
const p4 = Promise.reject(500)
try {
const res = await p4
console.log(res);
} catch (error) {
console.error(error) // try...catch相当于 promise catch
}
})()
注意:reject用await不执行,因为await对应then
!(async function () {
const p4 = Promise.reject(500)
const res = await p4 //await->then
console.log(res) //不会执行
})()
异步的本质:
async await 是同步语法,彻底消灭回调函数
js还是单线程,还得是有异步,还是得基于event loop
async await 只是语法糖
十、宏任务、微任务
- 宏任务:setTimeout, setInterval, ajax, DOM事件
- 微任务:promise async / await
event loop 和DOM渲染
- 每次Call Stack清空(即每次轮询结束),即同步任务执行完
- 都是DOM重新渲染的机会,DOM结构如有改变则重新渲染
- 然后再去触发下一次Even Loop
宏任务:DOM渲染后触发,如setTimeout
微任务:DOM渲染前触发,如promise
宏任务和微任务根本区别
微任务是ES6语法规定的
宏任务是由浏览器规定的
8-17题目
注意:promise初始化立刻执行,await 后的为回调异步
前端实现跨域:jsonp cors 服务器设置 access-control-allow-origin
十、http面试题
http状态码
- 1xx服务器收到请求
- 2xx请求成功,如200
- 3xx重定向,如302
301永久重定向,302临时重定向,304资源未被修改
-
4xx客户端错误,如404
-
5xx服务端错误,如500
Resutful API(一种新的api推广使用)
- get获取数据
- post新建数据
- patch/put更新数据
- delete删除数据
传统 API 设计:把每个url当做一个功能
Restful API设计:把每个url当做一个唯一的资源
如何当做一个资源:
- 不使用url参数
- 使用methd表示操作类型
http headers
请求头
- accpet 浏览器可接受的数据格式
- accept-encoding 浏览器可接收的压缩算法
- accept -languange 浏览器可接受的语言
- connection keep-live 一次tcp连接重复使用
- cookie
- host 域名
- user-agent 浏览器信息
- content-type 发送数据的格式(post)
响应头
- content-type
- content-encoding 返回的压缩算法
- set-cookie
- cache-control
http缓存
为什么缓存:提示页面加载速度,增强用户体验
哪些可以被缓存:(js css img)
强制缓存
cache-control
- 存在响应头中
- 控制强制缓存的逻辑
- 列如cache-control:max-age=255555412(单位是秒) 值:no-cache不用强制缓存 no-store都不做
cache-control的值:
1.max-age
2.no-cache不用强制缓存
协商缓存
- 服务端缓存策略
- 服务端判断客户端资源,是否和服务端资源一样
- 一致则返回304,否则返回200和最新资源
资源标识:
1.响应头中
2.last-modified 资源的最后修改时间
3.etag 资源的唯一标识(一个字符串 类似人类的指纹)
4.优先使用Etag
http请求的过程
刷新操作对http请求的影响
- 正常操作:强制缓存有效,协商缓存有效
- 手动刷新f5:强制缓存消失,协商缓存有效
- 强制刷新ctrl+f5:强制缓存和协商缓存都失效
https加密方式
http和https的区别:http明文传输,敏感信息容易被劫持,https=http+加密,劫持了也无法解密,现代浏览器已开始强制https协议
https采用非对称加密
- 对称加密:一个key负责加密、解密
- 非对称加密:一对key,A加密之后,B只能用来解密
十一、web API
- DOM是哪种数据结构:DOM树
- DOM操作常见的API:DOM节点的操作,DOM结构的操作,attribute(修改html属性,会改变html结构)和property(修改对象属性,不会体现到html结构)两者都会引起dom渲染
- 一次性插入多个节点考虑性能