今日学习总结

用来写文档

docsify.js.org

刚知道的一个库:

Rxjs

如何解决a标点击后hover事件失效的问题?

改变a标签css属性的排列顺序: link→visited→hover→active
各个阶段的含义:

  1. a:link:未访问时的样式,一般省略成a
  2. a:visited:已经访问后的样式
  3. a:hover:鼠标移上去时的样式
  4. a:active:鼠标按下时的样式

点击一个input依次触发的事件

const text = document.getElementById('text');
text.onclick = function (e) {
  console.log('onclick')
}
text.onfocus = function (e) {
  console.log('onfocus')
}
text.onmousedown = function (e) {
  console.log('onmousedown')
}
text.onmouseenter = function (e) {
  console.log('onmouseenter')
}

//先后顺序
'onmouseenter'
'onmousedown'
'onfocus'
'onclick'

docoment,window,html,body的层级关系

window > document > html > body
  • windowBOM的核心对象,它一方面用来获取或设置浏览器的属性和行为,另一方面作为一个全局对象。
  • document对象是一个跟文档相关的对象,拥有一些操作文档内容的功能。但是地位没有window高。
  • html元素对象和document元素对象是属于html文档的DOM对象,可以认为就是html源代码中那些标签所化成的对象。他们跟divselect什么对象没有根本区别。

有写过原生的自定义事件吗

ps:我还是第一次听说这个。

原生自定义事件有三种写法:

1.使用Event
2.使用customEvent(可以传参数)
3.使用document.createEvent('CustomEvent')initCustomEvent()

事件的监听

button.addEventListener('event_name', function (e) {})

事件的触发

dispatchEvent(myEvent)

注意,这里的参数是要自定义事件的对象(也就是myEvent),而不是自定义事件的名称('myEvent')

示例

// 1.
// let myEvent = new Event('myEvent');
// 2.
// let myEvent = new CustomEvent('myEvent', {
//   detail: {
//     name: 'lindaidai'
//   }
// })
// 3.
let myEvent = document.createEvent('CustomEvent');
myEvent.initEvent('myEvent', true, true)

let btn = document.getElementsByTagName('button')[0]
btn.addEventListener('myEvent', function (e) {
  console.log(e)
  console.log(e.detail)
})
setTimeout(() => {
  btn.dispatchEvent(myEvent)
}, 2000)

所有的事件都有冒泡吗?

并不是所有的事件都有冒泡的,例如以下事件就没有:

  • onblur
  • onfocus
  • onmouseenter
  • onmouseleave

手写实现instanceof

//其实就是一层一层的原型链上面找,直到null为止
function myInstanceof (left, right) {
  //基本数据类型直接返回false
  if(typeof left !== 'object' || left === null) return false;
  let proto = Object.getPrototypeOf(left);
  while (true) {
    if (proto === null) return false;
    if (proto === right.prototype) return true;
    proto = Object.getPrototypeOf(proto)
  }
}

webpack中的loader和plugin有什么区别

ps:webpack一直是我薄弱的地方,虽然看了,但还是不是很理解,可能要手动跟着实现webpack后方能真正领悟吧。
可参考:「吐血整理」再来一打Webpack面试题(持续更新)
loader它是一个转换器,只专注于转换文件这一个领域,完成压缩、打包、语言编译,它仅仅是为了打包。并且运行在打包之前。
plugin是一个扩展器,它丰富了webpack本身,为其进行一些其它功能的扩展。它不局限于打包,资源的加载,还有其它的功能。所以它是在整个编译周期都起作用。

HTTP和TCP的不同

ps:http也是我的薄弱之处,这里只是记录了大概的答案,其实我并不理解
HTTP的责任是去定义数据,在两台计算机相互传递信息时,HTTP规定了每段数据以什么形式表达才是能够被另外一台计算机理解。
TCP所要规定的是数据应该怎么传输才能稳定且高效的传递与计算机之间。

TCP和UDP的区别

