是有疑问的

77 阅读8分钟
异步任务只是让你稍后再做 并没有别的意思
同步任务是在主线程的都叫同步任务 一开始主线程空 大家都是异步任务
异步任务又分为宏任务微任务
主线程就是做事的那一个人 所以当他空了才会再来异步任务去执行
要理解的去看 而不是死记硬背 明白原理 慢慢的读出来 

说出来很快只是背下来肌肉记忆并不会理解这样不好 慢慢的读 然后理解 看东西不要太快的读 那是背 肌肉记忆而已对我们脑子没有帮助 要思考 脑子去想 去想刚刚的车牌号这种的 必须锻炼脑子
看完之后自己嘴巴复述下来 而且脑子去思考而不是只有嘴巴去出声音
自己说话有条理精炼 不要嗯 啊 嗯 停顿 可以慢慢的说不需要很快 不然面试官也听不清 但是必须有条理 不要停顿 慢慢的娓娓道来 说话不要太快 思考
 
数学建模:
https://www.jianshu.com/p/a35ba96d852b

按钮固定在页面底部遮住页面显示内容问题
在class为list的view下面写一个透明view,设置这个view的宽和高

不想不能改变的事情就不要去胡思乱想 没有任何意义
该学的时候学 改玩的时候玩
学的时候不要想任何东西了 专注当下

自己写东西太慢了 。。。。
加油吧 

flex设置之后他的子盒子的float clear vertical-align都会失效

flex-direction=
space-betwwen是没有空隙直接贴死 一个挨着一个的
flex-wrap
align-content

function _new(){
    let obj={}
    let [Con,...args]=arguments
    obj.__proto__=Con.prototype
    let res=Con.apply(obj,args)
    return res instanceof Object?res:obj

}
let key of object.keys(obj)
hasOwnProperty(key)
Object.assign(obj,{})

parse的时候遇到function undefined symbol date会自动省略
遇到正则返回空对象

Object.entries()
function clone(obj){
    let ans={}
    for(let key of Object.keys(obj)){
        ans[key]=obj[key]
    }
    for(let key in obj){
        if(obj.hasOwnProperty(key)){
            ans[key]=obj[key]
        }
    }
    for(let [key,val] of Object.entries(obj)){
        ans[key]=value
    }
}
Object.assign(obj,{})

function deepClone(obj){
    if(!obj||typeof obj!='object')return obj
    //function object 
    if(obj instanceof RegExp)return new RegExp(obj)
    let ans=new obj.constructor
    for(let key in obj){
        if(obj.hasOwnProperty(key)){
            ans[key]=deepClone(obj[key])
        }
    }
    return ans
}

防抖 重新点击了之后再重新运行 不点了三秒才运行完
function f(delay,fn){
    let timer=null;
    return function(){
        if(timer){
            clearTimeout(timer)
        }
        timer=setTimeout(fn,delay);
    }
}

节流 几秒内只可以一次

function f(delay,fn){
    let timer=false
    return function(){
      if(!timer){
          timer=true
          setTimeout(()=>{
              fn();
              timer=false
          },delay)
      }
    }
}

var xhr=new XMLHttpRequest()
xhr.open('get',url,true)
xhr.send(null)
xhr.onreadystatechange=function(){
    if(xhr.readyState==4){
        if(xhr.status>=200&&xhr.status<300||xhr.status==304){
            console.log(xhr.responseText)
        }else{
            throw new Error('error')
        }
    }
}

function Ajax(){
    let handleAjax=function(resolve,reject){
        if((this.status>=200&&......)){
            resolve(this.response)
        }
    }
}

// 三栏布局
浮动
绝对定位
flexbox
表格
网格

 // scrollY是返回文档当前垂直滚动的像素数

<!-- 页可见区域宽: document.body.clientWidth;
网页可见区域高: document.body.clientHeight;

window.innerHeight;
网页可见区域宽: document.body.offsetWidth   (包括边线的宽);
网页可见区域高: document.body.offsetHeight (包括边线的宽);
网页正文全文宽: document.body.scrollWidth;
网页正文全文高: document.body.scrollHeight;
网页被卷去的高: document.body.scrollTop;
网页被卷去的左: document.body.scrollLeft;
网页正文部分上: window.screenTop;
网页正文部分左: window.screenLeft;
屏幕分辨率的高: window.screen.height;
屏幕分辨率的宽: window.screen.width;

