知识点积累

文章目录

记录一些零碎的知识点

CSS 有哪些样式可以给子元素继承

  • 可继承的:font-size,font-weight,line-height,color,cursor 等 。
  • 不可继承的一般是会改变盒子模型的:display,marginborderpaddingheight 等。

box-sizing 常用的属性有哪些? 分别有啥作用?

这个 css 主要是改变盒子模型的大小。有两个值:content-box(标准模型),border-box(怪异模型)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<style>
.test {
box-sizing: content-box;
border: 5px solid #f00;
padding: 5px;
width: 100px;
height: 100px;
}
</style>
<div class="test"></div>
<!--
content-box的计算公式会把宽高的定义指向 content,border和 padding 另外计算,
也就是说 content + padding + border = 120px(盒子实际大小)

而border-box的计算公式是总的大小涵盖这三者, content 会缩小,来让给另外两者
content(80px) + padding(5*2px) + border(5*2px) = 100px
-->

说说样式权重的优先级;

!important > 行内样式 > id > class > tag

对数组 [‘2018-03-05’, ‘2013-06-12’,’2019-03-12’,’2018-03-05’,’2014-02-22’] 去重且排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//很好理解, Set 具有值唯一性(但不是所有值,等会我抛出我的另外一篇文章)
// 结合...解构,可以把可迭代(比如 arguments/nodelist 等)的转为数组
// sort 里面传入 两个值比较,返回-1和1是因为1代表这个数大排后(相对),-1代表小(相对),0为相等

let arr = [
...new Set([
'2018-03-05',
'2013-06-12',
'2019-03-12',
'2018-03-05',
'2014-02-22'
])
].sort(function (a, b) {
return a < b ? -1 : 1 // 这里返回的是升序的,降序改下返回值就好了.所以是相对
})

// ["2013-06-12", "2014-02-22", "2018-03-05", "2019-03-12"]

对数组[1,2,3,4,5,’6’,7,’8’,’a’,’b’,’z’]进行乱序

1
2
3
4
5
6
7
8
// 我们依旧可以用上面的 sort 的原理实现乱序

let tempArr = [1, 2, 3, 4, 5, '6', 7, '8', 'a', 'b', 'z'].sort(function () {
return Math.random() > 0.5 ? -1 : 1
})

// 因为里面有随机数,所以答案没有标准答案,我这边跑了一次是输出这个
//["6", "z", 3, "b", 5, 2, 7, "8", "a", 1, 4]

求[1, 10, 11, -1,’-5’,12, 13, 14, 15, 2, 3, 4, 7, 8, 9]内最大值与最小值之差

1
2
3
4
5
6
7
8
9
10
11
12
13
// 来一个很粗糙的版本,只当传入是数组且可以隐性转为数字的
function MaxMinPlus(arr) {
// 返回最大值与最小值之差
return Array.isArray(arr)
? Math.max.apply(Math, arr) - Math.min.apply(Math, arr)
: console.log('传入的不是数组亦或者未能解决的错误')
}

// 结果是 20

// 若是要完善的话,要考虑传入的是非数组,
//传入字符串的时候要判断,然后切割为数组..
// 都要考虑进去代码量不短

JS 的作用域是什么?有什么特别之处么

作用域就是有它自身的上下文区域(比如函数内),内部会有变量声明提升,函数声明提升这些;

函数声明提升优于变量声明提升..

作用域有全局作用域和块级作用域(局部,比如用 let 或者单纯花括号的);

作用域会影响 this 的指向

作用域链

当访问一个变量时,解释器会首先在当前作用域查找标示符,如果没有找到,就去父作用域找,直到找到该变量的标示符或者不在父作用域中,这就是作用域链

作用域链和原型继承查找时的区别:如果去查找一个普通对象的属性,但是在当前对象和其原型中都找不到时,会返回 undefined;但查找的属性在作用域链中不存在的话就会抛出 ReferenceError。

作用域链的顶端是全局对象,在全局环境中定义的变量就会绑定到全局对象中。

javascript 里面的继承怎么实现,如何避免原型链上面的对象共享

  • ES5:寄生组合式继承:通过借用构造函数来继承属性和原型链来实现子继承父。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function ParentClass(name) {
this.name = name
}
ParentClass.prototype.sayHello = function () {
console.log("I'm parent!" + this.name)
}
function SubClass(name, age) {
//若是要多个参数可以用apply 结合 ...解构
ParentClass.call(this, name)
this.age = age
}
SubClass.prototype = Object.create(ParentClass.prototype)
SubClass.prototype.constructor = SubClass
SubClass.prototype.sayChildHello = function (name) {
console.log("I'm child " + this.name)
}

let testA = new SubClass('CRPER')