1.TCP是一个面向连接的、可靠的、基于字节流的传输层协议。
2.UDP是一个面向无连接的传输层协议。
TCP为什么可靠,是因为它有三次握手来保证双方都有接受和发送数据的能力。

字节流服务:将大块数据分割为以报文段为单位的数据包进行管理

CommonJS和ES6模块的区别

ps: 真的是老火,这几种规范我都不知道看过多少次了,看了忘,理解了下次又不记得。
参考: 一篇不是标题党的CommonJS和ES6模块规范讲解
ps: 看完了,更新一下,感觉现在对这几种方式认识更加清晰了。小小的总结一下:
1.commonjs主要用于服务端,输出的是值拷贝,但是对象还是共享相同的地址,运行时才加载。
2.为了解决commonjs同步以及为了客户端,有了amdcmd,它们的区别是amd先加载模块在执行,而cmd可以随时自己去加载模块。 (amd可以用async去记忆)。

//AMD
define(['m1'], function (m1) {
  console.log('我是math, 我被加载了...')
  var add = function (a, b) {
    return a + b;
  }
  var print = function () {
    console.log(m1.name)
  }
  return {
    add: add,
    print: print
  }
})

//CMD
define(function (require, exports, module) {
  console.log('我是math, 我被加载了...')
  var m1 = require('m1');
  var add = function (a, b) {
    return a + b;
  }
  var print = function () {
    console.log(m1.name)
  }
  module.exports = {
    add: add,
    print: print
  }
})

3.es6 modules输出的是值引用,编译的时候就输出了。

正则里的非如何实现的

^要是放在[]里的话就表示"除了^后面的内容都能匹配",也就是非的意思。

var str = '123456';
console.log(str.replace(/[^1]/g, '帅'));
// l帅帅帅帅帅

反之,如果是不在[]里的话则表示开头匹配

var str = '123456';
console.log(str.replace(/^1/g, '帅'));
// 帅23456

你知道到哪里查看兼容性吗

可以到Can I use上去查看,官网地址为:caniuse.com/

移动端中css我不知道的那些单位

vminvmaxvmin为当前vwvh中较小的一个值;vmax为较大的一个值。例如视口宽度375px,视口高度812px,则100vmin = 375px;100vmax = 812px;
exchex以字符"x"的高度为基准;例如1ex表示和字符"x"一样长。ch以数字"0"的宽度为基准;例如2ch表示和2个数字"0"一样长。

利用meta标签把http请求换为https

<meta http-equiv ="Content-Security-Policy" content="upgrade-insecure-requests">

移动端动态计算font-size,保证1rem=100px

ps:很久以前面试时别人问题动态font-size是怎么计算出来的,当时的我不求甚解,没有答出来,现在回顾一下,记录一波。

网页的字体 / 100  =  网页的宽度 / 750
=>
网页的字体 * 750 = 100 * 网页的宽度
=>
网页的字体 = 100 * 网页的宽度 / 750

网页的宽度:document.documentElement.getBoundingClientRect().width

还有一些需要去理解的问题

webpack几种hash的实现原理

webpack如果使用了hash命名,那是每次都会重写生成hash吗

webpack中如何处理图片的?

animation部分,都不太懂

http请求可以怎么拦截

混合加密的好处

浏览器如何验证服务器的身份

ETag首部字段说一下

token会不会被伪造?

前后端如何验证一个用户是否下线了

CSP白名单知道吗?

nginx有配置过吗?

反向代理知道吗?

有用过抓包工具吗?

协商缓存说一下

HTTP中的Keep-Alive有了解过吗?

requestAnimationFrame有了解过吗?

如何在前端实现一个图片压缩

不使用框架如何实现组件按需加载以及原理

babel-plugin-import

手写promise

