赞
踩
Content-Type:请求的与实体对应的MIME信息。
Content-Length:请求内容长度
Content-Language:响应体的语言。
Connection:是否需要持久连接
Date:时间
Expect:请求的特定的服务器行为
Host:指定请求的服务器的域名和端口号。
Location:用来重定向接收方到非请求URL的位置来完成请求或标识新的资源
vuex的数据是保存在缓存中的
//父子
vuex 状态管理
props 父子传值
$attrs 除了clss和style、props以外 子组件从过this.$attrs都可以拿到父组件的值
$listeners 事件
inheritAttrs为true 除 props 之外的所有属性
ref
reject与provide
//兄弟
$bus
//子父
vuex
emit
1、基于冒泡事件的无痕埋点方案
原理:
1、页面挂载时,监听页面跳转和点击事件
2、页面监听方法addViewListener:基于vue-router的beforeEach钩子,进行监听,收集页面router的值
3、点击事件addClickListener:基于冒泡事件原理监听document.onclick方法,获取元素最近一层级dom上绑定的data-xxx属性,进行数据通信
2、基于decorator实现无痕埋点
原理:在钩子函数中 (activated - created - mounted) 依次寻找这三个钩子
(1)它没有mutation,他只有state,getters,action【同步、异步】使用他来修改state数据
(2)他默认也是存入内存中,如果需要使用本地存储,在配置上比vuex麻烦一点
(3)语法上比vuex更容易理解和使用,灵活。
(4)pinia没有modules配置,没一个独立的仓库都是definStore生成出来的
(5)state是一个对象返回一个对象和组件的data是一样的语法
1、webpack是先打包在启动开发服务器,请求服务器时给予打包的结果
2、vite是直接启动开发服务器,需要哪个模块就对哪个模块进行实时编译
3、现代浏览器中exmodules会主动获取所需文件,vite就是利用这一个特性将开发文件变成浏览器所需的执行文件,而不是像webpack一样交给浏览器是打包后的文件
4、vite不需要打包,因此不需要模块依赖、编译,所以启动速度快,浏览器需要哪个模块在对哪个模块进行按需动态编译
5、在内容改变的时候,vite会直接去请求该模块,而webpack会把该模块相关的依赖和本身在重新执行一边
Nginx 在部署HTTPS 时比较麻烦(相对其它两者来说),Caddy、 SSLDocker 都是自动配置并且更新HTTPS,这对我这样的懒人来说很有用
1、for性能比forEach好,for循环没有额外的函数调用栈和上下文
2、for循环中会用到一些中断行为,对于优化数组遍历查找是很好的,但由于forEach属于迭代器,只能按序依次遍历完成,所以不支持上述的中断行为。
3、forEach 的循环起点只能为0不能进行人为干预,而for循环不同,能控制
CDN指的是内容分发网络。其基本思路是尽可能的避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定,将用户导离最近的服务节点上。
好处:
网站加速,利于Google的排名
有利于提高网站的转化率
提升网站的稳定性和安全性
能捕捉到的异常必须是线程执行已经进入 try catch 但 try catch 未执行完的时候抛出来的。
宏任务,因为它是通过 Event Loop一帧一帧渲染出来的
1、echarts进行视图渲染的时候,我们一般都会使用定时器来进行试图的更新,所以每次开启新的定时器的时候都要清空定时器
2、再渲染数据视图的时候,我们先要销毁实例然后再进行渲染,先获取echars实例,然后 dispose()销毁
1、浏览器解析html源码,然后创建一个 DOM树
2、解析css,创建cssdom树(浏览器默认设置 < 用户设置 < 外链样式 < 内联样式 < html中的style。)
3、css+domtree组合成渲染树(rendering tree)
1、增加v8内存 increase-memory-limit
2、缩减sourcemap配置
把devtool关闭,不添加sourcemap到内存
1、增加v8内存 increase-memory-limit
2、缩减sourcemap配置
把devtool关闭,不添加sourcemap到内存
typeof
instanceof
Object.prototype.toString
个人理解:追溯本源,向上寻找,找不到本身就找原型
function Person(age) {
this.age = age;
}
Person.prototype.name = "kavin";
var person1 = new Person();
person1.name = 123
console.log(person1.name); //123 此时的name是本身
delete person1.name
console.log(person1.name); //kavin 因为本身的name被删除了,但是原型prototype有一份name,所 以找不到本身的时候,向上寻找去原型里面查找
1、原型继承 优点:父类新增原型方法/原型属性,子类都能访问到 缺点:子不能向父传参 2、构造函数继承 优点:解决了原型继承中,子类实例共享父类引用属性的问题 缺点:继承单一、子不能向父传参 3、类继承 extend suprer // 父类 class Person{ constructor(name){ this.name = name; } showName( ){ return ` 名字为:${this.name}`; } showTest( ){ return ` 测试父类和子类有相同的方法名`; } } // 子类 class Student extends Person{ constructor(name,skill){ super(name); this.skill = skill; } showSkill( ){ return `张三的技能为${ this.skill }` } showTest( ){ return '子类里的showTest' } } // 调用 let stu1 = new Student('Strive', '逃学'); console.log(stu1.showName( )); //名字为Strive console.log(stu1.showSkill( )); //张三的技能为逃学 console.log(stu1.showTest( )); // 子类里的showTest
npm 脚本的原理非常简单。每当执行npm run,就会自动新建一个 Shell,在这个 Shell 里面执行指定的脚本命令。因此,只要是 Shell(一般是 Bash)可以运行的命令,就可以写在 npm 脚本里面。
比较特别的是,npm run新建的这个 Shell,会将当前目录的node_modules/.bin子目录加入PATH变量,执行结束后,再将PATH变量恢复原样。
这意味着,当前目录的node_modules/.bin子目录里面的所有脚本,都可以直接用脚本名调用,而不必加上路径。比如,当前项目的依赖里面有 Mocha,只要直接写mocha test就可以了。
1、nuxt
优点:更快的到达页面,减少页面的缓存时间
缺点:缺少document、window、import,限制比较多
2、Phantomjs 针对爬虫做处理
这种解决方案其实是一种旁路机制,原理就是通过Nginx配置, 判断访问的来源UA是否是爬虫访问,如果是则将搜索引擎的爬虫请求转发到一个node server,再通过PhantomJS来解析完整的HTML,返回给爬虫。
把所有依赖打包成一个 bundle.js 文件,通过代码分割成单元片段并按需加载。
主要的原因,是为了并行下载。
老的浏览器,同一时间只能从相同域名下载两个文件,新一点的,可以到6-8个。
如果一个页面有10个js,css,都在同一个域名,那么就得排队下载。
如果有个下载卡住了,后面都会被连累。
如果域名不重复,就可以并行下载
但域名数目也不是越多越好因为解析域名也要时
https://blog.csdn.net/weixin_35942339/article/details/112746942?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0.no_search_link&spm=1001.2101.3001.4242
插槽
<template slot-scope="scope"></template>
具名插槽
<template>
<button name="left">
</template>
替换
<h1 slot="left">
Object.freeze(o)
混合模式(局部和全局)
理解:代码的复用性
<transition name = "nameoftransition">
<div></div>
</transition>
<router-link tag="div">sdfsdfadsfsdf</router-link>
@hook:mounted="handleChildMounted"
filters: {
'过滤器名称': function (value1[,value2,...] ) {
// 逻辑代码
}
}
})
<!-- 在双花括号中 -->
<div>{{数据属性名称 | 过滤器名称}}</div>
<div>{{数据属性名称 | 过滤器名称(参数值)}}</div>
<!-- 在 `v-bind` 中 -->
<div v-bind:id="数据属性名称 | 过滤器名称"></div>
<div v-bind:id="数据属性名称 | 过滤器名称(参数值)"></div>
vue-router 配置 resolve+require加载
import()
虚拟dom不会重绘和排版的操作,真实dom是由虚拟dom转换的,真实的dom重绘和排版效率低,虚拟DOM会进行频繁修改,然后一次性比较并修改真实DOM中需要改的部分(注意!),最后并在真实DOM中进行排版与重绘,减少过多DOM节点排版与重绘损耗
1、提高渲染性能的
2、避免数据混乱的情况
解释:diff
1、是否带有#号
2、hahs不会影响后端,改变hash不会刷新数据,而且不包含在http请求中
3、history应用于浏览器历史记录中,提供了一个对历史记录修改的功能,他虽然也可以改变地址,但浏览器不会立即向服务器发送请求
一个域名必须对应一个ip地址,但是一个ip地址可以有多个域名。域名通过DNS服务器解析为ip才能被计算机识别,而域名则是由于ip比较难记,而域名对人来说比较容易记忆而对应ip 产生的,直接输入ip同样可以反问网站
首先是利用script标签的src属性来实现跨域。
通过将前端方法作为参数传递到服务器端,然后由服务器端注入参数之后再返回,实现服务器端向客户端通信。
由于使用script标签的src属性,因此只支持get方法
CORS 是一个 W3C 标准,全称是 "跨域资源共享"(Cross-origin resource sharing),它新增的一组 HTTP 首部字段,允许服务器声明哪些来源的请求有权访问当前资源,从而克服了 Ajax 只能同源使用的限制。
基于 Ajax 请求跨域获取数据失败的真正原理是:浏览器禁止与当前网页不同来源的数据被使用。CORS 的解决办法是,在服务端程序中,在发送消息之前手动修改响应头,将带有客户端浏览器的 IP 地址的数据包发送给客户端浏览器,然后客户端浏览器在查验服务端返回的数据时,发现响应头激活中的 IP 和当前网页的 IP 一样,那浏览器就认为这个数据包合法,可以使用该数据
指定一个唯一类型 let a = symbol()
Object.prototype.hasOwnProperty() 返回的是true和false
[] {} 内存地址不一样
因为它是脚本语言,只要用于与浏览器进行交互和操作dom,当出现多任务的时候,就会出现同步问题
window.onresize 或者element-resize-detector
delete name
indexOf includes
indexof 当匹配的时候 返回的是0
inclides 返回的是true和fasle
let a = "1213212313";
let b = [1,2,3.4];
//对象数组判断
var myArray = [
{
hello: 'stevie',
foo: 'baz'
}
];
console.log(myArray.map(x=>x.hello).indexOf('stevie'))
//元组判断
b.indexOf(1)
当this是在函数内的时候,this指向的是windows
当this是在对象的时候,且对象里面有函数,指向的是对象,如果里面还嵌套对象,则指向就近的对象
理解this简单理解,谁是老大或者就近老大
函数方法嵌套另一个函数方法 a(){a()}
解构数组
let n = new Array(10);
console.log(n.fill(1))
http是无状态的短连接,tcp是有状态的长连接,http建立在tcp之上
一个明文传输,一个是加密的ssl传输
一个端口为443,一个为8080
http传输速度比https快
https比http安全,但比较消耗成本,要买ssl证书
一个是传输协议,一个是用户数据报协议
一个面向连接,一个面向无连接
一个需要传输,一个不需要传输
一个1对1,一个1对多
CanelToken const CancelToken = axios.CancelToken; const source = CancelToken.source(); axios.get('/user/12345', { // 必须对请求进行cancelToken设置 cancelToken: source.token }).catch(function (thrown) { // 如果请求被取消则进入该方法判断 if (axios.isCancel(thrown)) { console.log('Request canceled', thrown.message); } else { // handle error } }); // 取消上面的请求 // source.cancel('messge') message为可选项,必须为String source.cancel('Operation canceled by the user.');
1、pending/reslove/reject 。pending就是未决,resolve可以理解为成功,reject可以理解为拒绝。
2、Promise用来封装一个异步操作并可以获取其结果
3、优点:1、解决回调地狱(Callback Hell)问题,让回调函数变成了规范的链式写法,程序流程可以看的很清楚
缺点:1、编写的难度比传统写法高,而且阅读代码也不是一眼可以看懂。2、无法取消Promise,一旦新建它就会立即执行,无法中途取消
promise,因为promise是微任务
async await返回的是一个promise 对象 它会优先执行同步的方法在执行异步的方法 如果里面调用了另一个函数方法 那个方法里面也有异步操作 也视为同步执行 如果await 上面有一个异步请求 则先执行异步请求在执行await 同理 await 下面是一个异步请求 先执行await 在执行异步 如果是await btn() 该方法变成异步 反正一句理解 异步遵循谁先谁执行 await最终的作用我大概理解成 将鸭子变成鸡 这里的鸡指的是异步 如果类似let a =await console 直接将await赋值给了一个对象 它就会变成与普通对象方法一样 变成同级从上往下执行
async和await是原生函数里面的语法,目前回调函数暂不支持async。
使用async和await明显节约了不少代码,不需要.then,不需要写匿名函数处理promise的resolve的值,不需要定义多余的data变量,还避免了嵌套代码。
async/await让try/catch 可以同时处理同步和异步错误。try/catch不能处理JSON.parse的错误,因为他在promise中。此时需要.catch,这样的错误处理代码非常冗余。并且,在我们的实际生产代码会更加复杂
async function timeout() { return 'hello world' }
timeout().then(result => { console.log(result); })
try{}cahcth(err){}
function Parent(month){
this.month = month;
}
var child = new Parent('Ann');
console.log(child.month); // Ann
console.log(child.father); // undefined
catchtap 组织小程序冒泡事件
1、var可以重复声明变量,第二次赋值会覆盖第一次的值,let无法重复声明,会报错
2var和let声明变量未定义打印都是untif
3、var是函数作用域,let是块级作用域
4、var会提升变量,let不会
5、conts定义常量无法修改,定义对象可以修改
事件循环,异步操作的原理
自我理解:js是单线程,当出现多个任务的时候,可能因为某一个任务阻塞,导致代码无法执行,出现一个假死的状态,无法响应给用户,而eveent-loop就是处理这种阻塞行为,变成非阻塞,它会先执行主线程任务,也就是我们所谓的同步,将异步行为放入到队列中,也就是任务对列,它会等主线程执行完毕之后,再去任务队列里面循环读取任务。
指当一块内存不再被应用程序使用的时候,由于某种原因,这块内存没有返还给操作系统或者内存池的现象
都无法被服务端获取,都无法设置日期
代码量、数据量
vuex
computed名称不能与data 里对象重复,只能用同步,必须有return;是多个值变化引起一个值变化,是多对一.
watch:名称必须和data里对象- -样,可以用于 异步,没有return;是一对多,监听一-个值,一个值变化引起多个值变化。
重绘一定会触发重排,重排不一定会触发重绘。
浅拷贝只是增加了一个指针指向已存在的内存地址,仅仅是指向被复制的内存地址,如果原地址发生改变,那么浅复制出来的对象也会相应的改变。深拷贝是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存。”
深拷贝 json.stringify、手写循环递归、_.cloneDeep()后再JSON(如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式,而不是对象的形式)
浅拷贝 object.assion({},list) 、Array.prototype.slice()、拓展运算符实现的复制,如果只有一级属性就是深拷贝,如果有两级是浅拷贝
会,因为在直接赋值的时候,它是一个浅拷贝,它的指针还是指向了原来的内存空间,当我们给这个对象用扩展运算符进行展开,并赋给另外一个值,就可以避免。
原始数据类型分为null,string等等,引用数据类型分为对象,函数,数组
区别:原始数据类型的值是存在于栈内存中,引用数据类型是存在于堆中,因为它的数据大小是大小不固定,所占空间大
function unique(arr) {
const res = new Map();
return arr.filter((a) => !res.has(a) && res.set(a, 1))
}
var obj = {};
var initValue = 'hello';
Object.defineProperty(obj,"newKey",{ get:function (){ //当获取值的时候触发的函数 return initValue; },
set:function (value){ //当设置值的时候触发的函数,设置的新值通过参数value拿到 initValue = value; } });
//获取值 console.log( obj.newKey ); //hello
//设置值
obj.newKey = 'change value'; console.log( obj.newKey ); //change value
简单写法
let a = 3
const b = ()=>{
Console.log(a)
}
困难写法
function foo(){
var local = 1
function bar(){
local++
return local
}
return bar
}
var div = document.createElement("div");//先创建元素
div.id="mydiv";//或者div.setAttribute("id","mydiv");//给元素绑定id
document.body.appendChild(div);//插入到body里面去
按钮点击先判断节点是否存在,不存在就创建,如何存在,我就动态修改它的显示与隐藏,如何不存在我就创建一个元素,再绑定一个id,并赋予值
改变某个类、某个方法的运行环境
call、bind将参数以逗号的方式分割传入,apply直接传入数据
call、bind唯一的区别,bind返回的是一个函数,实际过程中,bind不推荐使用,消耗性能
消耗性能内存
强缓存和协商缓存
强缓存 直接从缓存取出 express
协商缓存 由服务器告诉浏览器缓存是否可用 etag
1、exports只能使用.语法向外暴露内部变量 例 exports.xxx=xxx
2、module.exports既可以通过点语法,也可以直接赋值一个对象 例 module.exports.xxx=xxx
3、exports = module.exports = {};
4、如果给exports 和 module.exports直接复制,则会指向新的内存,切断两者之间的联系
Nodejs是服务器端的一门技术。它是基于Google V8 JavaScript引擎而开发的。用来开发可扩展的服务端程序。
nodejs会让我们的编程工作变得简单,它主要包含如下几点几个好处:
执行快速、永远不会阻滞、JavaScript是通用的编程语言、异步处理机制
回调地狱是由嵌套的回调函数导致的。这样的机制会导致有些函数无法到达,并且很难维护。
回调函数是指用一个函数作为参数传入另一个函数,这个函数会被在某个时机调用。
callback是作为参数传入另一个函数,另一个函数相当于获取了callback这个的值,而return是直接指向了他的调用者,获取的结果同样给了调用者
错误优先的回调函数用于传递错误和数据。第一个参数始终应该是一个错误对象, 用于检查程序是否发生了错误。其余的参数用于传递数据
使用Promises
运算错误并不是bug,这是和系统相关的问题,例如请求超时或者硬件故障。而程序员错误就是所谓的bug。
Stub是用于模拟一个组件或模块的函数或程序。在测试用例中, 简单的说,你可以用Stub去模拟一个方法,从而避免调用真实的方法, 使用Stub你还可以返回虚构的结果。你可以配合断言使用Stub。
Stream 流是从源读取或写入数据并将其传输到连续流目标的管道
1.Node还没有简单易用的多核计算接口。Cluster并不是那么好用。
2.Node的单核效率虽然比传统脚本语言高,但是和C、C++、Java比并没有优势。
req:全称request请求对象
res:全称 response响应对象
当前文件所在目录
当前文件路径
关系型数据库和对象之间作一个映射,这样,我们在具体的操作数据库的时候,就不需要再去和复杂的SQL语句打交道,只要像平时操作对象一样操作它就可以了 。
import和require都是被模块化所使用
2、require是运行时调用,可以运用在代码的任何地方,require可以理解为一个全局方法,import是编译时调用,只能放在文件开头xxxxxxxxxx import和require都是被模块化所使用2、require是运行时调用,可以运用在代码的任何地方,require可以理解为一个全局方法,import是编译时调用,只能放在文件开头vuex
连接成功 接收数据 失败连接 关闭连接
201
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。