html+css(h5+css3)
css 动画和 js 动画的差异
1. 代码复杂度,js 动画代码相对复杂一些
2. 动画运行时,对动画的控制程度上,js 能够让动画,暂停,取消,终止,css动画不能添加事件
3. 动画性能看,js 动画多了一个js 解析的过程,性能不如 css 动画好
rgba()和 opacity 的透明效果有什么不同
rgba()和 opacity 都能实现透明效果,但最大的不同是 opacity 作用于元素,以及元素
内的所有内容的透明度,
而 rgba()只作用于元素的颜色或其背景色。(设置 rgba 透明的元素的子元素不会继承
透明效果!)
css中link和@import的区别
1. link属于html标签,而@import是CSS中提供的
2. 在页面加载的时候,link会同时被加载,而@import引用的CSS会在页面加载完成后才会加载引用的CSS
3. @import只有在ie5以上才可以被识别,而link是html标签,不存在浏览器兼容性问题
4. Link引入样式的权重大于@import的引用(@import是将引用的样式导入到当前的页面中)
cssHack
注释:/* ie6 */
选择器:*html(ie6) *+ html(ie7)
方法:*background
em和rem,px
em对于父元素,rem根元素
px,em,rem相对单位 pt绝对单位
相同点:px和em都是长度单位;
异同点:px的值是固定的,指定是多少就是多少,计算比较容易。em得值不是固定的,并且em会继承父级元素的字体大小。
浏览器的默认字体高都是16px。所以未经调整的浏览器都符合: 1em=16px。那么12px=0.75em, 10px=0.625em。
HTML和XHTML的区别
1. 所有的标记都必须要有一个相应的结束标记
2. 所有标签的元素和属性的名字都必须使用小写
3. 所有的 XML 标记都必须合理嵌套
4. 所有的属性必须用引号 "" 括起来
5. 把所有 < 和 & 特殊符号用编码表示
6. 给所有属性赋一个值
7. 不要在注释内容中使用 "--"
8. 图片必须有说明文字
浏览器标准模式和怪异模式之间的区别是什么?
1. 盒子模型 渲染模式的不同
2. 使用 window.top.document.compatMode 可显示为什么模式
说几条写JavaScript的基本规范
1. 不要在同一行声明多个变量。
2. 请使用 ===/!==来比较true/false或者数值
3. 使用对象字面量替代new Array这种形式
4. 不要使用全局函数。
5. Switch语句必须带有default分支
6. 函数不应该有时候有返回值,有时候没有返回值。
7. For循环必须使用大括号
8. If语句必须使用大括号
9. for-in循环中的变量 应该使用var关键字明确限定作用域,从而避免作用域污染。
前端网站常规优化方案
1. 合并、压缩、混淆html/css/js文件(webpack实现,减小资源大小)
2. Nginx开启Gzip,进一步压缩资源(减小资源大小)
3. 图片资源使用CDN加速(提高加载速度)
4. 符合条件的图标做base64处理(减小资源大小)
5. 样式表放首部,JS放尾部(JS单线程,会阻塞页面;资源加载方式)
6. 设置缓存(强缓存和协商缓存,提高加载速度)
7. link或者src添加rel属性,设置prefetch或preload可预加载资源。(加载时机)
8. 如果使用了UI组件库,采用按需加载(减小资源大小)
9. SPA项目,通过import或者require做路由按需(减小资源大小)
10. 服务端渲染SSR,加快首屏渲染,利于SEO
11. 页面使用骨架屏,提高首页加载速度(提高加载速度)
12. 使用 JPEG 2000, JPEG XR, and WebP 的图片格式来代替现有的jpeg和png,当页面图片较多时,这点作用非常明显
13. 使用图片懒加载-lazyload
你做的页面在哪些流览器测试过?这些浏览器的内核分别是什么?
1. Trident(IE内核):IE、傲游、世界之窗浏览器、Avant、腾讯TT、猎豹安全浏览器、360极速浏览器、搜狗浏览器、百度浏览器等。
2. Gecko(firefox内核):火狐
3. webkit(Safari内核):傲游浏览器3、 Apple Safari (Win/Mac/iPhone/iPad)、Symbian手机浏览器、Android 默认浏览器
4. Blink(Chrome内核):Chrome
5. Presto(Opera内核):已废弃,现Opera已投入chrome
*FC的含义和区别
1. BFC(Block Formatting Contexts):块级格式化上下文行为规范
float的值不为none;
overflow的值不为visible;
position的值不为relative和static;
display的值为table-cell,table-caption何inline-block中的任何一个。
2. IFC(Inline Formatting Contexts):内联格式化上下文行为规范
3. GFC(GridLayout Formatting Contexts):网格格式化上下文行为规范
当display:grid,开启独立渲染空间,可以定义网格排列
4. FFC(Flex Formatting Contexts):自适应格式化上下文行为规范
display值为flex或者inline-flex的元素将会生成自适应容器,当前只有谷歌和火狐支持该属性
Scss和Less的区别
1. 编译环境:Scss在Ruby环境编译(服务端),Less在JavaScript环境编译(客户端)
2. 变量:Scss声明是$,Less是@
3. Scss函数语法比Less多(循环,mix)
浏览器是如何渲染页面的
1. 解析HTML文件,创建DOM树。自上而下,遇到任何样式与脚本都会阻塞。
2. 解析css。优先级:浏览器默认设置<用户设置<内部样式<HTML中的style样式。
3. 将CSS与DOM合并,构建渲染树(Render Tree)
4. 布局和绘制,重绘(repaint)和重排(reflow)
jq的特点
简单,链式调用,错误机制处理,事件循环
em和rem,px的区别
em对于父元素,rem根元素
px,em,rem相对单位 pt绝对单位
相同点:px和em都是长度单位;
异同点:px的值是固定的,指定是多少就是多少,计算比较容易。em得值不是固定的,并且em会继承父级元素的字体大小。
HTML语义化的理解
1.当页面样式加载失败的时候能够让页面呈现出清晰的结构
2.有利于seo优化,利于被搜索引擎收录(更便于搜索引擎的爬虫程序来识别)
3.便于项目的开发及维护,使html代码更具有可读性,便于其他设备解析。
css渐进增强和优雅降级
渐进增强:针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。
优雅降级:一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。
区别:优雅降级是从复杂的现状开始,并试图减少用户体验的供给,而渐进增强则是从一个基础的版本开始,不断扩充以适应未来环境的需要。
CSS隐藏元素的几种方法
1. Opacity:元素本身依然占据它自己的位置并对网页的布局起作用。它也将响应用户交互;
2. visibility:与opacity唯一不同的是它不会响应任何用户交互。此外,元素在读屏软件中也会被隐藏
3. display:display设为none,任何对该元素直接的用户交互操作都不可能生效。此外,读屏软件也不会读到元素的内容。这种方式产生的效果就像元素完成不存在;
4. position:不会影响到布局,能让元素保持可以操作;
5. Clip-path:clip-path属性还没有在IE或者Edge下完全支持。如果要在你的clip-path中使用外部SVG文件,浏览器支持度还要低。
cookies、sessionStorage和localstorage区别
相同点:都存储在客户端
不同点:
1.存储大小:
cookie数据大小不能超过4k。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
2.有效时间:
localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
sessionStorage 数据在当前浏览器窗口关闭后自动删除。
cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
3.数据与服务器之间的交互方式:
cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端;
sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。
CSS3的新特性
1. 颜色:新增RGBA,HSLA模式
2. 文字阴影(text-shadow)
3. 边框:圆角(border-radius),边框阴影(box-shadow)
4. 盒子模型:box-sizing
5. 背景:background-size:设置背景图片的尺寸 background-origin设置背景图片的原点background-clip 设置背景图片的裁切区域;
6. 渐变:liner-gradient radial-gradient
7. 过渡:transition,可实现动画
8. 自定义动画animate @keyfrom
9. 伪元素::selection
10. 媒体查询,@media
11. Border-image
12. 2D转换 transform:translate(x,y) rotate(x,y) skew(x,y) scale(x,y)
13. 3D转换
14. 字体图标font-face
15. 弹性布局flex
Flex主轴与交叉轴
justify-content 定义子元素主轴上的对齐方式:
justify-content: flex-start;默认值;主轴起点对齐,起点由flex-direction决定
justify-content: flex-end;主轴终点对齐,终点由 flex-direction决定
justify-content: center;主轴居中对齐
justify-content: space-between; 主轴两端对齐
justify-content: space-around;主轴平均分布
align-items 定义元素在交叉轴上对齐方式,交叉轴起点始终在左或上:
align-items: flex-start;交叉轴起点对齐,交叉轴与主轴垂直
align-items: flex-end;交叉轴终点对齐,交叉轴与主轴垂直
align-items: center;交叉轴居中对齐,交叉轴与主轴垂直
align-items: stretch;默认值;如果项目未设置高度或设为auto,将占满整个容器的高度
align-items: baseline;第一个子元素文字对齐
重绘和重排及优化
重绘(repaint或redraw)
当盒子的位置、大小以及其他属性,例如颜色、字体大小等都确定下来之后,浏览器便把这些原色都按照各自的特性绘制一遍,将内容呈现在页面上。重绘是指一个元素外观的改变所触发的浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。
重排(重构/回流/reflow)
当渲染树中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建, 需要重新计算样式和渲染树。每个页面至少需要一次回流,就是在页面第一次加载的时候。
在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程称为重绘。
重排必定会引发重绘,但重绘不一定会引发重排。
重排的成本比重绘的成本高得多的多。DOM树里的每个结点都会有reflow方法,一个结点的reflow很有可能导致子结点,甚至父点以及同级结点的reflow。
浏览器优化:
offsetTop、offsetLeft、offsetWidth、offsetHeight scrollTop、scrollLeft、scrollWidth、scrollHeight clientTop、clientLeft、clientWidth、clientHeight width、height getComputedStyle() getBoundingClientRect()
减少上面属性的使用
减少重绘与回流:
CSS:
使用 transform 替代 top
使用 visibility 替换 display: none ,因为前者只会引起重绘,后者会引发回流
改变了布局 避免使用table布局,可能很小的一个小改动会造成整个 table 的重新布局。
尽可能在DOM树的最末端改变class,回流是不可避免的,但可以减少其影响。尽可能
在DOM树的最末端改变class,可以限制了回流的范围,使其影响尽可能少的节点。
避免设置多层内联样式,CSS 选择符从右往左匹配查找,避免节点层级过多。
将动画效果应用到position属性为absolute或fixed的元素上,避免影响其他元素的布局,这样只是一个重绘,而不是回流,同时,控制动画速度可以选择 requestAnimationFrame,详见探讨 requestAnimationFrame。
避免使用CSS表达式,可能会引发回流。
将频繁重绘或者回流的节点设置为图层,图层能够阻止该节点的渲染行为影响别的节点,例如will-change、video、iframe等标签,浏览器会自动将该节点变为图层。
CSS3 硬件加速(GPU加速),使用css3硬件加速,可以让transform、opacity、filters这些动画不会引起回流重绘 。但是对于动画的其它属性,比如background-color这些,还是会引起回流重绘的,不过它还是可以提升这些动画的性能。
JavaScript
避免频繁操作样式,最好一次性重写style属性,或者将样式列表定义为class并一次性更改class属性。
避免频繁操作DOM,创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中。
避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。
对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。
自定义布局和响应式布局的区别
自适应布局是多各网页对应对个设备,响应式布局是一套网页对应多个设备
自适应对页面做的屏幕适配是在一定范围:比如pc端一般要大于1024像素,手机端要小于768像素。而响应式布局全部适应
自适应布局如果屏幕太小会发生内容过于拥挤。而响应式布局正是为了解决这个问题而衍生出的概念,它可以自动识别屏幕宽度并做出相应调整的网页设计
es6和javaScript
例举3种强制类型转换和2种隐式类型转换?
1. 强制(parseInt(),parseFloat(),Number())
2. 隐式(== , !! + -)
介绍下 Set、Map的区别?
应用场景Set用于数据重组,Map用于数据储存
Set:
(1)成员不能重复
(2)只有键值没有键名,类似数组
(3)可以遍历,方法有add, delete,has
Map:
(1)本质上是健值对的集合,类似集合
(2)可以遍历,可以跟各种数据格式转换
ES5和ES6的区别,说一下你知道的ES6
ECMAScript5,即ES5,是ECMAScript的第五次修订,于2009年完成标准化。
ECMAScript6,即ES6,是ECMAScript的第六次修订,于2015年完成,也称ES2015;ES6相对于ES5更加简洁,提高了开发效率;
ES6的新特性:
1.let声明变量和const声明变量;两个都有块级作用域;
2.箭头函数,不在使用function(),而是利用了()=>来进行定义;
3.模板字符串,用反引号标识,可以当作普通字符串使用,也可以定义多行字符串
4.解构赋值,ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值;
5.for of循环,可以遍历数组、Set和Map结构,某些类似数组的对象,对象,以及字符串
6.import、export导入导出
7.set 数据结构,类似数组,对所有的数据都是唯一的,没有重复的值。本身是构造函数
8....展开运算符,可以将数组或对象里面的值展开,还可以将多个值收集为一个变量;
9.class类的继承,不再像ES5一样使用原型链实现继承
10.async、await,搭配promise,处理异步流程,提高代码的简洁性和可读性
11.Symbol 是一种基本类型,通过调用symbol函数产生,接收一个可选的名字参数,该函数返回的symbol是唯一的
12.Proxy代理监听对象
for 、 forEach 、map、for…in、for…of的区别
1.for语句是最原始的循环语句。定义一个变量i(数值类型,表示数组的下标),按照一定的条件,对i进行循环累加。条件通常为循环对象的长度,当超过长度就停止循环。因为对象无法判断长度,所以搭配Object.keys()使用;
2.forEach ES5提出。自称是for循环的加强版,比for语句在写法大行简单很多。本质上是数组的循环,forEach每个元素执行一次callback函数,也就是调用它的函数,因此,不会改变原数组。返回值是undefined;
3.map ES5提出。给原数组中的每个元素都按顺序调用一次callback函数,生成一个新数组,不修改调用它的原数组本身。返回值是新的数组。
4.for...in ES5提出。遍历对象上的可枚举属性,包括原型对象上的属性,且按任意顺序进行遍历,也就是顺序不固定。遍历数组时把数组的下标当作键值,此时的i是字符串类型。它是遍历对象属性而构建的,不建议与数组一起使用。
5.for...of ES6提出。只遍历可迭代对象的数据
JavaScript原型,原型链 ? 有什么特点?
原型对象也是普通的对象,是对象一个自带隐式的 __proto__ 属性,原型也有可能有自己的原型,如果一个原型对象的原型不为null的话,我们就称之为原型链。
原型链是由一些用来继承和共享属性的对象组成的(有限的)对象链。
JavaScript的数据对象有那些属性值?
writable:这个属性的值是否可以改。
configurable:这个属性的配置是否可以删除,修改。
enumerable:这个属性是否能在for…in循环中遍历出来或在Object.keys中列举出来。
value:属性值。
当我们需要一个属性的时,Javascript引擎会先看当前对象中是否有这个属性, 如果没有的话,就会查找他的Prototype对象是否有这个属性。
function clone(proto) {
function Dummy() { }
Dummy.prototype = proto;
Dummy.prototype.constructor = Dummy;
return new Dummy(); //等价于Object.create(Person);
}
function object(old) {
function F() {};
F.prototype = old;
return new F();
}
var newObj = object(oldObject);
JQuery的特点
1.首先jQuery提供了强大的元素选择器。用于获取html页面中封装了html元素的jQuery对象
2.第二点就是jQuery提供了对css样式操作的支持,像对class属性的增加删除切换操作
3.第三点就是jQuery出色的DOM操作的封装,极大的简化了javascript的对dom节点的增删改查操作,让我们可以使用一种更加简洁的方法来操作节点。
4.第四点就是jQuery还是一个为事件处理特点设计的框架,提供了静态绑定事件和动态绑定事件,完善了事件的处理机制。
5.jQuery解决了大量浏览器之间的兼容性的问题
6.jQuery极大的简化ajax编程,提供了一种更加简洁,统一的编程方式。
7.可实现链式调用
8.没有事件覆盖
深拷贝和浅拷贝
浅拷贝:创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址,所以如果其中一个对象改变了这个地址,就会影响到另一个对象
浅拷贝方法
Objcet.assign
拓展运算符…
Array.prototype.slice
Array.prototype.concat
深拷贝:将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象
深拷贝方法
JSON.stringify()
数组深克隆:[].concat ()
函数外深克隆:JSON.parse()
function fn(str){
var asd;
if(test(str) === "Array"){
asd = [];
}else if(test(str) === "Object"){
asd = {};
}else{
return str;
}
for(var i in str){
if(test(str[i]) == "Object"){
fn(str[i])
}else{
asd[i] = str[i]
}
}
return asd
}
function test(es){
return Object.prototype.toString.call(es).slice(8,-1)
}
import和export
ES6标准中,JavaScript原生支持模块(module)了。这种将JS代码分割成不同功能的小块进行模块化,将不同功能的代码分别写在不同文件中,各模块只需导出公共接口部分,然后通过模块的导入的方式可以在其他地方使用。
export用于对外输出本模块(一个文件可以理解为一个模块)变量的接口。
import用于在一个模块中加载另一个含有export接口的模块。
import和export命令只能在模块的顶部,不能在代码块之中。
//导入部分
//全部导入
import Person from './example'
//将整个模块所有导出内容当做单一对象,用as起别名
import * as example from "./example.js"
console.log(example.name)
console.log(example.getName())
//导入部分
import { name } from './example'
//导出部分
// 导出默认
export default App
// 部分导出
export class User extend Component {};
this指向
1.全局作用域下的this指向window
2.如果给元素的事件行为绑定函数,那么函数中的this指向当前被绑定的那个元素
3.函数中的this,要看函数执行前有没有.(点) 若有.(点),点前是谁,this就指向谁,若没有点,则指向window
4.自执行函数中的this永远指向window
5.定时器中函数的this指向window
6.构造函数中的this指向当前的实例
7.call、apply、bind可以改变函数的this指向
8.箭头函数中没有this,如果输出this,就会输出箭头函数定义时所在作用域中的this。
js判断变量的类型
1.使用typeof能判断出四种,分别是number,string,boolean,object,剩余的均被检测为object;
2.使用instanceof,根据instanceof的定义:判断参照对象的prototype属性所指向的对象是否在被检测对象的原型链上;
3.使用constructor检测针对instanceof的弊端,我们使用了constructor检测,constructor是原型对象的属性指向构造函数。这种方式解决了instanceof的弊端,可以检测出除了undefined和null的9种类型,但是这种方式仍然有个弊端,就是constructor所指向的构造函数是可以被修改的。
4.使用Object.prototype.toString.call
5.jQuery.type()方法.$.type(obj),没有缺点,除了需要使用jQuery
什么是迭代器、生成器,以及他们的区别
迭代器:迭代器又称遍历器(iterator)是一个统一的接口,用来处理数据结构的
生成器:生成器是通过Generator函数创建出来的一个对象,这个对象即是迭代器,也是可迭代对象
区别:
1.生成器是生成元素的,迭代器是访问集合元素的一中方式
2.迭代输出生成器的内容
3.迭代器是一种支持next()操作的对象
4.迭代器是生成器的子集
javaScript 内存泄漏及如何避免
全局的 +use strict
循环引用 赋值为null
定时器遗忘 清除定时器
闭包 解除闭包
dom元素移除替换绑定事件没有清除 手动清除,事件委托
自动类型转换:(let s = “xxx” s.length,字符串没有长度,会先创建String对象) 类型值在运算之前先显示转化一下
ES5/ES6 的继承除了写法以外还有什么区别?
class 声明会提升,但不会初始化赋值。Foo 进入暂时性死区,类似于 let、const 声明变量。
class 声明内部会启用严格模式。
class 的所有方法(包括静态方法和实例方法)都是不可枚举的。
必须使用 new 调用 class。
class 的所有方法(包括静态方法和实例方法)都没有原型对象 prototype
class 内部无法重写类名。
js延迟加载的方式有哪些?
方案一:<script>标签的async="async"属性(详细参见:script标签的async属性)
方案二:<script>标签的defer="defer"属性
方案三:动态创建<script>标签
方案四:AJAX eval(使用AJAX得到脚本内容,然后通过eval_r(xmlhttp.responseText)来运行脚本)
方案五:iframe方式
数组和对象有哪些原生方法,列举一下?
Array.concat( ) 连接数组
Array.join( ) 将数组元素连接起来以构建一个字符串
Array.length 数组的大小
Array.pop( ) 删除并返回数组的最后一个元素
Array.push( ) 给数组添加元素
Array.reverse( ) 颠倒数组中元素的顺序
Array.shift( ) 将元素移出数组
Array.slice( ) 返回数组的一部分
Array.sort( ) 对数组元素进行排序
Array.splice( ) 插入、删除或替换数组的元素
Array.toLocaleString( ) 把数组转换成局部字符串
Array.toString( ) 将数组转换成一个字符串
Array.unshift( ) 在数组头部插入一个元素
Object.hasOwnProperty( ) 检查属性是否被继承
Object.isPrototypeOf( ) 一个对象是否是另一个对象的原型
Object.propertyIsEnumerable( ) 是否可以通过for/in循环看到属性
Object.toLocaleString( ) 返回对象的本地字符串表示
Object.toString( ) 定义一个对象的字符串表示
Object.valueOf( ) 指定对象的原始值
new操作符具体干了什么呢?
1、创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
2、属性和方法被加入到 this 引用的对象中。
3、新创建的对象由 this 所引用,并且最后隐式的返回 this 。
function myNew (fn, ...args) {
let instance = Object.create(fn.prototype);
let result = fn.call(instance, ...args)
return typeof result === 'object' ? result : instance;
}
xml和json的区别
JSON相对于XML来讲,数据的体积小,传递的速度更快些
JSON与JavaScript的交互更加方便,更容易解析处理,更好的数据交互
XML对数据描述性比较好;
JSON的速度要远远快于XML
Flex主轴与交叉轴
display: flex;
justify-content: center; //主轴居中
align-items: center; //交叉轴居中
justify-content 定义子元素主轴上的对齐方式:
justify-content: flex-start;默认值;主轴起点对齐,起点由flex-direction决定
justify-content: flex-end;主轴终点对齐,终点由 flex-direction决定
justify-content: center;主轴居中对齐
justify-content: space-between; 主轴两端对齐
justify-content: space-around;主轴平均分布
align-items 定义元素在交叉轴上对齐方式,交叉轴起点始终在左或上:
align-items: flex-start;交叉轴起点对齐,交叉轴与主轴垂直
align-items: flex-end;交叉轴终点对齐,交叉轴与主轴垂直
align-items: center;交叉轴居中对齐,交叉轴与主轴垂直
align-items: stretch;默认值;如果项目未设置高度或设为auto,将占满整个容器的高度
align-items: baseline;第一个子元素文字对齐
Promise
直译过来就是:Promise对象表示异步操作的最终完成(或失败)及其结果值
作为一个新对象,他的存在肯定是有其意义的,比如优化了写法,或者解决了一些以前的问题等等
※ Promise解决了回调地狱的问题
什么是回调地狱?
简单说一下,在写JavaScript时,为了实现某些业务逻辑,常常会写出层层嵌套的回调函数,而回调函数总依赖另一个函数执行调用,这样极大影响了代码的可读性和逻辑。
而Promise作为对象,它和函数的区别是对象可以保存状态,但是函数不可以(闭包除外), 它并没有剥夺函数return的能力,因此不需要层层传递callback,用回调的方式获取数据,这使得Promise的代码风格容易理解且便于维护。
Promise对象对未来发生事情,远见规划,通过区分状态,在不同状态下有什么结果,该怎么做,解决异步调用存在的问题。
resolve :将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去
reject :将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去
Promise的三个状态
1 . pending 初始状态
2 . fulfilled 操作成功
3 . rejected 操作失败
当Promise的状态发生改变,就会触发then()里的响应函数处理后续步骤
ps :promise状态一经改变,不会再变
__proto__和prototype的区别
__proto__和prototype属性都是都是对象独有的
prototype属性是函数独有的,但是js中函数也是一种对象,所以函数也拥有__proto__和prototype属性
__proto__属性都是由一个对象指向一个对象,即指向它们的原型对象,这个属性的作用是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__属性所指向的那个对象里找,如果父对象也不存在这个属性,则继续往父对象的__proto__属性所指向的那个对象里找,直到找到为止,如果到了原型链的顶端null还是没有找到,那么就会报错
prototype属性是函数独有的,它是一个函数指向一个对象,含义是函数的原型对象,它的作用是包含可以由特定类型的所有实例共享的属性和方法,也就是让该函数所实例化的对象们都可以找到公用的属性和方法
任何函数在创建的时候,会默认创建prototype对象
Doctype作用? 严格模式与混杂模式如何区分?它们有何意义?
1. <!DOCTYPE> 声明位于文档中的最前面,处于 <html> 标签之前。告知浏览器以何种模式来渲染文档。
2. 严格模式的排版和 JS 运作模式是 以该浏览器支持的最高标准运行。
3. 在混杂模式中,页面以宽松的向后兼容的方式显示。模拟老式浏览器的行为以防止站点无法工作。
4. DOCTYPE不存在或格式不正确会导致文档以混杂模式呈现。
ajax的优缺点
优点:
1. 通过异步模式,提升了用户体验
2. 优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用
3. Ajax在客户端运行,承担了一部分本来由服务器承担的工作,减少了大用户量下的服务器负载。
缺点:
1. ajax不支持浏览器back按钮。
2. 安全问题 AJAX暴露了与服务器交互的细节。
3. 对搜索引擎的支持比较弱。
4. 破坏了程序的异常机制。
5. 不容易调试。
描述一下预编译过程。
函数运行的前一刻创建活动对象AO
将var声明的变量和形参作为活动对象的属性名,值为undefined 有重名不新增属性名直接替换
将实参和形参的值统一
检测function声明的函数,函数名作为AO对象的属性名,赋值为函数体 如果有和变量重名,注意:不新增属性名直接替换值
说几条写JavaScript的基本规范?
1.不要在同一行声明多个变量。
2.请使用 ===/!==来比较true/false或者数值
3.使用对象字面量替代new Array这种形式
4.不要使用全局函数。
5.Switch语句必须带有default分支
6.函数不应该有时候有返回值,有时候没有返回值。
7.For循环必须使用大括号
8.If语句必须使用大括号
9.for-in循环中的变量 应该使用var关键字明确限定作用域,从而避免作用域污染。
什么是"use strict";?使用它的好处和坏处分别是什么?
在代码中出现表达式-"use strict"; 意味着代码按照严格模式解析,这种模式使得Javascript在更严格的条件下运行。
好处:
消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
消除代码运行的一些不安全之处,保证代码运行的安全;
提高编译器效率,增加运行速度;
为未来新版本的Javascript做好铺垫。
坏处:
同样的代码,在"严格模式"中,可能会有不一样的运行结果;
一些在"正常模式"下可以运行的语句,在"严格模式"下将不能运行。
防抖和节流
防抖:高频触发事件后,函数不会因为事件而多次触发,函数只执行一次,在函数执行之后,方可再次执行
节流:高频触发事件后,函数会以时间差在单位时间可控制的多次执行
function fn(callback,time){//防抖
let timer = null;
return function(){
clearTimeout(timer);
timer = setTimeout(callback,time)
}
}
window.addEventListener("scroll",fn(test,1000))
function fn(callback,time) {//节流
let timer = null;
let oldtime = new Date();
return function() {
let newtime = new Date();
clearTimeout(timer);
if(newtime - oldtime >= time){
callback();
oldtime = new Date();
}else{
timer = setTimeout(callback,time);
}
}
}
CommonJS和ES6模块的区别
CommonJS模块是运行时加载,ES6 Modules是编译时输出接口
CommonJS输出是值的拷贝;ES6 Modules输出的是值的引用,被输出模块的内部的改变会影响引用的改变
CommonJs导入的模块路径可以是一个表达式,因为它使用的是require()方法;而ES6 Modules只能是字符串
CommonJS this指向当前模块,ES6 Modules this指向undefined
且ES6 Modules中没有这些顶层变量:arguments、require、module、exports、__filename、__dirname
关于第一个差异,是因为CommonJS 加载的是一个对象(即module.exports属性),该对象只有在脚本运行完才会生成。而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。
promise 放在try catch里面有什么结果
1. Promise 对象的错误具有冒泡性质,会一直向后传递,直到被捕获为止,也即是说,错误总会被下一个catch语句捕获
2. 当Promise链中抛出一个错误时,错误信息沿着链路向后传递,直至被捕获
cookies sessionStorage和localstorage区别
相同点: 都存储在客户端。
不同点:
1. 存储大小
cookie数据大小不能超过4k。
sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
2. 有效时间
localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
sessionStorage 数据在当前浏览器窗口关闭后自动删除。
cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
3. 数据与服务器之间的交互方式·
cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端
sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。
4、兼容性
sessionStorage和localStorage IE8以上才支持
浏览器会限制localStorage的值为string类型,例如存储常见的JSON对象需要转换
5、
Cookie的作用域通过文档源和文档路径来确定的
Cookie会随着http头信息一起发送,增加了文档传输的负载
LocalStorage本质上是对字符串的读取,如果存储过多会消耗内存空间,会导致页面变卡
LocalStorage无法被爬虫抓取到
document.write和innerHTML的区别
document.write是直接写入到页面的内容流,如果在写之前没有调用document.open, 浏览器会自动调用open。每次写完关闭之后重新调用该函数,会导致页面被重写。innerHTML则是DOM页面元素的一个属性,代表该元素的html内容。你可以精确到某一个具体的元素来进行更改。如果想修改document的内容,则需要修改document.documentElement.innerElement。innerHTML将内容写入某个DOM节点,不会导致页面全部重绘
innerHTML很多情况下都优于document.write,其原因在于其允许更精确的控制要刷新页面的那一个部分。
xml和json的区别
JSON相对于XML来讲,数据的体积小,传递的速度更快些
JSON与JavaScript的交互更加方便,更容易解析处理,更好的数据交互
XML对数据描述性比较好;
JSON的速度要远远快于XML
清除浮动的方法
父级div定义 height
原理:父级div手动定义height,就解决了父级div无法自动获取到高度的问题。
优点:简单、代码少、容易掌握
缺点:只适合高度固定的布局,要给出精确的高度,如果高度和父级div不一样时,会产生问题
结尾处加空div标签 clear:both
原理:添加一个空div,利用css提高的clear:both清除浮动,让父级div能自动获取到高度
优点:简单、代码少、浏览器支持好、不容易出现怪问题
缺点:不少初学者不理解原理;如果页面浮动布局多,就要增加很多空div,让人感觉很不好
父级div定义 伪类:after 和 zoom
原理:IE8以上和非IE浏览器才支持:after,原理和方法2有点类似,zoom(IE转有属性)可解决ie6,ie7浮动问题
优点:浏览器支持好、不容易出现怪问题(目前:大型网站都有使用,如:腾迅,网易,新浪等等)
缺点:代码多、不少初学者不理解原理,要两句代码结合使用才能让主流浏览器都支持
父级div定义 overflow:hidden
原理:必须定义width或zoom:1,同时不能定义height,使用overflow:hidden时,浏览器会自动检查浮动区域的高度
优点:简单、代码少、浏览器支持好
缺点:不能和position配合使用,因为超出的尺寸的会被隐藏。
Javascript 如何实现继承
原型链继承,借用构造函数继承,组合继承,寄生式继承,寄生组合继承
Javascript 中 callee 和 caller 的作用?
arguments.callee:获得当前函数的引用
caller 是返回一个对函数的引用,该函数调用了当前函数;
callee 是返回正在被执行的 function 函数,也就是所指定的 function 对象的正文。
什么是闭包,如何使用它,为什么要使用它?
能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
使用闭包的注意点:
· 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
· 闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
谈谈对闭包的理解
使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。
闭包有三个特性:
1.函数嵌套函数
2.函数内部可以引用外部的参数和变量
3.参数和变量不会被垃圾回收机制回收
setTimeout、Promise、 Async/Await 的区别
事件循环中分为宏任务队列和微任务队列
(1)、其中setTimeout的回调函数放到宏任务队列里,等到执行栈清空以后执行
(2)、promise.then里 的回调函数会放到相应宏任务的微任务队列里,等宏任务里面的同步代码执行完再执行
(3)、async函数表示函数里面可能会有异步方法,await后面跟一一个表达式
(4)、async方法执行时,遇到await会立即执行表达式,然后把表达式后面的代码放到微任务队列里,让出执行栈让同步代码先执行
es6箭头函数
函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
异步事件处理过程
当js引擎开始解析代码时,把任务压入执行栈,然后判断栈中任务类型,异步就把任务丢到异步处理模块中,有结果时把回调函数放到任务队列中,可以理解成分类,把各自放到对应类型的执行环境,执行栈秉承先进后出的顺序,任务队列则是先进先出,执行栈先执行任务,当执行栈清空会把任务队列中的任务拉到执行栈执行
node
express是什么?
Express是一个最小的,灵活的Node.js Web应用程序开发框架,它提供了一套强大的功能来开发Web和移动应用程序。 它有助于基于Node Web应用程序的快速开发。
特点:
1、可以设置 中间件来响应http请求
2、定义了路由用于执行不同的http请求动作
3、可以通过模板传递参数来动态渲染html页面
浏览器和Node 事件循环的区别
其中一个主要的区别在于浏览器的event loop 和nodejs的event loop 在处理异步事件的顺序是不同的,nodejs中有micro event;其中Promise属于micro event 该异步事件的处理顺序就和浏览器不同.nodejs V11.0以上 这两者之间的顺序就相同了.
数据库
关系型数据库和非关系型数据库
关系型:
1、复杂查询可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询。
2、事务支持使得对于安全性能很高的数据访问要求得以实现。
3、复杂操作:支持SQL,可以进行Join等复杂查询,可用于一个表以及多个表之间非常复杂的查询。
4、由于以标准化为前提,数据更新的开销很小(相同的字段基本上都只有一处)
缺点
1、读写性能比较差,尤其是海量数据的高效率读写;
2、固定的表结构,灵活度稍欠;
3、高并发读写需求,传统关系型数据库来说,硬盘I/O是一个很大的瓶颈。
4、不擅长为有数据更新的表做索引或表结构变更
5、不擅长对简单查询需要快速返回结果的处理
非关系型:
1、格式灵活:存储数据的格式可以是key,value形式、文档形式、图片形式等等,文档形式、图片形式等等,使用灵活,应用场景广泛,而关系型数据库则只支持基础类型。
2、速度快,非关系型数据库可以使用硬盘或者随机存储器作为载体,而关系型数据库只能使用硬盘;
3、高扩展性,基于键值对,数据之间没有耦合性,所以非常容易水平扩展。
4、成本低,非关系型数据库数据库部署简单,基本都是开源软件。
5、易于数据的分散,分布式数据库,各个数据都是独立设计的,很容易把数据分散在多个服务器上,故减少了每个服务器上的数据量。
缺点
1、不提供关系型数据库对事物的处理。NoSQL数据库只应用在特定领域,基本上不进行复杂的处理,不支持join等功能。但它恰恰弥补了之前所列举的关系型数据库的不足之处。
Vue
什么是MVVM?
MVVM是Model-View-ViewModel的缩写。MVVM是一种设计思想。Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步View 和 Model的对象。
在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。
mvvm和mvc区别?它和其它框架(jquery)的区别是什么?哪些场景适合?
mvc和mvvm其实区别并不大。都是一种设计思想。主要就是mvc中Controller演变成mvvm中的viewModel。mvvm主要解决了mvc中大量的DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。
区别:vue数据驱动,通过数据来显示视图层而不是节点操作。
场景:数据操作比较多的场景,更加便捷
Vue实现数据双向绑定的原理
Object.defineProperty()
vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter,用户看不到 getter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。
vue的数据双向绑定 将MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令(vue中是用来解析 {{}}),最终利用watcher搭起observer和Compile之间的通信桥梁,达到数据变化 —>视图更新;视图交互变化(input)—>数据model变更双向绑定效果。
Axios是什么
Axios是基于promise用于浏览器和nodejs的HTTP客户端,本质上是对原生XHR的封装,只不过这是promise的实现版本,符合最新的ES规范;
特征:
1.在浏览器中发送 XMLHttpRequests 请求;
2.在 node.js 中发送 http请求;
3.基于 promise 的 HTTP 库,支持promise所有的API
4.拦截请求和响应;(修改请求数据,只能用在'PUT','POST'和'PATCH'这几个请求方法)
5.转换请求和响应数据,响应回来的内容自动转换;
6.自动转换 JSON 数据;
7.客户端支持保护安全免受 XSRF 攻击;
vue的路由模式
Vue的路由实现:hash模式 和 history模式
hash模式:在浏览器中符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取;
特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。
hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 http://www.xxx.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。
history模式:history采用HTML5的新特性;且提供了两个新方法:pushState(),replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。
history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 http://www.xxx.com/items/id。后端如果缺少对 /items/id 的路由处理,将返回 404 错误。Vue-Router 官网里如此描述:“不过这种模式要玩好,还需要后台配置支持……所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。”
vue的优点是什么?
低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。
可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。
vue.cli中怎样使用自定义的组件?有遇到过哪些问题吗?
第一步:在components目录新建你的组件文件(indexPage.vue),script一定要export default {}
第二步:在需要用的页面(组件)中导入:import indexPage from '@/components/indexPage.vue'
第三步:注入到vue的子组件的components属性上面,components:{indexPage}
第四步:在template视图view中使用,
例如有indexPage命名,使用的时候则index-page
库,插件和框架的区别
框架:
提供了前端项目整体的解决方案,一系列定义好的数据结构和函数,一般用于作为一个软件的骨架,但程序真正的功能还需要开发者实现
库:
是一系列预先定义好的数据结构和函数(对于面向对象语言来说,是类)的集合,程序员通过使用这些数据结构和函数实现功能,为解决某种特定需求的程序功能集合
插件:
一般指软件系统的一部分,可以独立于整个系统进行开发与测试,具有可复用性
库和框架最大的区别在于:
”控制反转“,当你使用一个库,你会调用库中的代码,当你使用一个框架,框架会调用你的代码,很多框架都是以库的形式发布的
vuex面试相关
(1)vuex是什么?怎么使用?哪种功能场景使用它?
vue框架中状态管理。在main.js引入store,注入。新建一个目录store,…… export 。场景有:单页应用中,组件之间的状态。音乐播放、登录状态、加入购物车
(2)vuex有哪几种属性?
-
有五种,分别是 State、 Getter、Mutation 、Action、 Module - vuex的State特性 A、Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于一般Vue对象里面的data B、state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新 C、它通过mapState把全局的 state 和 getters 映射到当前组件的 computed 计算属性中 - vuex的Getter特性 A、getters 可以对State进行计算操作,它就是Store的计算属性 B、 虽然在组件内也可以做计算属性,但是getters 可以在多组件之间复用 C、 如果一个状态只在一个组件内使用,是可以不用getters - vuex的Mutation特性 Action 类似于 mutation,不同在于:Action 提交的是 mutation,而不是直接变更状态;Action 可以包含任意异步操作。
(3)不用Vuex会带来什么问题?
-
可维护性会下降,想修改数据要维护三个地方;
-
可读性会下降,因为一个组件里的数据,根本就看不出来是从哪来的;
-
增加耦合,大量的上传派发,会让耦合性大大增加,本来Vue用Component就是为了减少耦合,现在这么用,和组件化的初衷相背。
v-show和v-if指令的共同点和不同点
- v-show指令是通过修改元素的display的CSS属性让其显示或者隐藏
- v-if指令是直接销毁和重建DOM达到让元素显示和隐藏的效果
Vue中引入组件的步骤?
1)采用ES6的import … from …语法或CommonJS的require()方法引入组件
2)对组件进行注册,代码如下
// 注册
Vue.component('my-component', {
template: '<div>A custom component!</div>'
})
3)使用组件<my-component></my-component>
Vue生命周期
创建前/后: 在beforeCreate阶段,vue实例的挂载元素el和数据对象data都为undefined,还未初始化。在created阶段,vue实例的数据对象data有了,el还没有。
载入前/后:在beforeMount阶段,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换。在mounted阶段,vue实例挂载完成,data.message成功渲染。
更新前/后:当data变化时,会触发beforeUpdate和updated方法。
销毁前/后:在执行destroy方法后,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在
css是什么?在vue.cli中的安装使用步骤是?有哪几大特性?
css的预编译。
使用步骤:
第一步:先装css-loader、node-loader、sass-loader等加载器模块
第二步:在build目录找到webpack.base.config.js,在那个extends属性中加一个拓展.scss
第三步:在同一个文件,配置一个module属性
第四步:然后在组件的style标签加上lang属性 ,例如:lang=”scss”
特性:
- 可以用变量,例如($变量名称=值);
- 可以用混合器,例如()
- 可以嵌套
为什么避免 v-if 和 v-for 用在一起
当 Vue 处理指令时,v-for 比 v-if 具有更高的优先级,通过v-if 移动到容器元素,不会再重复遍历列表中的每个值。取而代之的是,我们只检查它一次,且不会在 v-if 为否的时候运算 v-for。
VNode是什么?虚拟 DOM是什么?
Vue在 页面上渲染的节点,及其子节点称为“虚拟节点 (Virtual Node)”,简写为“VNode”。“虚拟 DOM”是由 Vue 组件树建立起来的整个 VNode 树的称呼。
网络通信
url输入到浏览器到页面的呈现的过程
输入url网址
查看缓存
DNS解析域名获取IP
建立TCP连接(三次握手)
浏览器向服务器发出HTTP请求拿取数据包
服务器收到请求,返回数据
浏览器拿到数据进行页面渲染
关闭TCP连接(四次挥手)
三次握手四次挥手
三次握手:
第一次握手:客户端发送一个SYN码给服务器,要求建立数据连接;
第二次握手: 服务器SYN和自己处理一个SYN(标志);叫SYN+ACK(确认包);发送给客户端,可以建立连接
第三次握手: 客户端再次发送ACK向服务器,服务器验证ACK没有问题,则建立起连接;
四次挥手:
第一次挥手: 客户端发送FIN(结束)报文,通知服务器数据已经传输完毕;
第二次挥手: 服务器接收到之后,通知客户端我收到了SYN,发送ACK(确认)给客户端,数据还没有传输完成
第三次挥手: 服务器已经传输完毕,再次发送FIN通知客户端,数据已经传输完毕
第四次挥手: 客户端再次发送ACK,进入TIME_WAIT状态;服务器和客户端关闭连接;
http状态码有那些?分别代表是什么意思?
1xx:信息,请求收到,继续处理
2xx:成功,行为被成功地接受、理解和采纳
3xx:重定向,为了完成请求,必须进一步执行的动作
4xx:客户端错误,请求包含语法错误或者请求无法实现
5xx:服务器错误,服务器不能实现一种明显无效的请求
常见响应码含义:
200 OK 一切正常,对GET和POST请求的应答文档跟在后面。
301 Moved Permanently 客户请求的文档在其他地方,新的URL在Location头中给出,浏览器应该自动地访问新的URL。
400 Bad Request 请求出现语法错误。
404 Not Found 无法找到指定位置的资源。这也是一个常用的应答。
500 Internal Server Error 服务器遇到了意料不到的情况,不能完成客户的请求。
跨域
只要协议、域名、端口有任何一个不同,都被当作是不同的域。
由于浏览器的同源策略,其限制之一是不能通过ajax的方法情趣请求不同源的文档。第二个限制是浏览器中不同域的框架(iframe)间是不能进行js的交互操作的。
1、通过document.domain跨域
修改document.domain的方式只适用于不同子域的框架间的交互。
2、通过location.hash跨域
因为父窗口可以对iframe进行URL读写,iframe也可以读写父窗口的URL,URL有一部分被称为hash,就是#号及其后面的字符,它一般用于浏览器锚点定位,Server端并不关心这部分,应该说HTTP请求过程中不会携带hash,所以这部分的修改不会产生HTTP请求,但是会产生浏览器历史记录。此方法的原理就是改变URL的hash部分来进行双向通信。每个window通过改变其他 window的location来发送消息(由于两个页面不在同一个域下IE、Chrome不允许修改parent.location.hash的值,所以要借助于父窗口域名下的一个代理iframe),并通过监听自己的URL的变化来接收消息。这个方式的通信会造成一些不必要的浏览器历史记录,而且有些浏览器不支持onhashchange事件,需要轮询来获知URL的改变,最后,这样做也存在缺点,诸如数据直接暴露在了url中,数据容量和类型都有限等。
3、 通过HTML5的postMessage方法跨域
高级浏览器Internet Explorer 8+, chrome,Firefox , Opera 和 Safari 都将支持这个功能。这个功能主要包括接受信息的"message"事件和发送消息的"postMessage"方法。比如![img](file:///C:\Users\Administrator\AppData\Roaming\Tencent\QQTempSys\%W@GJ$ACOF(TYDYECOKVDYB.png)damonare.cn域的A页面通过iframe嵌入了一个![img](file:///C:\Users\Administrator\AppData\Roaming\Tencent\QQTempSys\[5UQ[BL(6~BS2JV6W}N6[%S.png)google.com域的B页面,可以通过以下方法实现A和B的通信
4、通过jsonp跨域
以上几种都是双向通信的,即两个iframe,页面与iframe或是页面与页面之间的,下面说几种单项跨域的(一般用来获取数据),因为通过script标签引入的js是不受同源策略的限制的。所以我们可以通过script标签引入一个js或者是一个其他后缀形式(如php,jsp等)的文件,此文件返回一个js函数的调用。
JSONP的优缺点
SONP的优点是:
它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果。
JSONP的缺点则是:
它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
5、通过CORS跨域
CORS(Cross-Origin Resource Sharing)跨域资源共享,定义了必须在访问跨域资源时,浏览器与服务器应该如何沟通。CORS背后的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
CORS与JSONP的对比
JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。
使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。
JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS)。
js时间线
1.创建Document对象,开始解析web页面,解析HTML元素和他们的文本内容后添加Element对象和Text节点到文档中,此时document.readyState = “loading”。
2.遇到link外部css,创建线程加载,并继续解析文档。
3.遇到script外部js,并且没有设置async , defer ,浏览器加载,并阻塞,等待js加载完成并执行该脚本,然后继续解析文档(同步加载,阻塞加载)
4.遇到script外部js,并且设置有async,defer 浏览器创建线程加载,并继续解析文档,对于async属性的脚本,脚本加载完成后立即执行,举例:<script src="" defer async></script>
5.遇到img标签等,先正常解析dom结构,然后浏览器异步加载src,并继续解析文档
6.当文档解析完成document.readyState === “interactive”
7.文档解析完成后,所有设置有defer的脚本会按照顺序执行。
8.当文档解析完成之后,document对象触发DOMContentLoaded事件,这也标志着程序执行从同步脚本执行阶段,转化为事件驱动阶段(这里DOMContentLoaded事件只能由dom的2级绑定就是事件监听触发)document.readyState === “interactive”
9.当所有saync的脚本加载完成并执行后,img等加载完成后,此时document.readyState === “complete”
window对象触发load事件document.readyState === “complete”
10.从此,页面以异步响应方式处理用户输入,网络事件等。