2021-01-08(今日笔记)

1、css 预处理器(sass/less)

原理:是将类css语言通过 webpack 编译转成浏览器可读的真正css。常用功能:
嵌套
变量
循环语句
条件语句
自动前缀
单位转换
mixin复用

2、css动画

transition:过渡动画
transition-property:属性
transition-duration:间隔
transition-timing-function: 曲线
transition-delay:延迟

animation/keyframes:
animation-name:动画名称,对应 @keyframes
animation-duration:间隔
...

动画属性:尽量使用动画属性进行动画
translate
scale
rotate
skew

3、原型/构造函数/实例

原型(prototype):一个简单的对象,用于实现对象的属性继承。每个js对象中都包含一个 __proto__的
属性指向它爹(该对象的原型),可 obj.__proto__ 进行访问。

构造函数:可以通过 new 来新建一个对象的函数。

实例:通过构造函数和new创建出来的对象,便是实例。实例通过 __proto__ 指向原型,通过constructor
指向构造函数。

//实例
const instance = new Object()
实例为 instance,构造函数为object,构造函数拥有一个prototype的属性指向原型。
//原型
const prototype = Object.prototype

实例.__proto__ === 原型
原型.constructor === 构造函数
构造函数.prototype === 原型
实例.constructor === 构造函数


原型链:
原型链是由原型对象组曾,每个对象都有 __proto__ 属性,指向了创建对象的构造函数的原型,__proto__
将对象连接起来组成了原型链。是一个用来实现继承和共享属性的有限的对象链。

执行上下文:(EC 可以理解为一个对象)
包含三个部分:
变量对象VO
作用域链(词法作用域)
this指向
类型:
全局执行上下文
函数执行上下文
eval执行上下文
代码执行过程:
创建 全局上下文global EC;
全局执行上下文逐行自上而下执行。
函数执行上下文被激活,成为active EC,开始执行函数中的代码,caller被挂起
函数执行完成后,callee 被pop移除执行栈,控制权交还全局上下文caller,继续执行。


作用域:
执行上下文中包含作用域链。作用域其实可以理解为该上下文中声明的 变量和声明的作用范围。分为 块级作用
域和函数作用域。
特性:
声明提前:一个声明在函数体内都是可见的,函数优先于变量。
非匿名执行函数,函数变量为 只读 状态,无法修改。
let fun = function(){console.log('func')}
(function fun(){ fun = 10;console.log(fun) }()) ;//这里会输出: f fun(){fun=10;
console.log((fun)}


闭包:
(定义)父函数被销毁的情况下,返回出的子函数的[[scope]]中仍然保留着父级的单变量对象和作用域链,因此可以
继续访问到父级的变量对象。

会产生的问题:多个子函数的[[scope]]都是同时指向父级,是完全共享的。因此当父级的变量对象被修改时,
所有子函数都受到影响。

解决:
变量可以通过 函数参数的形式 传入,避免使用默认的[[scope]]向上查找。
使用 setTimeout 包裹,通过第三个参数传入
使用块级作用域,让变量成为自己上下文的属性,避免共享。


script 引入方式:
静态<script>引入
js动态插入<script>
<script defer>:延迟加载,元素解析完成后执行
<script async>:异步加载,但执行时会阻塞元素渲染


对象的拷贝:
浅拷贝:以赋值的形式拷贝引用对象,仍指向同一个地址,修改时原对象也会受到影响。
Object.assign
展开运算符(...)
深拷贝:完全拷贝一个新对象,修改时原对象不再受到任何影响。
JSON.parse(JSON.stringify(obj)):性能最快。
递归进行逐一赋值。


new 运算符的执行过程:
新生成一个对象
链接到原型:obj.__proto__ = Con.prototype
绑定 this: apply
返回新对象。


代码复用方式:
函数封装,
继承,
复制extend
混入mixin
借用apply/call

3、let, const 以及 var 的区别?

es5只有全局作用域和函数作用域,没有块级作用域。
es6中增加了块级作用域的概念。

let命令:
用来声明变量,但是所声明的变量,只在let命令所在的代码块内有效。
不存在变量提升。(var命令会发生'变量提升'现象,即变量可以在声明之前使用,值为undefined。)
不允许重复声明。
暂时性死区(只要块级作用域内存在let命令,它所声明的变量就绑定这个区域,不再受外部的影响。在代码块
内,使用let命令声明变量之前,该变量都是不可用的。temporal dead zone => TDZ)

