最后
基础知识是前端一面必问的,如果你在基础知识这一块翻车了,就算你框架玩的再6,webpack、git、node学习的再好也无济于事,因为对方就不会再给你展示的机会,千万不要因为基础错过了自己心怡的公司。前端的基础知识杂且多,并不是理解就ok了,有些是真的要去记。当然了我们是牛x的前端工程师,每天像背英语单词一样去背知识点就没必要了,只要平时工作中多注意总结,面试前端刷下题目就可以了。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
那么input[type=file]标签选择的文件,会被如何保存呢?
选择一个文件
在控制台输入
发现打印的DOM元素对象input中有一个特殊的属性files
files属性的类型是FileList,从名字就可以看出它是一个类数组,类数组元素是File类型对象
那么如果input[type=file]标签选择多个文件(标签加一个multiple属性),它的files中应该会包含多个File对象元素
而从打印结果可以看出File类型对象就是我们选择的文件
File是啥
File - Web API 接口参考 | MDN (mozilla.org)")
MDN关于File的介绍:
作用:
文件(
File
)接口提供有关文件的信息,并允许网页中的 JavaScript 访问其内容。
如何产生File对象:
通常情况下,
File
对象是来自用户在一个 元素上选择文件后返回的 FileList 对象,也可以是来自由拖放操作生成的 DataTransfer 对象,或者来自 HTMLCanvasElement 上的mozGetAsFile
() API。
File对象的属性
lastModified | 只读。返回当前 File 对象所引用文件最后修改时间的毫秒数。 |
File 对象所引用文件最后修改时间的 Date 对象。(废弃) | |
name | 只读。返回当前 File 对象所引用文件的名字。 |
size | 只读。返回当前 File 对象所引用文件的大小。 |
type | 只读。返回当前 File 对象所引用文件的MIME类型 |
其中lastModifiedDate,webkitRelativePath不推荐使用
剩下的属性也比较好理解,都是文件常见的信息,比如文件名,文件类型,文件大小,文件最后修改时间,需要注意这些File对象属性都是只读的。
File对象的方法
File对象没有定义任何方法,它的方法都继承自Blob。
原型链如下
可以发现File实例对象可以沿着原型链访问到Blob.prototype上的方法。
Blob是什么
Blob - Web API 接口参考 | MDN (mozilla.org)")
MDN对于Blob介绍是:
Blob
对象表示一个不可变、原始数据的类文件对象。
啥叫类文件对象?
Blob翻译过来是 Binary Larger Object,即二进制大对象。即Blob对象的组成是二进制数据。
而我们知道文件也是二进制编码的数据。
那么为什么Blob叫类文件呢,而不是文件呢?
其实Blob在这里代表的是比文件更加底层的概念。
我们知道文件是由二进制数据组成的,那么我们随意编写一些二进制数据,它能代表一个文件吗?答案是不能。文件的二进制数据具有各种特殊标识,来帮助外部理解一堆二进制数据是一个文件。
Blob代表的其实就是文件的切片。
我们知道文件的二进制数据组合在一起才能代表文件,而文件的二进制数据被分段后,比如分成十段,那么每一段都无法表示文件。但是每一段又都是文件的必不可少的组成部分。
此时就需要Blob来表示这些文件切片。所以说Blob是一个类文件对象。它不是文件,但是却和文件有千丝万缕的关系。
在浏览器API中,Blob是File的父类,这很好理解,父类是基类,子类是扩展类,我们可以说文件File是一堆二进制数据,是一个特殊的Blob,它可以当成Blob。但是它又比Blob多了一层含义。
Blob对象的属性:
size | 只读。Blob 对象中所包含数据的大小(字节)。 |
type | 只读。一个字符串,表明该 Blob 对象所包含数据的 MIME 类型。如果类型未知,则该值为空字符串。 |
有人说Blob对象咋还有文件才有的MIME类型呢?它不就是一个二进制数据对象吗?
还是要再说明一下,Blob对象相当于File对象的切片,如何标识一个文件切片属于什么文件类型是有必要的,它涉及都二进制数据的解析。
Blob对象的方法:
Blob.slice([start[, end[, contentType]]]) | 返回一个新的 Blob 对象,包含了源 Blob 对象中指定范围内的数据。 |
Blob.stream() | 返回一个能读取blob内容的 ReadableStream。 |
Blob.text() | 返回一个promise且包含blob所有内容的UTF-8格式的 USVString。 |
Blob.arrayBuffer() | 返回一个promise且包含blob所有内容的二进制格式的 ArrayBuffer |
Blob构造函数
返回一个新创建的 Blob
对象,其内容由参数中给定的数组串联组成。
其中blobParts参数是一个数组,数组中的每一项元素连接起来构成Blob对象的数据,数组中的每项元素可以是ArrayBuffer, ArrayBufferView, Blob, DOMString 。
options:可选项,字典格式类型,可以指定如下两个属性:
-
type,默认值为
""
,它代表了将会被放入到blob中的数组内容的MIME类型。 -
endings,默认值为"transparent",用于指定包含行结束符
\n
的字符串如何被写入。 它是以下两个值中的一个: “native”,表示行结束符会被更改为适合宿主操作系统文件系统的换行符; “transparent”,表示会保持blob中保存的结束符不变。
File,Blob的slice方法
那么现在了解Blob,而File继承了Blob的所有方法,且进行了拓展,可以直接操作文件,比如文件分片slice
从打印结果可以看出,file经过slice得到文件切片file_cp,而file_cp就不再是File类型了,而是Blob类型。
File,Blob的text方法
file.text()返回一个promise,该promise对象的结果是 blob所有内容的UTF-8格式的 USVString。
即file.text()将二进制编码的数据 转成了 utf-8编码的文本字符串。
不知道意义何在…,就像你用Notepad++打开一张png格式的图片一样。
File,Blob的arrayBuffer方法
file.arrayBuffer()
file.arrayBuffer()返回一个promise对象,其结果是 blob所有内容的二进制格式的 ArrayBuffer
ArrayBuffer是啥
那么啥是ArrayBuffer呢?ArrayBuffer - JavaScript | MDN (mozilla.org)")
ArrayBuffer
对象用来表示通用的、固定长度的原始二进制数据缓冲区。
它是一个字节数组,通常在其他语言中称为“byte array”。
你不能直接操作
ArrayBuffer
的内容,而是要通过 TypeArray 或 DataView 对象来操作,它们会将缓冲区中的数据表示为特定的格式,并通过这些格式来读写缓冲区的内容。
为什么ArrayBuffer中的数据无法直接操作呢?
因为ArrayBuffer数组的元素都是字节,即八位二进制数,且是二进制编码的,我们无法将ArrayBuffer字节数组的字节元素取出来,也无法覆盖字节元素。因为我们输入的都是字符,而不是字节。
而我们知道八位二进制数 可以转成 其他类型数据,最常见就是十进制数值,而我们是可以输入十进制数值的,所以可以将ArrayBuffer字节数组转为TypeArray类型数组,常见的TypeArray数组有:
由于ArrayBuffer都是字节元素,即每个元素都是无符号8位2进制,所以我们通常是将ArrayBuffer转为Unit8Array来进行处理
此时我们就可以对字节数组转成的Uint8Array数组进行元素操作了
对Uint8Array修改完后,再将其转为ArrayBuffer,则很简单,Uint8Array对象上就有一个buffer属性,可以获取到之前的ArrayBuffer实例
另外TypeArray没有新增,删除元素的操作,因为TypeArray的数组长度是固定的,无法改变的。
所以这么一看ArrayBuffer除了可以转为TypeArray修改字节元素外,也没啥,关键谁没事改字节数啊,文件的字节被改了,可能都无法解析了。
File,Blob的stream方法
file.stream()
返回一个能读取blob内容的 ReadableStream。
那么什么是ReadableStream呢?ReadableStream - Web API 接口参考 | MDN (mozilla.org)")
流操作API 中的ReadableStream
接口呈现了一个可读取的二进制流操作。
啥叫二进制流?
我们知道程序上的各种数据在计算机底层上都是二进制形式的,而程序中可识别数据互相传递,就意味着二进制形式数据的传输,即一串010101在各个程序中传输,而这些传输都是有方向性,就像水流一样,总是朝着一个方向流动,不可能出现一股水流出现两个方向。所以二进制数据的传输也是如此,所以二进制数据传输,也叫做流。
那么流的方向有哪些呢?
一个程序需要外部传入数据,那就底层的二进制数据就是朝着该程序输入,也叫输入流。
一个程序向外部提供数据,那么底层二进制数据就是朝程序外输出,也叫输出流。
具体判断是输入流,还是输出流的要点是,数据源是谁,如果从数据源读取数据,那么相当于数据源对外输出,就是输出流,如果向数据源写入数据,那么相当于输入流。
所以一个文件的输出流一般和读操作相关,输入流和写操作相关。
另外有一个关于流的概念,那就是流的组成。
我们知道流是指二进制数据的流动,那么流的组成就是二进制数据。但是二进制数据有不同的形式:
比如 0000000000001111111111111100000000000000,和 00000000 00001111 11111111 11000000 00000000
二者二进制数都相同,都表示40位的二进制数,但是第二个按照8位一组,进行了分组。
最后
为了帮助大家更好的了解前端,特别整理了《前端工程师面试手册》电子稿文件。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】