xlearns / myblog

1 stars 0 forks source link

读书

高级函数【基础为函数是一等公民first classs】

可以把函数当参数也可以当返回值

高级函数的意义

扩展trim函数

//trim
function trim(string,option){
    option = option||{
        start:false,
        end:false,
        chars:'',
    } 
    if(typeof option!='object'||option==null){
        throw new Error('option must object')
    }
    if(!string){
        return string || ''
    }
    if(option.start){
        return string.replace(/^\s+/mg,'')
    }else if(option.end){
        return string.replace(/\s+$/mg,'')
    }else if(option&&!option.start&&!option.end&&option.chars){
        return string.trim().split(option.chars).filter(v=>v!='').toString() 
    }else{
        return string.trim()
    }
}
console.log(trim(' 😀abc😀  ',{chars:'😀'}))

实现lodash zip函数

//zip
function zip(...args){
    let result = []
    args.forEach((v)=>{
            v.forEach((vv,index)=>{
                //初始化
                result[index] = result[index]||[]
                result[index].push(vv)
            })
    })
    return result
}
console.log(zip(['a', 'b','c'], [1, 2,3], [true, false],['哈哈', 'dj'],['name','ss','sss','ssss','sssss']))

实现slice函数

function mySlice(array,start,end){
    let length = array == null ? 0:array.length
    if(!length)[]
    //初始化
    start = start == null ? 0 : start
    end = end === undefined ? length : end
    if(start<0){
        start = -start > length ? 0 : (length + start)
    }
    end = end>length?length:end;
    if(end<0){
        end +=length
    }
    length = start > end ? 0 : ~~(end - start)
    start = ~~start
    //重0开始
    let index = -1
    const result = new Array(length)
    while (++index < length) {
        result[index] = array[index + start]
    }
    return result
}
var test = [1,2,3,4,5]
console.log(mySlice(test,2))

实现forEach函数

Array.prototype.myForEach=function(fn,_this){
  let arr = this;
  _this = _this?_this:window
  for(let i=0;i<arr.length;i++){
      fn.appley_this,[arr[i],i,arr])
  }
}

实现filter函数

Array.prototype.myFilter=function(fn,_this){
  let arr = this;
  let res = []
   _this = _this?_this:window
  for(let i=0;i<arr.length;i++){
     if(fn.apply(_this,[arr[i],i,arr])){
       res.push(arr[i])
     }
  }
  return res
}

实现reduce函数

Array.prototype.myReduce=function(fn,init,_this){
  let arr = this;
    init = init?init:0
   _this = _this?_this:window
   for(let i=0;i<arr.length;i++){
     init = fn.apply(_this,[init,arr[i],i,arr])
   }
   return init
}

实现once函数

function once(fn,_this){
  _this = _this?_this:window;
  let isRun = false
  return function(){
    if(!isRun){
    isRun = true
    return fn.apply(_this,arguments)
    }
  }
}

实现map函数

Array.prototype.myMap=function(fn,_this){
  let arr = this
  _this = _this?_this:window
  let res = []
  for(let i=0;i<arr.length;i++){
    res.push(fn.apply(_this,[arr[i],i,arr]))
  }
  return res
}

实现every函数

Array.prototype.myEvery=function(fn,_this){
 let arr = this
  _this = _this?_this:window
  let res = true
  for(let i=0;i<arr.length;i++){
    if(!fn.apply(_this,[arr[i],i,arr])){
      res = false
    }
  }
  return res
}

实现some函数

Array.prototype.mySome=function(fn,_this){
 let arr = this
  _this = _this?_this:window
    let res = false
  for(let i=0;i<arr.length;i++){
    if(fn.apply(_this,[arr[i],i,arr])){
      res = true
    }
  }
  return res
}

闭包

纯函数

 ## lodash 【纯函数】
 - 安装
    - 初始化package.json `npm init -y`
    - 安装 `npm install lodash`
 - 常用方法:last、first、toUpper、reverse、each、includes、find、findIndex
 - 函数柯里化:curry
 - 函数组合:flow、flowRight
