块状元素:display:block/table;有div h1 h2 table ul ol p等
内联元素:display:inline-block/inline;有span img input button 等
offsetWidth = (内容宽度+内边距+边框),无外边距
margin-top和margin-left负值,元素上移动,左移动
margin-right负值,右侧元素左移,自身不受影响
margin-bottom负值,下方元素上移动,自身不受影响
概念:块级格式化上下文
好处:一块独立渲染区域,内部元素的渲染不会影响边界外的元素
常见形成BFC的条件:
BFC的应用:清除浮动
relative依据自身定位
absolute依据最近一层的定位元素(非static)定位 (absolute relative fixed => body)
fixed根据浏览器窗口的位置和大小进行定位
vh:网页视口高度的1/100
vw:网页视口宽度的1/100
vmax:取两者最大值
vmin:取两者的最小值
turly变量 : !!a === true
falsely变量 :!!a === false
除了 = = null之外,其他一律用 = = =
例如:
const obj = { x: 100 }
if (obj.a == null) { }
相当于:
if (obj.a === null || obj.a === undefined) { }
// 深拷贝
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
}
作用域:
//es6新增const let 块级作用域
if (1) {
let a = 1
}
//报错
console.log(a)
自由变量:
闭包
// 函数作为返回值
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
总结:所有自由变量的查找,是在函数定义的地方,向上级作用域查找,不是在执行的地方!!!
this取什么值是在函数执行的时候确定的,不是在函数定义的时候确定的
function fn() {
console.log(this)
}
fn()//window
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方法中调用
箭头函数
异步应用场景
题目:
console.log(1);
setTimeout(() => {
console.log(2);
}, 1000)
setTimeout(() => {
console.log(3);
}, 0)
console.log(4);
//1432
问题:js是如何执行?
promise状态
三种转态:pending resolved rejected; pending -> resolved 或 pending ->rejected
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)
})
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 function p() {
return 100 //相当于return promise.resolve(100)
}
console.log(a()); //执行async函数,返回的是promise 对象
p().then((data) => {
console.log(data); //100
})
!(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
})()
!(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 只是语法糖
宏任务:DOM渲染后触发,如setTimeout
微任务:DOM渲染前触发,如promise
微任务是ES6语法规定的
宏任务是由浏览器规定的
8-17题目
注意:promise初始化立刻执行,await 后的为回调异步
前端实现跨域:jsonp cors 服务器设置 access-control-allow-origin
http状态码
301永久重定向,302临时重定向,304资源未被修改
4xx客户端错误,如404
5xx服务端错误,如500
传统 API 设计:把每个url当做一个功能
Restful API设计:把每个url当做一个唯一的资源
如何当做一个资源:
请求头
响应头
为什么缓存:提示页面加载速度,增强用户体验
哪些可以被缓存:(js css img)
cache-control
cache-control的值:
1.max-age
2.no-cache不用强制缓存
资源标识:
1.响应头中
2.last-modified 资源的最后修改时间
3.etag 资源的唯一标识(一个字符串 类似人类的指纹)
4.优先使用Etag
http和https的区别:http明文传输,敏感信息容易被劫持,https=http+加密,劫持了也无法解密,现代浏览器已开始强制https协议
https采用非对称加密