const:
声明一个只读的常量。一旦声明,常量的值就不能改变。
const 一旦声明变量,就必须立即初始化,不能留到以后赋值。对于const来说,只声明不赋值,就会报错。
const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。
const 的作用域与let命令相同:只在声明所在的块级作用域内有效。

var:变量提升(无论声明在何处,都会被提至其所在作用域的顶部。
let:无变量提升(未到let声明时,是无法访问该变量的)
const:无变量提升,声明一个基本类型的时候为常量,不可修改;声明对象可以修改。

4、HTTP常见状态码

HTTP状态码表示客户端HTTP请求的返回结果,标记服务器端的处理是否正常或者是出现的错误,能够根据返回的状态
码判断请求是否得到正确的处理。

1xx 信息性状态码: 接受的请求正在处理
2xx 成功状态码: 请求正常处理完毕
200 -> ok
204 -> no content: 表示客户端发送请求得到处理,但在返回的响应报文中不含实体的主体部分。

3xx 重定向 需要进行附加操作已完成请求
301 -> moved permanently: 永久性重定向,表示请求的资源被分配了新的url,之后应使用更改的url。
302 -> found:临时性重定向
304 -> not modified: 表示客户端发送附带条件的请求时,服务端允许访问资源。
4xx 客户端错误 客户端请求出错,服务器无法处理请求
400 ->bad request:请求报文中存在语法错误
401 ->unauthorized:未经许可,需要通过HTTP认证
403 ->forbidden:服务器拒绝该次访问
404 ->not found: 表示服务器上无法找到请求的资源。
5xx 服务器错误 服务器处理请求出错

5、vuex

vuex 是一个专门为vue.js应用设计的状态管理构架,统一管理和维护各个组件的可变化状态。
五个核心概念:
state: vuex的基本数据,用来存储变量
getter:从基本数据state派生的数据,相当于state的计算属性
mutation:提交更新数据的方法,必须是同步的(异步可使用action)
action:异步操作
modules:模块化vuex,可以让每一个模块都拥有自己的state,mutation等,方便管理。

6、防抖/节流

高频触发优化方式,能对性能有较大的帮助。

防抖(debounce):将多次高频操作优化为只在最后一次执行,通常使用的场景是:用户输入,只需要再输入完成后做一次
校验即可。
function debounce(fn,wait,immediate){
let timer = null;
return function(){
let args = arguments;
let context = this;
if(immediate && !timer){
fn.apply(context,args)
}
if(timer) clearTimeout(timer)
timer = setTimeout(()=>{
fn.apply(context,args)
},wait)
}
}

节流:每隔一段时间后执行一次,也就是降低频率,将高频操作优化成低频操作,通常使用场景:滚动条事件或者resize
事件,通常每隔100-500ms执行一次即可。
function throttle(fn,wait,immediate){
let timer = null;
let callNow = immediate
return function(){
let context = this,
args = arguments;
if(callNow){
fn.apply(context,args);
callNow = false
}
if(!timer){
timer = setTimeout(()=>{
fn.apply(context,args)
timer = null;
},wait)
}
}
}

7、函数执行改变this

在函数中,可以引用运行环境中的变量。就需要一个机制来让我们在函数体内部获取当前的运行环境,即this。
this指向,即谁调用了函数。例如
obj.fn(),便是obj调用了函数,即函数中的this === obj;
fn(),即window.fn(),因此 this === window;

手动修改this的指向,即:
call: fn.call(target,1,2)
apply: fn.apply(target,[1,2])
bind: fn.bind(target)(1,2)
共同点:第一个参数都是this要指向的对象,都可以利用后续参数传参,都可以改变this指向。
不同点:
call 和 apply 都是对函数的直接调用,而bind方法返回的仍然是一个函数,因此后面需要()进行调用才可以。
call后面的参数与func方法中是一一对应的,apply的第二个参数是一个数组,数组中的元素和func方法中一一对应。
由于bind返回的仍然是一个函数,所以我们可以在调用的时候进行传参。
例如:
var obj = {
name:'xx',
age:18,
say:function(param1,param2){
console.log(this.name +',今年'+ this.age+'岁,'+params1 + param2)
}
}
var obj2 = {
name:'yy',
name:'20'
}
obj2.say.call(obj1,'hello','world')
obj2.say.apply(obj1,['hello','world'])
obj2.say.bind(obj1)('hello','world')

8、ES6/ES7

声明
let/const:块级作用域,不存在变量提升,暂时性死区,不允许重复声明
const:声明常量,无法修改
解构赋值
class/extend:类声明与继承
set/map:新的数据结构
异步解决方案:
promise 的使用与实现
generator:
yield:暂停代码
next():继续执行代码

function* helloworld(){
yield 'hello';
yield 'world';
return 'ending';
}
const generator = helloworld();
generator.next() //{value:'hello',done:false}
generator.next() //{value:'world',done:false}
generator.next() //{value:'ending',done:false}
generator.next() //{value:undefined,done:true}

await/async: 是generator的语法糖,Babel中是基于promise实现。

async function getUserByAsync(){
let users = await fetchUser();
return users;
}
const user = await getUserByAsync()
console.log(user,'user')

9、函数柯里化

在一个函数中,首先填充几个参数,然后再返回一个新的函数的技术,称为函数的柯里化。
const add = function add(x){
return function(y){
return x+y
}
}
const add1 = add(1);
add1(2) => 3

10、数组 array

map:遍历数组,返回回调返回值组成的新数组
forEach:无法break,可以用try/catch 中 throw new Error 来停止。
filter:过滤
some:有一项返回true,则返回true
every:有一项返回false,则返回false。
join:通过指定连接符生成字符串
push/pop:末尾添加和删除,改变原数组。
unshift/shift:头部添加和删除,改变原数组。
sort(fn)/reverse:排序与反转,改变原数组
concat:连接数组,不影响原数组,浅拷贝
slice(start,end):返回截断后的新数组,不改变原数组
splice(start,number,value...):返回删除元素组成的数组,value为插入项,改变原数组
indexOf/lastIndexOf(value,formIndex):查找数组项,返回对应的下标
reduce/reduceRight()

数组乱序:
var arr = [1,2,3,4,5,6,7,8,9,10]
arr.sort(function({
return Math.random() - 0.5;
})
数组拆解:flat:[1,[2,3]] ->[1,2,3]
Array.prototype.flat = function(){
return this.toString.split(',').map(item => +item)
}

11、从输入url到页面展示的过程

DNS解析
TCP三次握手
发送请求,分析url,设置请求报文(头,主体)
服务器返回请求的文件html
浏览器渲染(html css layout布局...)

12、回流必定触发重绘,重绘不一定触发回流。重绘的开销较小,回流的代价较高。

13、存储

存储分为短暂性存储和持久性存储
短暂性存储:将数据存在内存中,只在运行时用即可。
持久性存储:分为浏览器端和服务器端。
浏览器:
cookie:通常用于存储用户身份,登录状态等。(体积上限4k,可自行设置过期时间)
localStorage/sessionStorage:长久存储/窗口关闭删除,体积限制4-5M
indexDB
服务器:
分布式缓存redis
数据库

14、内存泄露

意外的全局变量:无法被回收
定时器:未被正确关闭,导致所引用的外部变量无法被释放
事件监听:没有正确销毁
闭包:导致父级中的变量无法被释放
dom引用:dom元素被删除时,内存中的引用未被正确清空

15、get/post

get:缓存,请求长度受限,会被历史保存记录
post:安全,大数据,更多编码类型。

16、websocket

websocket 是一个持久化协议,基于http,服务端可以主动push。

new WebSocket(url)
ws.onerror = fn
ws.onclose = fn
ws.onopen = fn
ws.onmessage = fn
ws.send()

17、TCP三次握手,四次挥手

建立连接前,客户端和服务端需要通过握手来确认对方:
客户端发送syn(同步序列编号)请求,进入 syn_send 状态,等待确认。
服务端接收并确认syn包后发送 syn+ack包,进入 syn_recv状态
客户端接收 syn+ack 包后,发送 ack 包,双方进入 established 状态。

四次挥手:
客户端 -FIN ->服务端,FIN-WAIT
服务端 -ACK ->客户端,CLOSE-WAIT
服务端 -ACK,FIN ->客户端,LAST-ACK
客户端 -ACK ->服务端,CLOSED

18、跨域

JSONP: 利用 <script>标签不受跨域限制的特点,缺点是只能支持get请求
function jsonp(url,jsonpCallback,success){
const script = document.createElement('script')
script.src = url
script.async = true
window[jsonpCallback] = function(data){
success && successs(data)
}
document.body.appendChild(script)
}

设置 CORS: Access-Control-Allow-Origin:'*'
postMessage

参考链接:https://juejin.cn/post/6844903776512393224#heading-16

 

posted on 2021-01-08 19:53  有匪  阅读(63)  评论(0编辑  收藏  举报

导航