1、应用层DNS解析域名:客户端先检查本地是否有对应的IP地址,若找到则返回响应的IP地址。若没找到则请求上级DNS服务器,直至找到或到根节点。
2、浏览器与服务器建立TCP连接(默认端口80)(详细点可以说下三次握手的过程)
3、应用层客户端发送HTTP请求。
4、服务器响应请求:查找客户端请求的资源,并返回响应报文,响应报文中包括一个重要的信息——状态码(200-300,成功;304使用缓存)。
5、服务器返回相应文件给浏览器。
6、Tcp连接释放(可以说下四次挥手的过程)。
7、浏览器对HTML文件进行解析构建DOM树 ,构建渲染树 ,js根据DomAPI操作执行绑定事件等,页面显示完成。
TCP协议简介
以太网协议:子网内部点对点通信
IP协议:局域网互通,路由功能
TCP协议:保证数据通信的完整性和可靠性,防止丢包
三次握手(TCP连接建立):
1.C向S发出连接请求,进入同步已发送状态,S在监听状态
2.S向C发出确认报文,进入同步接受状态
3.C向S发出确认报文,进入建立连接状态,S收到也进入建立连接状态
四次挥手(TCP连接释放)
1.C向S发出连接释放报文,进入终止等待1状态
2.S接收,S向C发出确认报文,进入关闭等待状态
3.C接收,进入终止等待2状态
4.S向C发出连接释放报文,进入最后确认状态
5.C接收,C向S发出确认报文,进入时间等待状态,等待2∗MSL时长,进入关闭状态
6.S接收,进入关闭状态
1、float
2、flex
3、table
var CookieUtil={
// 获取,每个cookie都是一个名称/值对,名称/值对用“=”连接,
//如果要一次存储多个名称/值对,可以使用分“;”隔开
get:function(name){
// 在cookie的名或值中不能使用分号(;)、逗号(,)、等号(=)以及
//空格。如果想存入这些值,我们可以使用encodeURIComponent()
//函数进行编码
let cookieName=encodeURIComponent(name);
let cookieStr=document.cookie;
let arr1=cookieStr.split(";");
for(let i=0;i
同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
同源策略限制以下几种行为:
1.) Cookie、LocalStorage 和 IndexDB 无法读取
2.) DOM 和 Js对象无法获得
3.) AJAX 请求不能发送
解决方案:
1、 通过jsonp(只支持get请求t,本质通过script标签引入,callback)
2、 document.domain + iframe(不同子域框架交互,document.domain都设成相同主域名)
3、 location.hash + iframe(改变URL的hash部分来进行双向通信)
4、 window.name + iframe(windowd. name重点内容是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。)
5、 HTML5的postMessage(targetIframe.postMessage(message, targetOrigin))
6、 跨域资源共享(CORS)(使用自定义的HTTP头部让浏览器与服务器进行沟通,设置Access-Control-Allow-Origin,可通过Ajax进行跨域)
7、 nginx代理跨域
8、 nodejs中间件代理跨域
9、 WebSocket协议跨域(Socket.io)
方案详解1
方案详解2
jQuery中提供了四种事件监听方式,分别是bind、live、delegate、on,对应的解除监听的函数分别是unbind、die、undelegate、off
bind()函数只能针对已经存在的元素进行事件的设置;但是live(),on(),delegate()均支持未来新添加元素的事件设置;
bind()函数在jquery1.7版本以前比较受推崇,1.7版本出来之后,官方已经不推荐用bind(),替代函数为on(),这也是1.7版本新添加的函数,同样,可以用来代替live()函数,live()函数在1.9版本已经删除;
live()函数和delegate()函数两者类似,但是live()函数在执行速度,灵活性和CSS选择器支持方面较delegate()差些。
推荐使用on()
on()方法绑定事件可以提升效率
多个事件绑定同一个函数;多个事件绑定不同函数;绑定自定义事件;绑定多个选择器,多个事件
on()方法可以绑定动态添加到页面元素的事件
选择器部分
特效部分1:圆角,阴影,渐变:border-radius、box-shadow 、text-shadow、 -webkit-gradient
特效部分2:背景,边框背景: background-origin/clip/size、border-image
特效部分3: 变形:transform、translate、rotate、scale、transition-origin/property/duratio/timing-function
特效部分4:动画:animation-name/duration/timing-function/delay/iteration-count/direction
1、自动适应屏幕宽度(viewport)
2、使用框架搭建页面
bootstrap等
3、 宽度的严格布局书写
auto或者%
4、图片自适应
5、屏幕适配布局问题
/* 标准模型 */
box-sizing:content-box;
/*IE模型*/
box-sizing:border-box;
dom.offsetWidth/offsetHeight
边距重叠
父元素没有设置margin-top,而子元素设置了margin-top;则父元素也一起有了边距。
边距重叠解决方案(BFC)
Block Formatting Context 直译为“块级格式化上下文”
怎么取创建bfc
float属性不为none(脱离文档流)
position为absolute或fixed
display为inline-block,table-cell,table-caption,flex,inine-flex
overflow不为visible
根元素
应用场景
自适应两栏布局
清除内部浮动
防止垂直margin重叠
早在 HTTP 建立之初,主要就是为了将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器。
HTTP1.1和HTTP1.0的一些区别
1、缓存处理,header引入了更多的缓存控制策略
2、带宽优化及网络连接的使用,支持断点续传
3、错误通知的管理,错误状态响应码
4、Host头处理,一台物理服务器上可以存在多个虚拟主机,并且它们共享一个IP地址
5、长连接,支持长连接和请求的流水线处理,在一个TCP连接上可以传送多个HTTP请求和响应,不用每次请求都要创建连接,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive
http2 和http1.1之间的区别
1、HTTP/2采用二进制格式而非文本格式
2、HTTP/2是完全多路复用的,而非有序并阻塞的——只需一个连接即可实现并行
3、使用header压缩,HTTP/2降低了开销
4、服务端推送,HTTP/2让服务器可以将响应主动“推送”到客户端缓存中
HTTP2.0的多路复用和HTTP1.X中的长连接复用有什么区别
1、HTTP1. 一次请求-响应,建立一个连接,用完关闭;每一个请求都要建立一个连接;
2、 HTTP1.1 Pipeling解决方式为,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某请求超时等,后续请求只能被阻塞,毫无办法,也就是人们常说的线头阻塞;
3、 HTTP2 多个请求可同时在一个连接上并行执行。某个请求任务耗时严重,不会影响到其它连接的正常执行;
HTTPS与HTTP的一些区别
1、HTTPS协议需要到CA申请证书,一般免费证书很少,需要交费。
2、HTTP协议运行在TCP之上,所有传输的内容都是明文,HTTPS运行在SSL/TLS之上,SSL/TLS运行在TCP之上,所有传输的内容都经过加密的。
3、HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、HTTPS可以有效的防止运营商劫持,解决了防劫持的一个大问题。
##HTTP
HTTP(hypertext transport protocol), 即超文本传输协议.这个协议详细规定了浏览器和万维网服务器之间互相通信的规则.。
URL:统一资源定位符,就是一个网址:协议名://域名:端口/路径,例如:http://www.oldboy.cn:80/index.html
消息格式
首行 //请求消息和响应消息中具体格式略有区别,下面介绍
头部 //头部用来指出http消息的一些属性,它们有固定的格式
正文 //传输的实际内容
请求消息的结构
请求行 、请求头部 、请求正文
Method(方法|basic-path[?query-string](路径)|http/version(http版本)
-----------------------------------------------
Header name1 : value
...
Header nameN : value
-----------------------------------------------
-----------------------------------------------
request body(optional)
1、请求行
请求方法:GET/POST/DELETE/HEAD/PUT/OPTIONS/TRACE/CONNECT
请求路径:basic-path[?query-string]
请求url:协议://域名:端口/虚拟目录/文件部分?参数部分#锚
http://www.aspxfans.com:8080/news/index.asp
?boardID=5&ID=24618&page=1#name
2、请求头部
请求头与响应头
Accept:告诉服务器,客户端支持的数据类型。
Accept-Charset:告诉服务器,客户端采用的编码。
Accept-Encoding:告诉服务器,客户机支持的数据压缩格式。
Accept-Language:告诉服务器,客户机的语言环境。
Host:客户机通过这个头告诉服务器,想访问的主机名。
If-Modified-Since:客户机通过这个头告诉服务器,资源的缓存时间。
Referer:客户机通过这个头告诉服务器,它是从哪个资源来访问服务器的。(一般用于防盗链)
User-Agent:客户机通过这个头告诉服务器,客户机的软件环境。
Cookie:客户机通过这个头告诉服务器,可以向服务器带数据。
Connection:客户机通过这个头告诉服务器,请求完后是关闭还是保持链接。
Date:客户机通过这个头告诉服务器,客户机当前请求时间。
3、请求正文
当使用GET方法发送请求的时候,请求体是空的
响应消息的结构
响应行 、 响应头部 、 响应正文
http/version number | status code | message
-----------------------------------------------
Header name 1: value
header name 2: value
...
-----------------------------------------------
-----------------------------------------------
response body(optional)
1、响应行
版本号 :http版本目前有四个:HTTP0.9 、 HTTP1.0 、HTTP1.1 、 HTTP2
状态码 :HTTP状态码主要表示应答的状态。状态码由三位数字组成,第一个数字定义了响应的类别,后面两个数字表示该大状态的一个子状态。
1XX 提示信息类 - 表示请求已被成功接收,继续处理
2XX 响应成功类 - 表示请求已被成功接收,理解,接受
3XX 重定向类 - 要完成请求必须进行更进一步的处理
4XX 客户端错误类 - 请求有语法错误或请求无法实现
5XX 服务器端错误类 - 服务器未能实现合法的请求
200 ok:
最常见的就是成功响应状态码200了, 这表明该请求被成功地完成,
所请求的资源发送回客户端。上面打开项目主页的实例中就是200
304 not modified:
假如我们打开主页后在浏览器中刷新,就会看到响应的状态码变成了304,
这代表之前响应的html文档已经被缓存了,服务器端相同的文档没有变化,
可以继续使用缓存的文档,因此304响应没有response body部分
302 found:
重定向,新的URL会在response header中的Location中返回,浏览器将
会自动使用新的URL发出新的Request,假如我们在登录页提交登录表单发
送一个POST请求进行登录,就会得到一个302响应并且重定向到/index路
径下
404 not found:
请求资源不存在(输错了URL,或者服务器端现在没有这个页面了)
500 Internal Server Error:
服务器发生了不可预期的错误,这个一般在会在服务器的程序码出错时发生
状态文本
2、响应头部
请求头与响应头
Location:这个头配合302状态码使用,告诉用户端找谁。
Server:服务器通过这个头,告诉浏览器服务器的类型。
Content-Encoding:服务器通过这个头,告诉浏览器数据采用的压缩格式。
Content-Length:服务器通过这个头,告诉浏览器回送数据的长度。
Content-Language:服务器通过这个头,告诉服务器的语言环境。
Content-Type:服务器通过这个头,回送数据的类型
Last-Modified:服务器通过这个头,告诉浏览器当前资源的缓存时间。
Refresh:服务器通过这个头,告诉浏览器隔多长时间刷新一次。
Content-Disposition:服务器通过这个头,告诉浏览器以下载的方式打开数据。
Transfer-Encoding:服务器通过这个头,告诉浏览器数据的传送格式。
ETag:与缓存相关的头。
Expires:服务器通过这个头,告诉浏览器把回送的数据缓存多长时间。-1或0不缓存。
Cache-Control和Pragma:服务器通过这个头,也可以控制浏览器不缓存数据。
Connection:服务器通过这个头,响应完是保持链接还是关闭链接。
Date:告诉客户机,返回响应的时间。
3、相应正文
Flex是Flexible Box的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。任何一个容器都可以指定为Flex布局。Webkit内核的浏览器,必须加上-webkit前缀。子元素的float、clear和vertical-align属性将失效。采用Flex布局的元素,称为Flex容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为Flex项目(flex item),简称"项目"。
容器
项目
柯里化是指将使用多个参数的函数转换成一系列使用一个参数的函数的技术。
柯里化的用途主要
// 通用版
// 首先将参数进行分割,也就是将除了func之外的参数存进args。
// 返回的函数接受新传入的参数并与之前的参数合并,
//从而将所有的参数传入函数中,并执行真正的函数。
var curry1=function(func){
// []相当于Array,数组
// [].slice()是一个函数,返回数组某一段
// .call()是函数slice本身的方法,第一个参数是指定函数
//执行时的this指针,第二个是参数
// 所以相当于arguments.slice(1)
// arguments是传入的参数数组,但不是真正数组,需要借助数组的slice方法
var args=[].slice.call(arguments,1);
return function(){
// connect参数合并
var newArgs=args.concat([].slice.call(arguments));
// 执行
return func.apply(this,newArgs);
}
}
function add1(a,b){
return a+b;
}
var addCurry1=curry1(add1);
console.log(addCurry1(1,2));
addCurry1=curry1(add1,1,2);
console.log(addCurry1());
addCurry1=curry1(add1,1,);
console.log(addCurry1(2));
// 改进版
// 若传入的参数没有到达两个的话,就继续调用curry,继续接受参数。
//若参数到达2个了,就直接调用add函数。
var curry2=function(func,args){
var len=func.length;
args=args||[];
return function(){
var newArgs=args.concat([].slice.call(arguments));
if(newArgs.length
Function.prototype.bind=function(othis){
var args=Array.prototype.slice.call(arguments,1);
var ftobind=this;
var result=function(){
return ftobind.apply(
othis,args.concat(Array.prototype.slice.call(arguments))
);
}
var temp=function(){};
temp.prototype=this.prototype;
result.prototype=new temp();
return result;
};
var A={
name:'lorogy',
print:function(title){
console.log(title+'!'+this.name);
}
};
A.print('Hello');
var func=A.print;
func('Hello');
var funcc=A.print.bind(A);
funcc('Hello');
// Hello!lorogy
// Hello!undefined
// Hello!lorogy
OOP
即Object Oriented Programming,面向对象编程,是计算机的一种编程架构,OOP的一条基本规则是,计算机程序由能够起到子程序作用的单个或对象组合而成。包含属性和方法的对象是类的实例,而JS中没有类的概念,而是直接使用对象实现编程任务。
特性:
构造函数
只有函数对象才有 prototype属性 。函数对象是由function创造出来的函数或者系统内置的函数对象(Function,Object,Array,String,Number)。
函数也是对象的一种,所以继承了对象原型,可以对其添加属性和方法,构造函数也是函数,所以用自定义函数的方式,并将首字母大写以明确是构造函数即可,可以用new操作符创建函数实例验证。
prototype
即原型对象,每创建一个函数都会有一个prototype属性,这个属性是一个指针,指向一个对象,这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。
特性:让所有对象实例共享原型对象所包含的属性和方法
constructor
constructor 属性返回对创建此对象的函数对象的引用。
原型链
function Fun(){}
//我创造了一个函数Fn
//这个函数由Function生成(Function作为构造函数)
var fn=new Fun()
//我创建了一个函数fn
//这个函数由Fn生成(Fn作为构造函数)
console.log(fn.__proto__===Fun.prototype) //true
//fn的__proto__指向其构造函数Fun的prototype
console.log(Fun.__proto__===Function.prototype) //true
//Fun的__proto__指向其构造函数Function的prototype
console.log(Function.__proto__===Function.prototype) //true
//Function的__proto__指向其构造函数Function的prototype
//构造函数自身是一个函数,他是被自身构造的
console.log(Function.prototype.__proto__===Object.prototype) //true
//Function.prototype的__proto__指向其构造函数Object的prototype
//Function.prototype是一个对象,同样是一个方法,方法是函数,
//所以它必须有自己的构造函数也就是Object
console.log(Fun.prototype.__proto__===Object.prototype) //true
//与上条相同
//此处可以知道一点,所有构造函数的的prototype方法的__都
//指向__Object.prototype(除了....Object.prototype自身)
console.log(Object.__proto__===Function.prototype) //true
//Object作为一个构造函数(是一个函数对象!!函数对象!!),
//所以他的__proto__指向Function.prototype
console.log(Object.prototype.__proto__===null) //true
//Object.prototype作为一切的源头,他的__proto__是null
//下面是一个新的,额外的例子
var obj={}
//创建了一个obj
console.log(obj.__proto__===Object.prototype)//true
//obj作为一个直接以字面量创建的对象,所以obj__proto__直接指向了
//Object.prototype,而不需要经过Function了!!
//下面是根据原型链延伸的内容
//还有一个上文并未提到的constructor, constructor在原型链中,
//是作为对象prototypr的一个属性存在的,它指向构造函数
//(由于主要讲原型链,这个就没在意、);
console.log(obj.__proto__.__proto__===null)
//true
console.log(obj.__proto__.constructor===Object)
//true
console.log(obj.__proto__.constructor.__proto__
===Function.prototype)
//true
console.log(obj.__proto__.constructor.__proto__.
__proto__===Object.prototype)
//true
console.log(obj.__proto__.constructor.__proto__.
__proto__.__proto__===null)
//true
console.log(obj.__proto__.constructor.__proto__.
__proto__.constructor.__proto__===Function.prototype)
//true
object.hasOwnProperty(proName); //如果该属性或者方法是该 对象自身定义的而不是器原型链中定义的 则返回true;否则返回false;
object1.isPrototypeOf(object2); //判断指定对象object1是否存在于另一个对象object2的原型链中,是则返回true,否则返回false。
实例
js继承和继承基础总结
父类代码
// 父类
function Fn(name){
this.name=name;
this.sleep=function(){
console.log(this.name+' is sleeping');
}
}
Fn.prototype.eat=function(food){
console.log(this.name+' is eating '+food);
};
1、原型链继承
// 原型链继承,父类的实例为子类的原型
function Subfn1(){}
Subfn1.prototype=new Fn();
Subfn1.prototype.name='sub1';//必须在 new fn()之后
var subfn1=new Subfn1();
console.log(subfn1.name);//sub1
subfn1.eat('1');//sub1 is eating 1
subfn1.sleep();//sub1 is sleeping
console.log(subfn1 instanceof Fn);//true
console.log(subfn1 instanceof Subfn1);//true
特点:
缺点:
推荐指数:★★(3、4两大致命缺陷)
2、构造继承
// 构造继承,使用父类的构造函数来增强子类实例,
//等于是复制父类的实例属性给子类(没用到原型)
function Subfn2(name){
Fn.call(this);
this.name=name||'sub2';
}
var subfn2=new Subfn2();
console.log(subfn2.name);//sub2
//subfn2.eat('2');//subfn2.eat is not a function
subfn2.sleep();//sub2 is sleeping
console.log(subfn2 instanceof Fn);//false
console.log(subfn2 instanceof Subfn2);//true
特点:
缺点:
推荐指数:★★(缺点3)
3、实例继承
// 实例继承,为父类实例添加新特性,作为子类实例返回
function Subfn3(name){
var instance=new Fn();
instance.name=name||'sub3';
return instance;
}
var subfn3=new Subfn3();
console.log(subfn3.name);//sub3
subfn3.eat('3');//sub3 is eating 3
subfn3.sleep();//sub3 is sleeping
console.log(subfn3 instanceof Fn);//true
console.log(subfn3 instanceof Subfn3);//false
特点:
缺点:
推荐指数:★★
4、拷贝继承
// 拷贝继承
function Subfn4(name){
var fn=new Fn();
for(var p in fn){
Subfn4.prototype[p]=fn[p];
}
Subfn4.prototype.name=name||'sub4';
}
var subfn4=new Subfn4();
console.log(subfn4.name);//sub4
subfn4.eat('4');//sub4 is eating 4
subfn4.sleep();//sub4 is sleeping
console.log(subfn4 instanceof Fn);//false
console.log(subfn4 instanceof Subfn4);//true
特点:
缺点:
推荐指数:★(缺点1)
5、组合继承
// 组合继承,通过调用父类构造,继承父类的属性并保留传参的优点,
//然后通过将父类实例作为子类原型,实现函数复用
function Subfn5(name){
Fn.call(this);
this.name=name||'sub5';
}
Subfn5.prototype=new Fn();
Subfn5.prototype.constructor=Subfn5;
var subfn5=new Subfn5();
console.log(subfn5.name);//sub5
subfn5.eat('5');//sub5 is eating 5
subfn5.sleep();//sub5 is sleeping
console.log(subfn5 instanceof Fn);//true
console.log(subfn5 instanceof Subfn5);//true
特点:
缺点:
推荐指数:★★★★(仅仅多消耗了一点内存)
6、寄生组合继承
// 寄生组合继承,通过寄生方式,砍掉父类的实例属性,这样,
//在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,
//避免的组合继承的缺点
function Subfn6(name){
Fn.call(this);
this.name=name||'sub6';
}
(function (){
var Super=function(){};
Super.prototype=Fn.prototype;
Subfn6.prototype=new Super();
Subfn6.prototype.constructor=Subfn6;
})();
var subfn6=new Subfn6();
console.log(subfn6.name);//sub6
subfn6.eat('6');//sub6 is eating 6
subfn6.sleep();//sub6 is sleeping
console.log(subfn6 instanceof Fn);//true
console.log(subfn6 instanceof Subfn6);//true
特点:
堪称完美
缺点:
实现较为复杂
推荐指数:★★★★(实现复杂,扣掉一颗星)
浅拷贝和深拷贝都只针对于像Object, Array这样的复杂对象,
浅拷贝:浅拷贝是拷贝引用,拷贝后的引用都是指向同一个对象的实例,彼此之间的操作会互相影响
深拷贝:在堆中重新分配内存,并且把源对象所有属性都进行新建拷贝,以保证深拷贝的对象的引用图不包含任何原有对象或对象图上的任何对象,拷贝后的对象与原来的对象是完全隔离,互不影响
// 浅拷贝
// 浅拷贝
let obj = {
nNum : 1,
sName : 'aaron'
};
function shallowCopy(o) {
let result = {};
for(let item in o) {
if(o.hasOwnProperty(item)) {
result[item] = o[item];
};
};
return result;
};
console.log(shallowCopy(obj));//{ nNum: 1, sName: 'aaron' }
// $.extend({} , obj);//jquery
console.log(Object.assign({} , obj));//es6
// 深拷贝
obj = {
nNum : 1,
oAar : [1,2,3,4]
};
let newObj = shallowCopy(obj);
console.log(newObj === obj); // false
console.log(newObj.oAar === obj.oAar); // true,引用的同一地址
console.log(newObj);//{ nNum: 1, oAar: [ 1, 2, 3, 4 ] }
newObj.oAar.push(5);
console.log(obj);//{ nNum: 1, oAar: [ 1, 2, 3, 4, 5 ] }
console.log(newObj);//{ nNum: 1, oAar: [ 1, 2, 3, 4, 5 ] }
function deepCopy(o,temp){
let result=temp||{};
for(let item in o){
if((typeof o[item])==='object'&&o[item]!==null){
//typeof null==='object'
result[item]=(o[item].constructor===Array)?[]:{};
//针对数组情况,result初始化应为[]而不是{}
result[item]=deepCopy(o[item],result[item]);
}else{
result[item]=o[item];
}
}
return result;
}
newObj = deepCopy(obj);
//$.extend(true, {}, obj)//jquery
console.log(newObj === obj); // false
console.log(newObj.oAar === obj.oAar); // false
console.log(newObj);
newObj.oAar.push(6);//{ nNum: 1, oAar: [ 1, 2, 3, 4, 5 ] }
console.log(obj);//{ nNum: 1, oAar: [ 1, 2, 3, 4, 5 ] }
console.log(newObj);//{ nNum: 1, oAar: [ 1, 2, 3, 4, 5, 6 ] }
和C#、Java一样JavaScript有自动垃圾回收机制,也就是说执行环境会负责管理代码执行过程中使用的内存,在开发过程中就无需考虑内存分配及无用内存的回收问题了。
内存泄露是指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束。
typeof [var]
//string/number/object/function
[var] instanceof [String/Number/Array/Function/Error]
//true/false
[var].constructor==[String/Number/Array/Function/Error]
//true/false
Object.prototype.toString.call([var])==
"[object String/Number/Array/Date/Function/Error]"
//true/false
[pattern].test([string]);//true/false
[pattern].exec([string]);//返回匹配数组
[string].match([pattern]);//返回匹配数组
[string].search([pattern]);//返回索引
[string].replace([pattern],[newstring]);//更改,替换
[string].split([pattern],[len]);
//返回以[pattern]为间隔的len长的数组
return this
(function(){
function _$(eles){
this.elements=[];
for(let i=0;i
事件委托——给父元素绑定事件,用来监听子元素的冒泡事件,并找到是哪个子元素的事件。适用于当子元素有很多,需要对子元素的时间进行监听的时候。
优点:
event.target
window.onload = function(){
var oUl = document.getElementById("ul");
oUl.onclick = function(ev){
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == 'li'){
alert(target.innerHTML);
}
}
}
CDN的全称是Content Delivery Network,即内容分发网络。其目的是通过在现有的Internet中增加一层新的网络架构,将网站的内容发布到最接近用户的网络”边缘”,使用户可 以就近取得所需的内容,解决Internet网络拥挤的状况,提高用户访问网站的响应速度。从技术上全面解决由于网络带宽小、用户访问量大、网点分布不均 等原因所造成的用户访问网站响应速度慢的问题。
由于不同厂商的流览器或某浏览器的不同版本(如IE6-IE11,Firefox/Safari/Opera/Chrome等),对CSS的支持、 解析不一样,导致在不同浏览器的环境中呈现出不一致的页面展现效果。这时,我们为了获得统一的页面效果,就需要针对不同的浏览器或不同版本写特定的CSS 样式,我们把这个针对不同的浏览器/不同版本写相应的CSS code的过程,叫做CSS hack!
分类
CSS Hack大致有3种表现形式,CSS属性前缀法、选择器前缀法以及IE条件注释法(即HTML头部引用if IE)Hack,实际项目中CSS Hack大部分是针对IE浏览器不同版本之间的表现差异而引入的。
,针对IE6及以下版本: string
var sdata=storage.getItem('data');
console.log(JSON.parse(sdata));//string-->json
}else{
console.log("浏览器不支持localStorage");
}
GET - 从指定的资源请求数据;POST - 向指定的资源提交要被处理的数据
GET 方法
请注意,查询字符串(名称/值对)是在 GET 请求的 URL 中发送的:
/test/demo_form.asp?name1=value1&name2=value2;
POST 方法
请注意,查询字符串(名称/值对)是在 POST 请求的 HTTP 消息主体中发送的:
POST /test/demo_form.asp HTTP/1.1;
Host: w3schools.com; name1=value1&name2=value2;
GET |
POST |
|
后退按钮/刷新 |
无害 |
数据会被重新提交(浏览器应该告知用户数据会被重新提交)。 |
书签 |
可收藏为书签 |
不可收藏为书签 |
缓存 |
能被缓存 |
不能缓存 |
编码类型 |
application/x-www-form-urlencoded |
application/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码。 |
历史 |
参数保留在浏览器历史中。 |
参数不会保存在浏览器历史中。 |
对数据长度的限制 |
是的。当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。 |
无限制。 |
对数据类型的限制 |
只允许 ASCII 字符。 |
没有限制。也允许二进制数据。 |
安全性 |
与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。在发送密码或其他敏感信息时绝不要使用 GET ! |
POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。 |
可见性 |
数据在 URL 中对所有人都是可见的。 |
数据不会显示在 URL 中。 |
新特性
兼容问题
IE8/IE7/IE6支持通过document.createElement方法产生的标签,可以利用这一特性让这些浏览器支持HTML5新标签,浏览器支持新标签后,还需要添加标签默认的样式。当然也可以直接使用成熟的框架、比如html5shim
显示 联系:label的for与input的id要一致
隐式联系:input放在label内
button submit reset checkbox radio text password email tel url file number range date datetime datetime-local month week time image hidden search color
属性 |
描述 |
accept-charset |
字符集,"utf-8" |
action |
提交表单的地址(URL),"[].php" |
autocomplete |
浏览器应该自动完成表单(默认:开启)。 |
enctype |
被提交数据的编码(默认:url-encoded),“application/x-www-form-urlencoded” |
method |
提交表单时所用的 HTTP 方法(默认:GET)。 |
name |
识别表单的名称(对于 DOM 使用:document.forms.name)。 |
novalidate |
浏览器不验证表单。 |
target |
规定 action 属性中地址的目标(默认:_self),"_blank" |
vue
不是一个框架,因为它只聚焦视图层,是一个构建数据驱动的Web界面的库
与angular相比:都是双向数据绑定,但学习成本低,不够成熟
与react相比:都是组件思想,但学习成本低,不够成熟
angular
一款优秀的前端JS框架,已经被用于Google的多款产品当中
完善、强大、丰富
入门容易深入难
react
主要用于构建UI,采用特殊的JSX语法
速度快、模块化、单向数据流、兼容性、社区丰富
学习曲线陡峭
.clearfix::before,.clearfix::after {
content: ".";
display: block;
height: 0;
visibility: hidden;
}
.clearfix:after {clear: both;}
.clearfix {zoom: 1;}
浏览器内核可以分为两部分,一部分是渲染引擎(render engineer或layout engineer);另一部分是JS引擎。
渲染引擎:负责取得网页的内容(HTML、XML、图像等等)、整理讯息(例如加入CSS等),以及计算网页的显示方式,然后会输出至显示器或打印机。
浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。所有网页浏览器、电子邮件客户端以及其它需要编辑、显示网络内容的应用程序都需要内核。
JS引擎:解析和执行javascript来实现网页的动态效果。
最开始渲染引擎和JS引擎并没有区分的很明确,后来JS引擎越来越独立,内核就倾向于只指渲染引擎。
1、Trident ([‘traɪd(ə)nt])
Trident是IE的内核,也就是国内双核浏览器的内核之一。Trident内核一直延续到IE11,IE11的后继者Edge采用了新内核EdgeHTML。
2、 Gecko ([‘gekəʊ])(开源)
Gecko是Netscape6Z开始采用的内核,是一个开源内核,后来被FF(FireFox)采用。
3、Webkit(开源)
Webkeit的鼻祖是Safari, 其前身是KDE(Linux的桌面系统)的KHTML(开源的)。Webkit也是开源的。
注意:Webkit其实包括是渲染引擎Webcore(前身是KHTML),以及JS引擎JSCore
4、Chromium(Blink,V8)(开源)
chromium fork自webkit,代码可读性和编译速度得到提升。值得一提是谷歌专门研发了自己的JS引擎——V8,极大地提高了JS的运算速度。由于chromium也是开源的,所以搜狗、QQ、360都用chromium内核。
自13年4月后,谷歌开始在Chromium项目中研发Blink渲染引擎,之前一直用的是Webkit的渲染引擎。之所以研发独立的渲染引擎,是因为苹果推出的Webkit2与chromium的设计存在冲突,影响了chromium的架构移植工作。
5、Presto ([‘prestəʊ])(已废弃)
自Opera7.0开始使用。13年2月后为了减少研发成本,放弃Presto,采用
chromium,之后也紧跟Blink的脚步。
浏览器:IE,Chrome,Safar,FireFoxi,Opera。
内核:Trident,Webkit,Gecko,Presto。
一个程序至少有一个进程,一个进程至少有一个线程。
JavaScript 运行机制详解:再谈Event Loop
JS是单线程语言
JS需要异步
JS通过事件循环(event loop)在单线程上实现异步
console.log(1)//同步,主线
setTimeout(function(){
console.log(2)
},0)//异步,放入事件列表,0秒后推入事件队列,主线空闲
console.log(3)//同步,主线
//132
setTimeout(function(){
console.log('定时器开始啦')
});//异步,事件列表,宏任务
new Promise(function(resolve){
console.log('马上执行for循环啦');
//同步,主线程,直接执行,宏任务
for(var i = 0; i < 10000; i++){
i == 99 && resolve();
}
}).then(function(){
console.log('执行then函数啦')//异步,事件列表,微任务
});
console.log('代码执行结束');//同步,主线程,直接执行,宏任务
//马上执行for循环啦 --- 代码执行结束
//--- 执行then函数啦 --- 定时器开始啦
macro-task(宏任务):包括整体代码script,setTimeout,setInterval
micro-task(微任务):Promise,process.nextTick
首先执行script下的宏任务,遇到setTimeout,将其放到宏任务的【队列】里
遇到 new Promise直接执行,打印"马上执行for循环啦"
遇到then方法,是微任务,将其放到微任务的【队列里】
打印 "代码执行结束"
本轮宏任务执行完毕,查看本轮的微任务,发现有一个then方法里的函数,
打印"执行then函数啦"
到此,本轮的event loop 全部完成。
下一轮的循环里,先执行一个宏任务,发现宏任务的【队列】里有一个
setTimeout里的函数,执行打印"定时器开始啦"
setTimeout(function(){
console.log('执行了')
},3000)
3秒后,会执行setTimeout里的那个函数,这准说法并不严谨,应该是
3秒后,setTimeout里的函数被会推入event queue,而event queue(事件队列)里的任务,只有在主线程空闲时才会执行
1、DOM:Document Object Model,浏览器将HTML解析成树形的数据结构,简称DOM。
2、CSSOM:CSS Object Model,浏览器将CSS代码解析成树形的数据结构。
3、DOM 和 CSSOM 都是以 Bytes → characters → tokens → nodes → object model.这样的方式生成最终的数据。如下图所示:
DOM树的构建过程是一个深度遍历过程:当前节点的所有子节点都构建好后才会去构建当前节点的下一个兄弟节点。
4、Render Tree:DOM 和 CSSOM 合并后生成 Render Tree,如下图:
Render Tree 和DOM一样,以多叉树的形式保存了每个节点的css属性、节点本身属性、以及节点的孩子节点。
浏览器渲染的整个流程
1、 首先当用户输入一个URL的时候,浏览器就会发送一个请求,请求URL对应的资源。
2、 然后浏览器的HTML解析器会将这个文件解析,并且构建成一棵DOM树。
3、 在构建DOM树的时候,遇到JS和CSS元素,HTML解析器就换将控制权转让给JS解析器或者是CSS解析器。
4、 JS解析器或者是CSS解析器解析完这个元素时候,HTML又继续解析下个元素,直到整棵DOM树构建完成。
5、 DOM树构建完之后,浏览器把DOM树中的一些不可视元素去掉,然后与CSSOM合成一棵render树。
6、 接着浏览器根据这棵render树,计算出各个节点(元素)在屏幕的位置。这个过程叫做layout,输出的是一棵layout树。
7、 最后浏览器根据这棵layout树,将页面渲染到屏幕上去。
// 获取URL后面的参数变为对象
(function(){
var urlToObject=function(url){
var urlObject={};
if(/\?/.test(url)){
var urlString=url.substring(url.indexOf("?")+1);
var urlArray=urlString.split("&");
for (var i = 0; i < urlArray.length; i++) {
var urlItem=urlArray[i];
var item=urlItem.split("=");
urlObject[item[0]]=item[1];
}
}
return urlObject;
}
var testUrl="http://tools.jb51.net/index.php?key0=0&key1=1"
var result=urlToObject(testUrl);
console.log(result);
})();
行内元素:会在水平方向排列,不能包含块级元素,设置width无效,height无效(可以设置line-height),margin上下无效,padding上下无效。
块级元素:各占据一行,垂直方向排列。从新行开始结束接着一个断行。
兼容性:
//*zoom:1作用是 在IE下触发hasLayout
//*display:inline作用是 一旦触发了hasLayout
//设置display:inline和display:block效果相似。
display:inline-block;
*display:inline;
*zoom:1;
box-sizing: content-box|border-box|inherit;
content-box:宽度和高度分别应用到元素的内容框。在宽度和高度之外绘制元素的内边距和边框(元素默认效果)。
border-box:元素指定的任何内边距和边框都将在已设定的宽度和高度内进行绘制。通过从已设定的宽度和高度分别减去边框和内边距才能得到内容的宽度和高度。
告知浏览器的解析器用什么文档标准解析这个文档。DOCTYPE不存在或格式不正确会导致文档以兼容模式呈现。
标准模式的排版和JS运作模式都是以该浏览器支持的最高标准运行。
兼容模式中,页面以宽松的向后兼容的方式显示,模拟老式浏览器的行为以防止站点无法工作。
HTML5不基于 SGML,因此不需要对DTD进行引用,但是需要doctype来规范浏览器的行为(让浏览器按照它们应该的方式来运行)。
HTML4.01基于SGML,所以需要对DTD进行引用,才能告知浏览器文档所使用的文档类型。
六大数据类型
Undefined、Null、Boolean、Number、String、Object
五大基本类型
Undefined、Null、Boolean、Number、String
三大引用类型
Object、Array、Function
本地对象:
Date、Number、 Boolean、String、Array、RegExp、Function、Object
内置对象:
Global、Math
null是一个表示"无"的对象,转为数值时为0;undefined是一个表示"无"的原始值,转为数值时为NaN。
undefined:
(1)变量被声明了,但没有赋值时,就等于undefined。
(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。
(3)对象没有赋值的属性,该属性的值为undefined。
(4)函数没有返回值时,默认返回undefined。
null:
(1) 作为函数的参数,表示该函数的参数不是对象。
(2) 作为对象原型链的终点。
(1)创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
(2)属性和方法被加入到 this 引用的对象中。
(3)新创建的对象由 this 所引用,并且最后隐式的返回 this 。
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它是基于JavaScript的一个子集。数据格式简单, 易于读写, 占用带宽小。
格式:采用键值对,例如:{‘age’:‘12’, ‘name’:‘back’}
它的功能是把对应的字符串解析成JS代码并运行;
应该避免使用eval,不安全,非常耗性能(2次,一次解析成js语句,一次执行)。
由JSON字符串转换为JSON对象的时候可以用eval,var obj =eval(’(’+ str +’)’)。
创建新节点
createDocumentFragment() //创建一个DOM片段
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点
添加、移除、替换、插入
appendChild()
removeChild()
replaceChild()
insertBefore() //在已有的子节点前插入一个新的子节点
查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值
getElementById() //通过元素Id,唯一性
apply()函数有两个参数:第一个参数是上下文,第二个参数是参数组成的数组。如果上下文是null,则使用全局对象代替。
如:function.apply(this,[1,2,3]);
call()的第一个参数是上下文,后续是实例传入的参数序列。
如:function.call(this,1,2,3);
User Agent是Http协议中的一部分,属于头域的组成部分,User Agent也简称UA。通俗地讲,UA是一种向访问网站提供你所使用的浏览器类型、操作系统、浏览器内核等信息的标识。通过这个标识,用户所访问的网站可以显示不同的排版,从而为用户提供更好的体验或者进行信息统计。
(function whatBrowser(){
console.log("浏览器名称:"+navigator.appName);
console.log("版本号:"+navigator.appVersion);
console.log("代码名称:"+navigator.appCodeName);
console.log("用户代理标识:"+navigator.userAgent);
})()
//判断访问终端
var browser={
versions:function(){
var u = navigator.userAgent, app = navigator.appVersion;
return {
trident: u.indexOf('Trident') > -1,
//IE内核
presto: u.indexOf('Presto') > -1,
//opera内核
webKit: u.indexOf('AppleWebKit') > -1,
//苹果、谷歌内核
gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1,
//火狐内核
mobile: !!u.match(/AppleWebKit.*Mobile.*/),
//是否为移动终端
ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/),
//ios终端
android: u.indexOf('Android') > -1 || u.indexOf('Adr') > -1,
//android终端
iPhone: u.indexOf('iPhone') > -1 ,
//是否为iPhone或者QQHD浏览器
iPad: u.indexOf('iPad') > -1,
//是否iPad
webApp: u.indexOf('Safari') == -1,
//是否web应该程序,没有头部与底部
weixin: u.indexOf('MicroMessenger') > -1,
//是否微信 (2015-01-22新增)
qq: u.match(/\sQQ/i) == " qq"
//是否QQ
};
}(),
language:(navigator.browserLanguage || navigator.language)
.toLowerCase()
}
//判断是否IE内核
if(browser.versions.trident){ alert("is IE"); }
//判断是否webKit内核
if(browser.versions.webKit){ alert("is webKit"); }
//判断是否移动端
if(browser.versions.mobile||browser.versions.android
||browser.versions.ios){ alert("移动端"); }
(1) 减少http请求次数:CSS Sprites, JS、CSS源码压缩、图片大小控制合适;网页Gzip,CDN托管,data缓存 ,图片服务器。
(2) 前端模板 JS+数据,减少由于HTML标签导致的带宽浪费,前端用变量保存ajax请求结果,每次操作本地变量,不用请求,减少请求次数
(3) 用innerHTML代替DOM操作,减少DOM操作次数,优化javascript性能。
(4) 当需要设置的样式很多时设置className而不是直接操作style。
(5) 少用全局变量、缓存DOM节点查找的结果。减少IO读取操作。
(6) 避免使用CSS Expression(css表达式)又称Dynamic properties(动态属性)。
(7) 图片预加载,将样式表放在顶部,将脚本放在底部 加上时间戳。
优雅降级:web站点在所有新式浏览器中都能正常工作,如果用户使用的是老式浏览器,则代码会检查以确认它们是否能正常工作。
由于IE独特的盒模型布局问题,针对不同版本的IE的hack实践过优雅降级了,为那些无法支持功能的浏览器增加候选方案,使之在旧式浏览器上以某种形式降级体验却不至于完全失效。
渐进增强:从被所有浏览器支持的基本功能开始,逐步地添加那些只有新式浏览器才支持的功能,向页面增加无害于基础浏览器的额外样式和功能的。当浏览器支持时,它们会自动地呈现出来并发挥作用。