屏幕可用工作区高度: window.screen.availHeight; -->

一个事件可以有多个事件监听者

ts是js的一个超集

先确定后端端口以及开启起来了
跨域最好的方法是在后端解决当然前端可以解决

判断懒加载时机:
判断滚动条是否触底 然后懒加载

没有数据了之后
比如到第六页就没有数据了 那他一直请求多尴尬

cookie是存在请求头部的
不在url中 服务端能拿到cookie 

服务端不存cookie的但是知道cookie怎么来
保存在服务端的cookie叫session

localstorage 永久有效,除非代码清除或者手动在浏览器里清除。

Cache-Control:max-age=3600
s
过期时长来控制缓存 
Cache-Control:public private no-cache no-store s-maxage
private no-cache no-store s-maxage 
cache-control no-cache no-store 

window document html body
window是bom核心对象他一方面用来获取或设置浏览器的属性和行为
另一方面作为一个全局对象
document对象是一个跟文档相关的对象
true是捕获 false是冒泡
customEvent
let event=new Event()
let event=new Event("event_name")
let f=new CustomEvent("name",{
   details:{
    }
})
document.createEvent("customEvent")
myEvent.initEvent()
createEvent('customEvent')
preventDefault()

onblur
onfocus
onmouseenter
onmouseleave

enter leave

