javascript
模拟实现
- 实现一个简单的Promise,具备then 与 catch方法
function myPromise(executor){
this.status = 'pending'
this.rejectedList = []
this.fulfilledList = []
this.result
this.err
function resolve (data) {
this.result = data
this.status = 'fulfilled'
this.fulfilledList.forEach(f=>{f(result)})
}
function reject (data) {
this.err = data
this.status = 'rejected'
this.rejectedList.forEach(f=>{f(err)})
}
this.then = function(callback) {
if (this.status === 'pending') {
this.fulfilledList.push(callback)
} else {
callback(this.result)
}
return this
}
this.catch = function (callback) {
if (this.status === 'pending') {
this.rejectedList.push(callback)
} else {
callback(this.err)
}
return this
}
executor(resolve.bind(this), reject.bind(this))
}
new myPromise((res,rej)=>{
console.log(1)
res('success')
}).then(console.log)
new myPromise((res,rej)=>{
console.log(2)
rej('error')
}).then(console.log)
.catch(err=>{
console.log('----')
console.log(err)
})
场景题
- 如何实现大文件的分片上传,断点续传,还有通常说的秒传?
实现一个大文件上传和断点续传
- 分片上传
- 解释:分片上传,即指将大文件切片成多个小文件块,然后同时上传
- 思路:
- 预设一个
SIZE
值,表示每个分片的最大大小,如SIZE=10*1024*1024
- 根据
SIZE
,利用Blob.prototype.slice(File继承了Blob,同样拥有slice方法),将File对象进行切片,并记录每个切片的顺序,便于服务器合并分片
- 服务器接收到所有切片后进行合并
- 断点续传
- 解释:在拥有类似暂停/恢复功能的上传场景中,要求从上一次的位置接着上传
- 思路:
- 在分片上传的基础上,增加上传中断的方法
- 当用户点击暂停时,将所有正在上传的切片上传中断(已上传完成的则不用管)
- 当用户点击恢复时,服务器返回哪些切片已经拥有,前端根据返回的切片列表进行过滤,继续上传剩余的切片
- 服务器接收到所有切片后进行合并
- 秒传
- 解释:即不管多大的文件,都是瞬间上传完毕
- 思路:计算待上传文件的Hash值,提交给后端查询是否上传过该文件,若是则直接返回上传成功(实际根本没上传)
理论
- 什么是函数柯里化?他有什么作用
- 将一个接收多个参数的函数转换成接收首个参数的函数,并返回接收余下参数的函数
- 作用
- 实现一个柯里化函数
function currying(fn, ...args) {
return fn.length > args.length ? (...args2) => currying(fn, ...args, ...args2) : fn(...args)
}
function sum(a,b,c,d,e){
console.log(a+b+c+d+e)
}
sum = currying(sum)
sum(1,2)(3)(4)(5)
- this指向考察,阐明输出结果是什么
var a = 1
var obj = {
fun:function(){
console.log(a)
},
a:2
}
obj.fun()
var a = 1
function foo(){
console.log(a)
}
function bar(){
var a = 2
foo()
}
bar()
- 原始值类型有哪些
- Number
- String
- Boolean
- Undefined
- Null
- BigInt
- Symbol
- null是对象吗?为什么 typeof null === 'object'
- 不是
- js设计时,把引用类型的标识位设置成000,而null的值就是0,因此在判断的时候会把null判断成对象
事件相关
- 事件触发的几个阶段是什么
- 捕获:由外而内,由父到子,网景提出
- 事件目标处理函数
- 冒泡:由内而外,由子到父,IE提出
- 为什么通常在冒泡阶段执行事件
- 由子到父元素,即是由精确的元素到模糊的元素,可以更精确的处理事件,同时可以阻止事件冒泡到父元素
- 实现一个demo
<ul id='list'>
<li data-id>
</li>
</ul>
- 要求点击li或者li中的任意子节点都能取到li上的data-id如何实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul id='list'>
<li data-id="li" onclick="handle(event)">
<p>11111111111111111111111111111111</p>
<p>11111111111111111111111111111111</p>
<p>11111111111111111111111111111111</p>
</li>
</ul>
<script>
function handle(e) {
alert(e.currentTarget.dataset.id)
}
</script>
</body>
</html>