```js
const _  = require('lodash')
//功能函数
const reverse = arr=>arr.reverse()
const first = arr=>arr[0]
const toUpper = arr=>arr.toUpperCase()

//组合
const f = _flowRight(toUpper,first,reverse)
//测试
console.log(f(['one','two','three']))

//简单写法
const f = _flowRight(_.toUpper,_.first,_.reverse)
console.log(f(['one','two','three']))

//满足结合律 
const f = _flowRight(_flowRight(_.toUpper,_.first),_.reverse)
console.log(f(['one','two','three']))

实现lodash的组合函数源码

function flow(...fns){ return function(value){ return fns.reduce((pre,cur)=>{ //上一个值是当前值的参数 return cur(pre) },value) } }

//测试

//功能函数 const reverse = arr=>arr.reverse() const first = arr=>arr[0] const toUpper = arr=>arr.toUpperCase()

//组合 const f = flowRight(toUpper,first,reverse) //结果 console.log(f(['one','two','three']))


## vue router实现原理

# 拉钩vue3 源码
- vue  = 响应式 + 模板解析 + 虚拟DOM + 组件
## vue2.x在created和data声明数据的区别?
- `唯一区别为在created声明的变量不会被挂载Object.defineProperty也就是不是响应式,在一些不需要响应式的数据就可以写在created中`
## vue3.x优化
- 体积变小,引入tree shaking通过在编译阶段做静态分析,找到没有引入的模块打上标记,包体积越小,意味着网络传输时间越短,js引擎解析包的速度也越快
- 数据劫持,vue2.x采用的是Object.defineProperty则就会存在问题,拦截不了对象属性的添加和删除,虽然vue2.x为了解决问题提供了$set、$delete方法,其实,对于层级比较浅的对象,Object.defineProperty的速度是比proxy要快的,但是Odp对嵌套层级比较深的对象,需要递归便利这个对象,执行Object.defineProperty把每一层对象都变成响应式。这样就会造成相当大的内存负担。但是proxy其实也监听不到内部深层次对象的变化,不过vue3.x采用在getter中去递归响应式,这样的好处是只有真正访问到的内部才会变成响应式,而不是像2.x一样无脑递归。
- 编译优化
    - vue2.x:从new Vue->渲染成DOM的流程为:`1.new Vue 2. init 3. $mount 4. compile 5. render 6. vnode 7 patch 8 DOM`其中响应式就发生在init阶段
    - 
- API优化:composition API 
   - vue2.x 为option
   - 改完类似reacthooks
## reactive、computed、effect
```js
let config = {
    get(obj,key){
        const res = Reflect.get(obj,key)
        track(obj,key)
        return typeof res =='object' ?reactive(res):res;
    },
    set(obj,key,value){
        let inof = {oldValue:Reflect.get(obj,key),newValue:value}
        Reflect.set(obj,key,value)
        trigger(obj,key,inof)
    }
}

function reactive(obj){
    return new Proxy(obj,config)
}

// effect
let stackEffect = []
// dep
let weakmap = new WeakMap()

function track(obj,key){
    let depsMap = weakmap.get(obj)
    let effect = stackEffect[stackEffect.length - 1]
    if(!effect)return
    if(!depsMap){
        depsMap = new Map()
        weakmap.set(obj,depsMap)
    }
    let deps = depsMap.get(key)
    if(!deps){
        deps = new Set()
        depsMap.set(key,deps)
    }
    if(!deps.has(effect)){
        deps.add(effect)
        effect.deps.push(effect)
    }
}

function trigger(obj,key,value){
    let depsMap = weakmap.get(obj)
    let effects = new Set()
    let computed = new Set()
    if(key){
        let deps = depsMap.get(key)
        deps.forEach(effect=>{
            if(effect.computed){
                computeds.add(effect)
            }else{
                effects.add(effect)
            }
        })
    }
    effects.forEach((effect)=>effect())
    computed.forEach((effect)=>effect())
}

function effect(fn,op={}){
    let o = createEffect(fn,op)
    if(!o.lazy){
        o()
    }else{
        return o
    }
}
function createEffect(fn,op){
    const effect = function(...args){
        return run(effect,fn,args)
    }
    effect.lazy = op.lazy
    effect.computed = op.computed
    effect.deps = []
    return effect
}
function run(effect,fn,ages){
    if(stackEffect.indexOf(effect)==-1){
        try{    
            stackEffect.push(effect)
            return fn(ages) 
        }finally{
            stackEffect.pop()
        }
    }
}
function computed(fn){
    const runner = effect(fn,{lazy:true,compued:true})
    return {
        effect:runner,
        get value(){
            return runner()
        }
    }
}

js基本数据类型如何判断

如何理解html语义化

什么是BFC

响应式布局

如何实现居中

Symbol

this指向

闭包

reduce实现

compose实现

apply、bind、call实现

new实现

继承

class继承与原型继承区别

宏任务 微任务

setTImeout与requestAnmationframe区别

try{}catch{}、onerror、addEventListener('error')、unhandlerrejection

promise异常

promise 异步实现

promise穿透实现

promise then链式调用实现

promise静态方法实现

为什么给对象添加的方法能用在基本类型上?

说一下http与https

Tcp三次握手

TCP和UDP区别

WebSocket的实现和应用

http请求的方式、head方式

一个图片URL访问后直接下载怎样实现?

说一下webQuality

说一下HTML5 drag api

说一下http2.0

补充400、401、403状态码

fetch发送两次请求的原因

Cookie、sessionStorage、localStorage区别

说一下Web worker

对html语义化的理解

iframe是什么?有什么缺点

Doctype作用?严格模式与混杂模式如何区分?它们有何意义

Cookie如何防范xss

Cookie和Seesion区别

概括RESTFUL

viewport和移动端布局

click在ios有300ms延迟原因和如何解决

AddEventListener参数

http常用请求头

强、协商缓存

304

强、协商缓存什么时候用那个

前端优化

GET与POST区别

301与302区别

如何画一个三角形

说一下浏览器缓存

HTML5新增元素

在地址栏输入一个url,到这个页面呈现,中间会发生什么

cache-control的值有哪些

浏览器在生成页面的时候,会生成那两颗树

那些请求头跟缓存相关

css盒模型

画一条0.5的线

link与import标签的区别

transition和animation的区别

flex布局

BFC

垂直居中的方法

js动画和css3动画的差异性

块、行元素

多行元素的文本省略号

外边距折叠

清除浮动

怎样让一个元素消失

三栏布局的实现方式

calc

display:table和本身table有何区别

如果想要改变一个dom的字体颜色,不在它本身进行操作

line-height与height区别

设置一个元素的背景,背景颜色会填充那些区域

属性选择器与伪类选择器的优先级

为什么img是inline还可以设置宽高

重绘重排

CSS正方形

overflow原理

box-sizing基本用法

flex布局