JS label JS标记语法
栈内存和堆内存
-
栈:一级缓存
先进后出多的的数据结构,由操作系统自动分配释放,存放函数的参数值和局部变量 栈调用时是处在存储空间的,调用完成之后立即被释放,占内存的更新速度快,因为局部函数的生命周期短 -
堆:二级缓存 —— 存储的是实体对象
由程序员分配释放,程序员不释放就等着垃圾回收机制回收,分配方式类似与链表 生命周期由虚拟机的垃圾回收算法来决定(并不是孤儿对象就会回收),所以调用这些对象的速度要慢一些
vue2和vue3
- 打包体积减小41%
- 初始渲染加快55%,DOM更新加快133%
- 内存减小54% vue创建和挂载
-
vue2
vue create 名字 -
vue3 —— 虚拟DOM重写利用了tree-shanking
1. vue create 名字 2. npm init vite-app 名字 -
$nexttick
由于Vue DOM更新是异步,修改数据时,视图不会立即更新,而是会监听数据变化,并缓存在同一事件循环中,等同一数据循环中的所有数据变化完成之后,再统一进行视图更新。为了确保得到更新后的DOM,所以设置了 Vue.nextTick()方法。 此时通过 Vue.nextTick 获取到改变后的 DOM,created 和 mounted 阶段,如果需要操作渲染后的视图,也要使用 nextTick 方法。
script标签中defer和async区别
import和link引入区别
适配:viewport、rem、vw
点击穿透
HTTP和HTTPS区别
-
http:超文本传输协议 —— 3个数据包
1. 默认端口:80 2. 速度快,安全性低 -
https:超文本安全传输协议(SSL/TLS)—— 一共12个数据包
1. 默认端口:443 2. 数据加密,安全性高,但是数据传输慢,更消耗资源 3. SSL安全加密隧道协商完成 —— 客户端和服务端每次都会交换3个数据包
为什么三次握手和四次挥手 —— TCP协议是全双工通讯(双方都可以发送消息)
-
三次握手 —— 建立连接,等到应答(只是服务端的回应合并了变成了三次)
1. 第一次:客户端向服务端发送请求,建立连接 2. 第二次:服务端接收到客户端的请求链接,并向客户端回应 3. 第三次:客户端回应服务端的应答,建立连接,开始请求处理 二次握手缺点:服务端不能确定客户端是否接收到应答,客户端可以随时向服务端发送消息,但是服务端不知道客户端准备好了没有,不敢轻易发送消息,就违背了全双工通讯的定义 -
四次挥手 —— 关闭连接,等到应答(一应一答)
1. 第一次:客户端停止工作,向服务端发送消息,释放连接 2. 第二次:服务端接收到客户端的消息,先向客户端回应 3. 第三次:消息处理完成之后,请求时放链接 4. 第四次:回应服务端,连接释放 能不能是三次挥手:不能,客户端完成不能保证服务端也完成,要等到自己的消息发送完成之后,再去请求释放连接,不能合并为一次
GET和POST
-
区别:本身的区别并没有,都是基于http的请求方法,区别是浏览器商家去定义上去的
-
GET:—— 产生一个TCP数据包(同时发送)
1. get是从服务端获取数据 2. 通过URL地址栏传输,明文,安全性比较低 3. get传输的数据量比较小不能 > 2KB, 4. get回退是无害的 5. get会被浏览器主动cache,请求参数会被完整保存在历史记录里,post不会 6. 在网络差的情况下,一次和两次时间要多消耗一点,但是数据完整性好 7. get只能url编码,post可以多种编码方式 -
POST:—— 产生两个TCP数据包(Firefox是一个除外,浏览器先发header,服务器响应之后再发data )
1. 向服务端传递数据 2. 将请求参数放在请求体(request body)里面,安全性较高 3. post的传输的体积要大,默认是不受限制,但一般是 80-100KB, 4. post回退浏览器会再次提交请求, 5. post不会被浏览器主动cache,需手动配置 6. get在url中有长度限制,post没有
三方授权登陆—— github为例
网络安全:CSRF和XXS
websocket
webGIS
Nginx代理
暴露和引入模块
数组方法
节流防抖
原型对象
ES6及以上新特新
Promise
微任务和宏任务
微信小程序
uniapp
react
Nginx代理
6.22
- 熟悉TS的基本类型
number string boolean object unknown any tuple(元组——固定长度的数组) enum(枚举) void never
断言:变量 as 类型
<类型>变量
数组的声明方式:Array<类型> 类型[] —— 什么类型的数组(字符串,数字)
元组: xxx:[变量,变量]
多个属性的对象:[propName:string]:any
-
tsconfig.js配置compilerOptions
-
webpack打包ts
6.23
- 类 —— class:
- 构造函数与this
- constructor和super
- 继承
- 抽象类和抽象方法
1. 抽象类:—— abstract class Person{}
1. 抽象类是专门用来做继承的(extends)
2. 抽象类不能用来创建对象
3. abstract (抽象的)
4. 抽象类中既有抽象方法又有普通方法
2. 抽象方法:—— abstract sayHi():void;
1. 抽象方法只能定义在抽象类中
2. 抽象方法没有方法体
3. 抽象方法在子类中必须进行重写
子类中重写:sayHi(){方法体}
- 接口 —— interface:定义一个类结构 注:
编译之后产生的文件是看不见interface和abstract的
1. 描述一个对象的类型:—— 别名 对象声明
1. 不可以使用同一个别名(如:myType)重复声明
type myType={
name:string,
age:number
}
//用myType对对象做了一个属性限制
const obj:myType={
name:'ts',
age:18
}
2. 接口定义一个类结构:—— 用接口定义类中应该包含哪些属性和方法
1. 也可以当做类型声明来使用
2. 可以使用一个同一个名(如:myInterface)重复声明 —— 就合并属性
interface myInterface{
name:string,
age:number
}
interface myInterface{
sex:string
}
const obj:myInterface={
name:'ts',
age:18,
sex:'男'
}
3. 接口定义类结构:—— 用接口去限制类的结构
1. 接口中的属性都不能有实际的值,方法都是抽象方法
2. 接口只定义结构,不考虑实际值
interface myInterface{
name:string,
sayHi():void;
}
interface myInterface{
sex:string
}
const obj:myInterface={
name:'ts',
age:18,
sex:'男'
}
4. 定义类时:—— 可以使类去实现一个接口
1. 实现接口(implements)就是满足接口的要求
2. 接口只定义结构,不考虑实际值、具体值
interface myInterface{
name:string,
sayHi():void;
}
class MyClass implements myInterface{
name:string;
//初始化数据name,类似react
constructor(name:string){
this.name=name
}
sayHi(){
//方法体;
}
}
const obj:myInterface={
name:'ts',
age:18,
sex:'男'
}
- 属性的封装:在TS中可以再属性前面
添加修饰符来限制操作
属性的封装
1. public:—— 公共属性,默认属性,可以随意修改访问
1. 抽象类是专门用来做继承的(extends)
2. private:—— 私有属性,属性只有在类内部进行访问修改;
1. 在外部访问修改会报错提示,但是在报错仍能编译的情况下依旧会修改,因为这个是TS独有的,在JS中被忽略了 —— 解决:在tsconfig.js中配置"noEmitOnError":true
2. 通过调用类中 实例方法让私有属性可以被外部访问和修改,可以进行数据的合法性,如属性 age > 0
private name:string
private age:number
constructor(name:string,age:number){
this.name=name
this.age=age
}
getName(){
return this.name
}
setName(value:string){
this.name=value
}
3. TS中设置getter/setter方法,外部通过 如:person.name、person.age 访问内部的"_name"、"_age"属性
private _name:string
private _age:number
constructor(name:string,age:number){
this._name=name
this._age=age
}
get name(){
return this._name
}
set name(value:string){
this._name=value
}
get age(){
return this._age
}
set age(value:string){
if(value>0){
this._age=value
}
}
3. protected:—— 受保护的属性,只有在当前类和其子类中访问(修改)
4. readOnly:—— 只读属性
5. 简写
class Person{
//可以直接将属性定义在构造函数中
constructor(public name:string,public age:number){
}
}
const per=new Person('ts',20)
定义类简写形式
- 泛型 —— 定义函数或者类时,如果该遇到类型不明确的就可以使用泛型
1. 直接调用具有泛型的函数
//T表示的泛型
function fn<T>(a:T){
return a;
}
//不指定泛型,TS可以自动对类型进行推断
let res1=fn(a:10)
//指定泛型T为string
let res2=fn<string>(a:'hi')
function fn2<T,K>(a:T,b:K){
return a;
}
let res3=fn(11,'hello')
let res4=fn<number,string>(11,'hi')
2. 泛型和接口
interface Inter{
length:number
}
//泛型要符合Inter接口的类型
function fn3<T extends Inter>(a:T){
return a.length
}
fn3('123')
3. 在类中使用泛型
1. class Person<T>{
name:T;
constructor(name:T){
this.name=name
}
}
2. class Person{
constructor(public name:T){}
}
const person=new Person<string>('ts')
6.24
6.25
6.26
6.27
6.28
阿里金典面试题:—— “==”的运算规则和类型转换
var a=?;
if(a==1 && b==2 && c==3){
console.log(true)
}
a={
n:1,
valueOf:function(){
return this.n++
}
}
类型不同:
1. 一端原始一端对象:对象转为原始类型后比较,先调valueOf,无法转换为原始类型再调toString
2. 两端原始
6.29
- document.querySelector. —— element类型
- document.getElementById() —— HTMLElement类型
-
css的阴影属性问题:
box-shadow —— 针对整个盒子来设置阴影 filter:drop-shadow ——针对区域里面的像素点 -
花样数字:
原始值 输出 0.11 —— 0.11 .11 —— 0.11 11 —— 11 11. —— 11 011 —— 9 //0开头的数字串表示八进制,大于8就会自动转为十进制 080 —— 80 0o11 —— 9 //0o开头的表示八进制,不会转换为十进制 0o80 —— 报错 0b11 —— 3 0x11 —— 17 11.toString —— 报错 11 .toString —— '11' -
JS中无法运算的大数据:—— 不可预测
JS的数字存储 64位的浮点数 符号+指数+尾数 尾数 ——固定位1+ 其他52位 =53位 决定了数字精度,多了不要,少了补0 表示最大数字 —— 2的53次方-1 :也是number的最大安全整数(Number.MAX_SAFE_INTEGER) -
JS中的属性是否存在:
最终方案:既可以找自身属性也可以找原型链上的属性 —— function(obj,key){return key in obj} 1. —— function(obj,key){return obj[key]!==undefined 缺点:当obj的属性中的值如 obj={a:undefined} 时有弊端 2. —— function(obj,key){return Object.keys(obj).includes(key)} 缺点:当遇到不可枚举的属性时 —— Object.defineProperty(obj,'b'{ enumerable:false, value:1 }) Object.keys无法遍历得到属性b 3. —— function(obj,key){return obj.hasOwnProperty(key)} 缺点:只能判断自己身上的属性,不能判断原型链上的属性 —— 例如:toString方法 -
JS中的属性名的类型:—— 阿里金典面试题
var arr=[];arr[1]=1;arr['1']=3;console.log(arr[1]) //结果为3 var a={},b={key:'b'},c={key:'b'};a[b]=123,a[c]=456;console.log(a[b]) //结果为456,b.toString==c.toString==[object Object] 在JS中对象的属性名字只能有两种:string和Symbol,如果不是这两种类型,会自动转换为'字符串' -
JS中的属性是否存在:
box-shadow —— 针对整个盒子来设置阴影 filter:drop-shadow ——针对区域里面的像素点 -
JS中的属性是否存在:
box-shadow —— 针对整个盒子来设置阴影 filter:drop-shadow ——针对区域里面的像素点 -
JS中的属性是否存在:
box-shadow —— 针对整个盒子来设置阴影 filter:drop-shadow ——针对区域里面的像素点
6.30