// Object.create()的polyfill
/*
function pureObject(o){
//定义了一个临时构造函数
function F() {}
//将这个临时构造函数的原型指向了传入进来的对象。
F.prototype = obj;
//返回这个构造函数的一个实例。该实例拥有obj的所有属性和方法。
//因为该实例的原型是obj对象。
return new F();
}
*/
  • ES6: 其实就是 ES5 的语法糖,不过可读性很强
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class ParentClass {
constructor(name) {
this.name = name
}
sayHello() {
console.log("I'm parent!" + this.name)
}
}

class SubClass extends ParentClass {
constructor(name) {
super(name)
}
sayChildHello() {
console.log("I'm child " + this.name)
}
// 重新声明父类同名方法会覆写,ES5的话就是直接操作自己的原型链上
sayHello() {
console.log("override parent method !,I'm sayHello Method")
}
}

let testA = new SubClass('CRPER')

渲染海量数据且给每条内容添加监听事件

现在浏览器提供了requestAnimationFrameAPI 来解决非常耗时的代码段对渲染阻塞问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
;(() => {
const ndContainer = document.getElementById('js-list')
if (!ndContainer) {
return
}

const total = 30000
const batchSize = 4 // 每批插入的节点次数,越大越卡
const batchCount = total / batchSize // 需要批量处理多少次
let batchDone = 0 // 已经完成的批处理个数

function appendItems() {
//这是掘金答案,可是个人觉得innerHTML会更好,经测试是真的更好
const fragment = document.createDocumentFragment()
for (let i = 0; i < batchSize; i++) {
const ndItem = document.createElement('li')
ndItem.innerText = batchDone * batchSize + i + 1
fragment.appendChild(ndItem)
}

// 每次批处理只修改 1 次 DOM
ndContainer.appendChild(fragment)

batchDone += 1
doBatchAppend()
}

function doBatchAppend() {
if (batchDone < batchCount) {
window.requestAnimationFrame(appendItems)
}
}

// kickoff
doBatchAppend()

ndContainer.addEventListener('click', function (e) {
const target = e.target
if (target.tagName === 'LI') {
alert(target.innerHTML)
}
})
})()

vue 中 watch 和计算属性的区别

  • 计算属性是自动监听依赖值的变化,从而动态返回内容,监听到值变化时,可以出发一次回调,并做一些事情,若是仅需要动态值就使用计算属性
  • 需要知道值改变后执行业务逻辑,才用 watch

为什么通常在发送数据买点请求的时候使用的是 1*1 像素的透明 gif 图片。

  1. 没有跨域问题,一般这种数据上报,代码要写通用的
  2. 不会阻塞页面加载,影响用户体验,只要 new image 对象就好了
  3. 在所有图片中,体积最小
  4. 相比 XMLHttpRequest 对象发送 GET 请求,性能上更好。

另外该脚本的位置一般放在页面最后以免阻塞页面渲染,并且一般情况下也不需要 append 到 DOM 中。通过它的 onerror 和 onload 事件来检测发送状态

1
2
3
4
5
6
7
8
var thisPage = location.href
var referringPage = document.referrer ? document.referrer : 'none'
var beacon = new Image()
beacon.src =
'http://www.example.com/logger/beacon.gif?page=' +
encodeURI(thisPage) +
'&ref=' +
encodeURI(referringPage)

input 搜索如何防抖,如何处理中文输入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// 这个是用来获取当前时间戳的
function now() {
return +new Date()
}
/**
* 防抖函数,返回函数连续调用时,空闲时间必须大于或等于 wait,func 才会执行
*
* @param {function} func 回调函数
* @param {number} wait 表示时间窗口的间隔
* @param {boolean} immediate 设置为ture时,是否立即调用函数
* @return {function} 返回客户调用函数
*/
function debounce(func, wait = 50, immediate = true) {
let timer, context, args

// 延迟执行函数
const later = () =>
setTimeout(() => {
// 延迟函数执行完毕,清空缓存的定时器序号
timer = null
// 延迟执行的情况下,函数会在延迟函数中执行
// 使用到之前缓存的参数和上下文
if (!immediate) {
func.apply(context, args)
context = args = null
}
}, wait)

// 这里返回的函数是每次实际调用的函数
return function (...params) {
// 如果没有创建延迟执行函数(later),就创建一个
if (!timer) {
timer = later()
// 如果是立即执行,调用函数
// 否则缓存参数和调用上下文
if (immediate) {
func.apply(this, params)
} else {
context = this
args = params
}
// 如果已有延迟执行函数(later),调用的时候清除原来的并重新设定一个
// 这样做延迟函数会重新计时
} else {
clearTimeout(timer)
timer = later()
}
}
}

有兼容问题

DNS 预解析

DNS 解析也是需要时间的,可以通过与解析的方式来蔚县获得域名所对应的 IP
<link rel="dns-prefetch" href="//yuchengkai.cn" />

分享到:
network