一、页面渲染过程(转自:https://blog.csdn.net/longholidays/article/details/62054097)
浏览器的渲染页面时,表示网站资源已经请求成功。
渲染时,大致的流程如下:
(解析html以构建dom树->构建render树->布局render树->绘制render树)
具体的流程如下:
1:浏览器会将HTML解析成一个DOM树,DOM树的构建过程是一个深度遍历过程,当前节点的所有子节点都构建好后才会去构建当前节点的下一个兄弟节点,
2:将CSS解析成CSS规则树;
3:根据DOM树和CSS来构造render树,渲染树不等于DOM树,像header和display:none;这种没有具体内容的东西就不在渲染树中;
4:根据render树,浏览器可以计算出网页中有哪些节点,各节点的CSS以及从属关系,然后可以计算出每个节点在屏幕中的位置;
5:遍历render树进行绘制页面中的各元素。
P.S页面发生重拍(回流)的话,会重新加载DOM树,影响页面加载速度。会导致页面重拍的原因如下:
1:页面初始化;
2:操作DOM时;
3:某些元素的尺寸变了;
4:CSS的属性发生改变。
浏览器加载页面资源的步骤如下(部分参考网络资料):
1.用户输入网址(假设是第一次访问),浏览器向服务器发出请求,服务器返回html文件;
2.浏览器开始载入html代码,发现<head>标签内有一个<link>标签引用外部CSS文件;
3.浏览器又发出CSS文件的请求,服务器返回这个CSS文件;
4.浏览器继续载入html中<body>部分的代码,并且CSS文件已经拿到手了;
5.浏览器在代码中发现一个<img>标签引用了一张图片,向服务器发出请求。此时浏览器不会等到图片下载完,而是继续加载后面的代码;
6.服务器返回图片文件,由于图片占用了一定面积,影响了后面段落的排布,因此浏览器需要回过头来重新渲染这部分代码;
7.浏览器发现了一个包含一行Javascript代码的<script>标签,直接运行该脚本;
8.Javascript脚本执行了这条语句,它命令浏览器隐藏掉代码中的某个<div> (style.display=”none”)。少了一个元素,浏览器不得不重新渲染这部分代码;
9.</html>表示暂时加载完成;
10.此时用户点了一下界面中的“换肤”按钮,Javascript让浏览器换了一下<link>标签的CSS路径;
11.浏览器向服务器请求了新的CSS文件,重新加载页面。然后执行渲染过程。
图文讲解(另一位):https://www.cnblogs.com/dojo-lzz/p/3983335.html
2、HTTP协议详解(转自:https://www.cnblogs.com/ranyonsue/p/5984001.html)
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。
HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。
HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。
主要特点
1、简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
2、灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
3.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
4.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
5、支持B/S及C/S模式。
二、HTTP协议中,除了GET和POST还有什么请求?(转自https://blog.csdn.net/weixin_33738982/article/details/91465789)
HTTP/1.1协议中共定义了八种方法(也叫“动作”)来以不同方式操作指定的资源, 不过一般来说,Web服务器默认的只支持Post和Get这两种“只读”的请求方法。
OPTIONS:
这个方法可使服务器传回该资源所支持的所有HTTP请求方法。用’*'来代替资源名称,向Web服务器发送OPTIONS请求,可以测试服务器功能是否正常运作。
HEAD:
与GET方法一样,都是向服务器发出指定资源的请求。只不过服务器将不传回资源的本文部分。它的好处在于,使用这个方法可以在不必传输全部内容的情况下,就可以获取其中“关于该资源的信息”(元信息或称元数据)。
GET:
向指定的资源发出“显示”请求。使用GET方法应该只用在读取数据,而不应当被用于产生“副作用”的操作中,例如在Web Application中。其中一个原因是GET可能会被网络蜘蛛等随意访问。参见安全方法
POST:
向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据被包含在请求本文中。这个请求可能会创建新的资源或修改现有资源,或二者皆有。
PUT:
向指定资源位置上传其最新内容。
DELETE:
请求服务器删除Request-URI所标识的资源。
TRACE:
回显服务器收到的请求,主要用于测试或诊断。
CONNECT:
HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接(经由非加密的HTTP代理服务器)。
方法名称是区分大小写的。当某个请求所针对的资源不支持对应的请求方法的时候,服务器应当返回状态码405(Method Not Allowed),当服务器不认识或者不支持对应的请求方法的时候,应当返回状态码501(Not Implemented)。
通常我们用的也都是 GET 和 POST 方法,如果要实现其他的方法,需要在服务器做相应的配置。 但是我们应该清楚,有这些个动作的存在。 而且,其他请求方式也都可以通过这两种方式间接的来实现。
三、数据结构:八大数据结构分类****(转自:https://blog.csdn.net/yeyazhishang/article/details/82353846)****
数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成 。
常用的数据结构有:数组,栈,链表,队列,树,图,堆,散列表等
1、数组
数组是可以再内存中连续存储多个元素的结构,在内存中的分配也是连续的,数组中的元素通过数组下标进行访问,数组下标从0开始。
2、栈
栈是一种特殊的线性表,仅能在线性表的一端操作,栈顶允许操作,栈底不允许操作。 栈的特点是:先进后出,或者说是后进先出,从栈顶放入元素的操作叫入栈,取出元素叫出栈。
3、队列
队列与栈一样,也是一种线性表,不同的是,队列可以在一端添加元素,在另一端取出元素,也就是:先进先出。从一端放入元素的操作称为入队,取出元素为出队
4、链表
链表是物理存储单元上非连续的、非顺序的存储结构,数据元素的逻辑顺序是通过链表的指针地址实现,每个元素包含两个结点,一个是存储元素的数据域 (内存空间),另一个是指向下一个结点地址的指针域。根据指针的指向,链表能形成不同的结构,例如单链表,双向链表,循环链表等。
5、树
树是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合。把它叫做 “树” 是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:
每个节点有零个或多个子节点;
没有父节点的节点称为根节点;
每一个非根节点有且只有一个父节点;
除了根节点外,每个子节点可以分为多个不相交的子树;
在日常的应用中,我们讨论和用的更多的是树的其中一种结构,就是二叉树。
6、散列表
散列表,也叫哈希表,是根据关键码和值 (key和value) 直接进行访问的数据结构,通过key和value来映射到集合中的一个位置,这样就可以很快找到集合中的对应元素。
7、堆
堆是一种比较特殊的数据结构,可以被看做一棵树的数组对象,具有以下的性质:
堆中某个节点的值总是不大于或不小于其父节点的值;
堆总是一棵完全二叉树。
将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。常见的堆有二叉堆、斐波那契堆等。
堆的定义如下:n个元素的序列{k1,k2,ki,…,kn}当且仅当满足下关系时,称之为堆。
(ki <= k2i,ki <= k2i+1)或者(ki >= k2i,ki >= k2i+1), (i = 1,2,3,4…n/2),满足前者的表达式的成为小顶堆,满足后者表达式的为大顶堆
8、图
图是由结点的有穷集合V和边的集合E组成。其中,为了与树形结构加以区别,在图结构中常常将结点称为顶点,边是顶点的有序偶对,若两个顶点之间存在一条边,就表示这两个顶点具有相邻关系。
四、网页上哪里可以看到请求的所有信息
在网页刷新的同时,出现密密麻麻的记录,显示出了发送的请求,收到的信息等。
五、js继承的6种方式(转自:https://www.cnblogs.com/ranyonsue/p/11201730.html)
想要继承,就必须要提供个父类(继承谁,提供继承的属性)
1、原型链继承
重点:让新实例的原型等于父类的实例。
特点:1、实例可继承的属性有:实例的构造函数的属性,父类构造函数属性,父类原型的属性。(新实例不会继承父类实例的属性!)
缺点:1、新实例无法向父类构造函数传参。
2、继承单一。
3、所有新实例都会共享父类实例的属性。(原型上的属性是共享的,一个实例修改了原型属性,另一个实例的原型属性也会被修改!)
2、借用构造函数继承
重点:用.call()和.apply()将父类构造函数引入子类函数(在子类函数中做了父类函数的自执行(复制))
特点:1、只继承了父类构造函数的属性,没有继承父类原型的属性。
2、解决了原型链继承缺点1、2、3。
3、可以继承多个构造函数属性(call多个)。
4、在子实例中可向父实例传参。
缺点:1、只能继承父类构造函数的属性。
2、无法实现构造函数的复用。(每次用每次都要重新调用)
3、每个新实例都有父类构造函数的副本,臃肿。
3、组合继承(组合原型链继承和借用构造函数继承)(常用)
重点:结合了两种模式的优点,传参和复用
特点:1、可以继承父类原型上的属性,可以传参,可复用。
2、每个新实例引入的构造函数属性是私有的。
缺点:调用了两次父类构造函数(耗内存),子类的构造函数会代替原型上的那个父类构造函数。
4、原型式继承
重点:用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了个可以随意增添属性的实例或对象。object.create()就是这个原理。
特点:类似于复制一个对象,用函数来包装。
缺点:1、所有实例都会继承原型上的属性。
2、无法实现复用。(新实例属性都是后面添加的)
5、寄生式继承
重点:就是给原型式继承外面套了个壳子。
优点:没有创建自定义类型,因为只是套了个壳子返回对象(这个),这个函数顺理成章就成了创建的新对象。
缺点:没用到原型,无法复用。
6、寄生组合式继承(常用)
寄生:在函数内返回对象然后调用
组合:1、函数的原型等于另一个实例。2、在函数中用apply或者call引入另一个构造函数,可传参
重点:修复了组合继承的问题
六、JS数组转字符串(3种方法)****(转自:http://c.biancheng.net/view/5673.html)
JavaScript 允许数组与字符串之间相互转换。其中 Array 方法对象定义了 3 个方法,可以把数组转换为字符串。
1、toString():将数组转换成一个字符串
2、toLocalString() :把数组转换成本地约定的字符串
与 toString() 方法用法基本相同,主要区别在于 toLocalString() 方法能够使用用户所在地区特定的分隔符把生成的字符串连接起来,形成一个字符串。
join():将数组元素连接起来以构建一个字符串
把数组转换为字符串,不过它可以指定分隔符。在调用 join() 方法时,可以传递一个参数作为分隔符来连接每个元素。如果省略参数,默认使用逗号作为分隔符,这时与 toString() 方法转换操作效果相同。
如何把字符串转化为数组?
split() 方法是 String 对象方法,与 join() 方法操作正好相反。该方法可以指定两个参数,第 1 个参数为分隔符,指定从哪儿进行分隔的标记;第 2 个参数指定要返回数组的长度。
七、javascript中call()、apply()、bind()的用法(转自:https://www.cnblogs.com/Shd-Study/p/6560808.html)
输出:
obj.objAge; //17
obj.myFun() //小张年龄undefined
输出:
shows() //盲僧
第一个打印里面的this 指向obj,第二个全局声明的shows()函数 this 是window ;**
call()、apply()、bind() 都是用来重定义 this 这个对象的
obj.myFun.call(db); //德玛年龄99
obj.myFun.apply(db); //德玛年龄99
obj.myFun.bind(db)(); //德玛年龄99
以上出了bind 方法后面多了个 () 外 ,结果返回都一致!
由此得出结论,bind 返回的是一个新的函数,你必须调用它才会被执行
对比call 、bind 、 apply 传参情况下
从上面四个结果不难看出:
call 、bind 、 apply 这三个函数的第一个参数都是 this 的指向对象,第二个参数差别就来了:
call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面 obj.myFun.call(db,‘成都’, … ,‘string’ )。
apply 的所有参数都必须放在一个数组里面传进去 obj.myFun.apply(db,[‘成都’, …, ‘string’ ])。
bind 除了返回是函数以外,它 的参数和 call 一样。
当然,三者的参数不限定是 string 类型,允许是各种类型,包括函数 、 object 等等!
八、const用法(转自:https://www.jb51.net/article/182185.htm)
const定义的变量不可以修改,而且必须初始化。
const 声明一个只读的常量,一旦声明,常量的值就不能改变。
所谓的常量就是不能改变的值。
上面代码表明改变常量的值会报错。
const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。
我们都知道const一般声明一个只读的常量,声明之后就不能修改了,并且声明时必须初始化
特殊情况:
可以理解为:
dog中存储的是对象的房间号(内存地址)
dog.name= ‘wangcai’,在给对象添加属性的过程,并没有改变这个地址,所以结果正常显示
其实const保证的并不是变量的值不动,而是变量指向的内存地址不得改动
● js看到变量message后,会给message分配一个空房间(内存空间)
看到等号右侧的字符串‘hello’时,会立马给它安排另一个房间,并把‘hello’放到这个房间
● js会拿小本本抄下这个房间的房间号(内存地址)
● 把这个房间号放到message这个房间里面,这时message中存储的就是hello字符串的存储地址(即指针)
当我们再次赋值时
js会将存储‘word’字符串的地址赋给message,而message又是用const定义的变量,不可以改变变量里存储的内存地址,这时就会❌报错
重点:const保证的并不是变量的值不动,而是变量指向的内存地址不得改动
九、js选择器
一、原生JS选择器
JS选择器常用的有getElementById()、getElementsByName()、getElementsByTagName()、getElementsByClassName()、querySelector()、querySelectorAll()
A: getElementById(ID): 返回对指定ID的第一个对象的引用,如果在文档中查找一个特定的元素,最有效的方法是getElementById()
B: getElementsByName(name): 返回文档中name属性为name值的元素,因为name属性值不是唯一的,所以查询到的结果有可能返回的是一个数组,而不是一个元素。
C: getElementsByTagName(tagname): 返回文档中指定标签的元素
D: getElementsByClassName():返回文档中所有指定类名的元素
E: querySelector():返回文档中匹配指定css选择器的第一个元素
F: querySelectorAll():返回文档中匹配指定css选择器的第一个元素
二、jQuery选择器#
内容
基本选择器有ID选择器、类选择器、标签选择器、通用选择器,事件的添加方法如下:
$(…).事件名(function() { });
属性样式有:
$(…).css(“border”,“1px solid red”)
$(…).css({…})
$(…).css(“border”)
$(…).attr(属性名,值)
$(…).html() innerHTML
$(…).text() innerText
$(…).val() value值
$(…).addClass() 增加
$(…).removeClass() 移除
$(…).toggleClass() 开关**
十、Utf-8编码汉字占多少个字节
一个utf8数字占1个字节
一个utf8英文字母占1个字节
少数是汉字每个占用3个字节,多数占用4个字节。
UTF-8 使用一至四个字节为每个字符编码。128 个 ASCII 字符(Unicode 范围由 U+0000 至 U+007F)只需一个字节,带有变音符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文及马尔代夫语(Unicode 范围由 U+0080 至 U+07FF)需要二个字节,其他基本多文种平面(BMP)中的字符(CJK属于此类-Qieqie注)使用三个字节,其他 Unicode 辅助平面的字符使用四字节编码。