今天看了另外一篇文章,跟着它的代码敲了下,感觉已经看懂了。剩下的就是自己手写出来,并记住它了。

        const isFunction = variable => typeof variable === 'function'
        const PENDING = 'PENDING'
        const FULFILLED = 'FUNFILLED'
        const REJECTED = 'REJECTED'

        class MyPromise {
            constructor (handle){
                if(!isFunction(handle)){
                    throw new Error('MyPromise must accept a function as a parameter')
                }

                this._status = PENDING
                this._value = undefined
                this._fulfilledQueues = []
                this._rejectedQueues = []

                try {
                    console.log('进入到内部,执行handle');
                    handle(this._resolve.bind(this), this._reject.bind(this))
                } catch (error) {
                    this._reject(err)
                }
            }

            _resolve (val){
                const run = () => {
                    if(this._status !== PENDING) return;

                    const runFulfilled = (value) => {
                        // 新奇的写法,不断shift来达到递归的效果
                        let cb
                        while (cb = this._fulfilledQueues.shift()) {
                            cb(val)
                        }
                    }

                    const runRejected = (err) => {
                        let cb
                        while (cb = this._rejectedQueues.shift()) {
                            cb(err)
                        }
                    }
                    
                    // 如果resolve的是一个promise时,需要再then一下
                    if(val instanceof MyPromise){
                        console.log('resolve是promise呀');
                        
                        val.then(value => {
                            this._status = FULFILLED
                            this._value = value
                            runFulfilled(value)
                        }, err => {
                            this._status = REJECTED
                            this._value = err
                            runRejected(err)
                        })
                    }else{
                        console.log('resolve啦');
                        
                        this._status = FULFILLED
                        this._value = val
                        runFulfilled(val)
                    }
                }

                setTimeout(run, 0)
            }

            _reject (err){
                if(this._status !== PENDING) return;

                const run = () => {
                    this._status = REJECTED
                    this._value = err
                    let cb
                    while (cb = this._rejectedQueues.shift()) {
                        cb(err)
                    }
                }
                
                setTimeout(run, 0)
            }

            then (onFulfilled, onRejected){
                const {_value, _status} = this
                console.log('进入then内部');
                
                // 返回一个promise,保证链式操作
                return new MyPromise((onFulfilledNext, onRejectedNext) => {
                    console.log('进入then promise返回', _status);

                    let fulfilled = val => {
                        console.log('变状态了!!!!!!!')
                        try {
                            if(!isFunction(onFulfilled)){
                                onFulfilledNext(val)
                            }else{
                                let res = onFulfilled(val)
                                // 如果then方法的返回值是promise就在then一下
                                if(res instanceof MyPromise){
                                    res.then(onFulfilledNext, onRejectedNext)
                                }else{
                                    console.log(`链式操作返回的res: ${res}`)
                                    onFulfilledNext(res)
                                }
                            }
                        } catch (error) {
                            onRejectedNext(error)
                        }
                    }

                    let rejected = err => {
                        try {
                            if(!isFunction(onRejected)){
                                onFulfilledNext(err)
                            }else{
                                let res = onRejected(err)
                                if(res instanceof MyPromise){
                                    res.then(onFulfilledNext, onRejectedNext)
                                }else{
                                    onRejectedNext(res)
                                }
                            }
                        } catch (error) {
                            onFulfilledNext(error)
                        }
                    }
                    
                    switch (_status){
                        case PENDING:
                            this._fulfilledQueues.push(fulfilled)
                            this._rejectedQueues.push(rejected)
                            break
                        case FULFILLED:
                            fulfilled(value)
                            break
                        case REJECTED:
                            rejected(_value)
                            break
                    }
                })
            }
        }

        let p1 = new MyPromise((resolve, reject) => {
            console.log('进入到promise了')
            setTimeout(() => {
                console.log('准备resolve了')
                resolve('FULFILLED')
            }, 1000)
        })

        let p2 = p1.then(res => {
            return res + '111111'
        })

        p2.then((res) => {
            console.log(res)
            return 1
        })
原文地址:https://www.cnblogs.com/wangxi01/p/12859581.html