function new(fn,...args){
   let instance=Object.create(fn.prototype)
   let result=fn.call(instance,...args)
   return typeof result=='object'?result:instance


疑问

js高频算法题 防抖节流会写实例
自己说话要有条理性
react node什么的知道一点

多敲几遍 打印出来什么的 多看看就会了 第一遍第二遍不会正常
宏任务 运行完会看一眼微任务列表 全部清空了才可以
http1.1扩充了4xx的一些状态码

vue2和vue3的差别 具体diff算法 
牛客学会用
一些面经的细碎的点 会

自己要勤搜
方法名 samesite什么的 自己熟悉
唉 面经面经啊

五色筛子
css

微信小程序的原理 uniapp原理什么的
常见面试题
 跨域??、、、?、
 /* 
    还有一种网格布局
    grid-template-rows:100px;
    grid-template-columns:200px auto 200px;
    */
    html{
        box-sizing: content-box;
        /* border-box包含边框和内边距和内容  不包含外边距 博客说错了hh */
    }
 
// 微任务包括:fetch v8的垃圾回收过程 processwx.nextTick

// 还可以用array.includes(arr[i]); 数组是否包含某个值 true or false
// Window.onhashchange=function(event){
//     let hash=location.hash.slice(1);
// }
// 数组去重
function unique(arr){
    return Array.from(new Set(arr));
    // 无法去掉空对象
}
// Array.from()方法就是将一个类数组对象或者可遍历对象转换成一个真正的数组。

this就是对于函数而言指向最后调用函数的那个对象
是函数运行时内部自动生成的一个内部对象,只能在函数内部使用,对于全局来说this指向window

loader是一个转换器 只专注于转换文件这一个领域
plugin跨站器 不局限与打包,资源的加载 还有其他的功能

http的责任是去定义数据

var a=[];
for(let i=0;i<10;i++){
    a[i]=function(){
        console.log(i);
    };
}
a[6]();

js中每次for循环都创建一个新的i变量

// compose函数
function compose(fnList){
    return (...args)=>{
        let len=fnList.length;
        if(len==0)return args;
        if(len==1)return fnList[0](...args);
        return fnList.reduce((x,y)=>{
            return typeof x=='function' ?y(x(...args)):y(x);
        })
    }
}

 // Array.from()方法就是将一个类数组对象或者可遍历对象转换成一个真正的数组。
  
// 创建自定义事件
    let myEvent =new Event('event_name');
    let myEvent1=new CustomEvent('event_name',{
        detail:{

        }
    });
    let myEvent2=new CustomEvent('event_name',{
        detail:{
            name:'zxm',
            age:3,
            sex:'girl'
        }
    });
    let myEvent3=document.createEvent('CustomEvent');
    myEvent3.initEvent(
        // 1.event_name事件名称
        // 2.canBubble是否冒泡
        // cancelable是否可以取消默认行为
        'CustomEvent',true,false
    );
    // 举个栗子
    var dom=document.querySelector('#id');
    // document.querySelector('#id')
    document.addEventListener('alert',function(event){
        console.log(event)
    },false);
    var evt=document.createEvent('HTMLEvents');
    evt.initEvent('alert',false,false);
    dom.dispatcherEvent(evt);
    
    window.dispatchEvent(new Event('resize'));
    var event=new CustomEvent("cat",{
        "detail":{
            name:'xx'
        }
    });

    // 事件的监听
    button.addEventListener('event_name',function(e){

    });
    // 自定义事件的名称和自定义事件的对象不同 而触发时的参数是自定义事件的对象
    let btn=document.createEvent('hhh');
    btn.initEvent('hhh',false,false);
    let a=document.getElementByTagName('button')[0];
    a.addEventListener('btn',function(e){

    });
    setTimeout(()=>{
        a.dispatchEvent(btn)
    },2000);
    // 冒泡和捕获
    window.addEventListener('click',function(e){
        console.log('window')
    });
    document.addEventListener('click',function(e){
        console.log('document')
    });
    // addEventListener有三个参数 1.是字符串指定事件名且不可以使用on前缀,默认是有很多html dom 事件的
    // 2.是事件触发时执行的函数 3.可选布尔值 指定此触发事件是否在捕获或冒泡阶段执行
    // 冒泡的顺序是:button->li->ul->document->window 捕获反过来
    // 不是所有事件都有冒泡 一下就没有 onblur失去焦点onfocus onmouseenter 事件在鼠标指针移动到元素上时触发  onmouseleave

    // 手写new
    function myNew(fn,...args){
        let instance=Object.create(fn.prototype);
        let result=fn.call(instance,...args);
        return typeof resultr==='object'?result:instance;

    }
    let a=new F(1,2);
    // args 将一个不定数量的参数表示为一个数组。(也叫做剩余参数)
    function f(...[a,b,c]){
        return a+b+c;
    }
    f(1,2,3);
    // 剩余参数被解构成 abc
    // Object.create(proto,[propertiesObject])
    // 1.参数必须是新建对象的原型对象,该参数可以是null,对象,函数的prototype属性
    // 2.参数可选 添加到新创建对象的可枚举属性(是放在实例上的)   此函数返回在指定原型对象上添加新属性后的对象
    Object.assign()
    // 第一个参数是目标对象 后面参数是源对象 他会将源对象的所有可枚举属性复制到目标对象上
    // 且这是浅拷贝 有很多局限吧但是也有一些用途  https://www.jianshu.com/p/d5f572dd3776
   
    console.log(typeof null==='object');true
   
    function A(name){  this.name = name; 
    this.fun = function(){  return this;  }  
    return '11';//注释掉后结果为underfine,一般在函数的new的过程中js内部会自动返回创建好的对象,所以那时的结果为返回的对象  }  var str = new String('sss');  var re = A.call(str,'cat');  console.log(re);//结果为11;
   //正常规定,如何fn返回的是null或undefined(也就是不返回内容),我们返回的是obj,否则返回rel
    }
    function newMy(fn,...args){
        let ans=Object.create(fn.prototype);
        let ans2=fn.apply(ans,args);
        return typeof ans2==='object'?ans2:ans;

    }
    let a=newMy(Object,1,2,3);
    //typeof除了null会显示object其他都会正常显示 比如说function也会有and object
    // 手写实现instanceof
    function myInstanceof(left,right){
        let proto=Object.getPrototypeOf(left);//用于获取指定对象的原型对象
        while(true){
            if(proto==null){
                return false;
            }
            // ??why null==null
            if(proto==right.prototype)return true;
            proto=Object.getPrototypeOf(proto);
        }
    }
 
new Promise((resolve,rejected)=>{
    resolve(value)
})
class Promise{
    constructor(executor){
        this.state='pending'
        this.value=undefined
        this.reason=undefined
        let resolve=value=>{
            if(this.state=='pending'){
                this.state='fulfilled'
                this.value=value
            }
        }
        let reject=reason=>{
            if(this.state=='pending'){
                this.state='rejected'
                this.reason=reason
            }
        }
        try{
            executor(resolve,reject)
        }catch(error){
            reject(error)
        }
    }
    then(onFulfilled,obRejected){
        if(this.state=='fulfilled'){
            onFulfilled(THIS.value)
        }
        if(this.state=='rejected'){
            obRejected(this.reason)
        }
    }
    catch(fn){
        return this.then(null,fn)
    }
}
Promise.resolve=function(val){
    return new Promise((resolve,reject)=>{
        resolve(val)
    })
}
Promise.race=function(promises){
    return new Promise((resolve,reject)=>{
        for(let i=0;i<promises.length;i++){
            promises[i].then(resolve,reject)
        }
    })
}
Promise.all=function(promises){
    let arr=[]
    let i=0
    function processData(index,data){
        arr[i]=data
        i++
        if(i==promises.length){
            resolve(arr)
        }
    }
    return new Promise((resolve,reject)=>{
        for(let i=0;i<promises.length;i++){
            promises[i].then(data=>{
                processData(i,data)
            },reject)
            // 只是定义了promise执行成功之后会执行的then方法因为是异步的所以并不会立即执行

        }
    })
}

function vue(){
    this.$data={a:1}
    this.el=document.getElementById('app')
    this.virtualdom=''
    this.observer(this.$data)
    this.render()
}
vue.prototype.observer=function(obj){
    let value
    let self=this
    for(let key in obj){
        value=obj[key]
        if(typeof value ==='object'){
            this.observer(value)
        }else{
            Object.defineProperty(this.$data,key,{
                get:function(){
                    return value
                },
                set:function(newVal){
                    value=newVal
                    self.render()
                }
            })
        }
    }
}
vue.prototype.render=function(){
    this.virtualdom='hello'+this.$data.a
    this.el.innerHTML=this.virtualdom
}

function vue(){
    let data={a:1}
    let el=document.getElementById('app')
    let virdom=''
    this.watcher(this.data)
    this.render()
}
vue.prototype.watcher=function(obj){
    let val
    for(let key in obj){
    if(typeof obj== 'object'){
        this.watcher(key)
    }else{
        Object.defineProperty(obj,key,{
            get:function(){
                return obj[key]
            },
            set:function(newVal){
                obj[key]=newVal
                this.render()
            }
        })
    }

}
}
vue.prototype.render=function(){
    this.virtualdom=this.data.a+''
    this.el.innerHTML=this.virtualdom
}

(function(){
    function sizeChange(){
        let html=document.documentElement
        html.style.fontSize=html.getBoundingClientRect().width/20+'px'

    }
    window.addEventListener('resize',sizeChange)
    sizeChange()
})()
function(){
    let html=docuemn.documentElement
    function onWindowResize(){
        let width=html.getBoundingClientRect().width/20+'px'
        html.style.fontSize=width
    }
    window.addEventListener('resize',onWindowResize)
    onWindowResize()
}

1rem=16px

event.currenetTarget

class f{
    constructor(){
        this.name=''
    }
}
class c{
    constructor(){
        this.__proto__=f.prototype
    }
}
let c1=new c()
c1.apply(f)

1.实现双向绑定原理vue

function vue(){
    let el=document.getElementById('app')
    let data={a:1}
    let virdom=""
    this.observer(this.data)
    this.render()
}
vue.prototype.observer=function(obj){
    let value
    let self=this
    for(key in obj){
        if(typeof obj[key]=='object'){
            this.observer(obj[key])
        }else{
            Object.defineProperty(obj,key,{
                set:function(newVal){
                  obj[key]=newVal
                  self.render()
                },
                get:function(){
                    return obj[key]
                }
            })
        }
    }
}
vue.prototype.render=function(){
    this.virdom=this.data.a
    this.el.innerHTML=this.virdom
}

let vue=new vue()
setTimeout(function(){
    vue.data.a=2
},2)

vue3

function vue(){
    this.$data={a:1}
    this.el=document.getElementById('app')
    this.virdom=''
    this.observer(this.$data)
    this.render()
}
vue.prototype.observer=function(obj){
    let self=this
    this.$data=new Proxy(this.$data,{
        get(target,key){
            return target[key]
        },
        set(target,key,value){
            target[key]=value
            self.render()
        }
    })
}

 .box{
        height: 100px;
        width: 100px;
        border-radius: 0.5;
        animation: lalala 2s linear infinite;
    }
    @keyframes lalala{
        from{
            transform: rotate(0deg)
        }
        to{
            transform: rotate(60deg)
        }
    }
    
 .box{
        height: 100px;
        width: 100px;
        border-radius: 0.5;
        animation: lalala 2s linear infinite;
    }
    @keyframes lalala{
        from{
            transform: rotate(0deg)
        }
        to{
            transform: rotate(60deg)
        }
    }