编译原理
编译型语言
例如Java
编译过程:词法分析->语法分析->语义检查->代码优化和字节码生成。
解释型语言
例如JavaScript
编译过程:词法分析 -> 语法分析 -> 语法树
词法分析
将字符流(char stream)转换为记号流(token stream)
例如:
const add = (a, b) => a + b
经过词法分析会变成
可以使用 esprima.org/demo/parse.… 体验一下
[ { "type": "Keyword", "value": "const" }, { "type": "Identifier", "value": "add" }, { "type": "Punctuator", "value": "=" }, { "type": "Punctuator", "value": "(" }, { "type": "Identifier", "value": "a" }, { "type": "Punctuator", "value": "," }, { "type": "Identifier", "value": "b" }, { "type": "Punctuator", "value": ")" }, { "type": "Punctuator", "value": "=>" }, { "type": "Identifier", "value": "a" }, { "type": "Punctuator", "value": "+" }, { "type": "Identifier", "value": "b" }]
语法分析
Tokens 转化为 AST 语法树
{
"type": "Program",
"body": [
{
"type": "VariableDeclaration",
"declarations": [
{
"type": "VariableDeclarator",
"id": {
"type": "Identifier",
"name": "add"
},
"init": {
"type": "ArrowFunctionExpression",
"id": null,
"params": [
{
"type": "Identifier",
"name": "a"
},
{
"type": "Identifier",
"name": "b"
}
],
"body": {
"type": "BinaryExpression",
"operator": "+",
"left": {
"type": "Identifier",
"name": "a"
},
"right": {
"type": "Identifier",
"name": "b"
}
},
"generator": false,
"expression": true,
"async": false
}
}
],
"kind": "const"
}
],
"sourceType": "script"
}
参考资料
cheogo.github.io/learn-javas… zhuanlan.zhihu.com/p/85915575
webpack 性能优化
www.cnblogs.com/laneyfu/p/6… zhuanlan.zhihu.com/p/25212283
运算符比较
类型相同比较
- 字符串:比较字符串的utf-16编码(通过
charCodeAt进行转换)从字符串中索引1开始比较,如果相等则继续比较第二位,直到比出大小,如果存在其中一个字符串率先比完,还没比出大小,则长度长的较大'aa'>'a' // true 'ab'>'aa' // true - 数字、BigInt:没啥好说的
- 布尔值:记住
ture>false - undefine、null:
undefined===undefined、null ===null,直接相等,怎么比都是false - Symbol:没法比大小
- 对象:先调用对象的
valueOf方法进行比较,如果相等,再调用toString方法进行比较var a = { data: [20, 20], value: 20 } var b = { data: [10, 30], value: 10 } a > b // false a < b // false a.valueOf = function () { return this.value // 20 } b.valueOf = function () { return this.value // 10 } a > b // true a < b // false
不同类型进行比较
如果是不同类型进行比较的话,会先将需要比较的值进行Number()转换,然后再进行比较。
如果经过转化以后的值是NaN的话,就比较不出大小了。除了数字字符串,其他类型经过Number()转化后,大部分都是NaN。下面列出一些特殊情况
console.log(Number('')); // 0
console.log(Number(true)); // 1
console.log(Number(false)); // 0
console.log(Number(null)); // 0
console.log(Number([x])); // x
注意Number只能转化长度为1的数组
思考
所以看完以上的你能否解释一下为什么![]==[]是true
fetch
fetch请求返回的res,主要存在三种方法
- res.text() 解析content-type为text/html类型的数据
- res.json() 解析application/json 类型的数据
- res.blob() 解析application/octet-stream 类型的数据
- res.formDate 解析application/x-www-form-urlencoded 类型的数据
缓存
eTag 默认情况下,Nginx 对于静态资源都会输出Last-Modified,而 ETag、Expire 和 Cache-Control 则需要自己配置:
etag on;
expires max;
etag默认是根据last-modified和content-length计算出来的,当然,你也可以自定etag的计算方式 juejin.cn/post/684490…
图片加载会阻塞dom解析嘛
强缓存
随笔
suspense
responseType:使用xhr请求时,设置对返回数据的解析方式
生命周期
vue
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- beforeDestory
- destoryed
keep-alive组件
- actived
- deactived
react
- desst:当props传值发生变化时触发,组件实例化时也会触发
- componentWillMount(已废弃)
- render
- componentDidMount
- componentWillReceiveProps(已废弃)
- componentShouldUpdate
- componentWillUpdate(已废弃)
- 获取update前后的state和props
- componentDidUpdate
- componentWillUnmount
性能优化
webpack层面
- tree shaking
- code splite+懒加载
- 代码压缩
- prefetch、preload、dns-prefetch
- hash缓存控制
代码层面
- 防抖、节流
- 事件代理
- 图片懒加载
- 减少重绘和回流,尤其是回流
- 减少css选择器嵌套层数
服务器层面
- cdn
- gzip压缩
单点登录实现原理
同域
在某个系统登录后直接将用户登录信息写到该域下的cookie中,其他同域系统请求携带cookie信息,实现单点登录
不同域
- 登录系统A(a.com),发现未登录跳转到sso,并携带backurl=a.com
- sso判断用户是否登陆,发现未登录,引导用户登录。
- 登录成功后再sso域下写入cookie信息,然后跳转到backurl,并携带一个token
- A获取到token,拿着token去sso获取用户信息
- 接着登录B系统(b.com),B发现用户未登录,携带backurl=b.com,跳转到sso
- sso发现用户已经登录过了,直接带着token跳转到B
- 这样B不要登录就获取到了token,实现了不同域的单点登录