所以,变量可分为本地变量与全局变量:javascript
注意,函数提高由优先于变量提高,函数表达式不会提高。php
举个例子, var a = 2;JavaScript 引擎会把它分为两个单独的声明,分别是css
var a a = 2html
第一个是编译阶段的任务,而第二个则是执行阶段的任务。 不管做用域中的声明出如今什么地方,代码执行前首先进行编译处理。 能够将这个过程形象地想象成全部的声明(变量和函数)都会被“移动”到各自做用域的最顶端,这个过程被称为提高。前端
做用域是由书写代码时函数声明的位置来决定的。编译的词法分析阶段基本可以知道所有标识符在哪里以及是如何声明的,从而可以预测在执行过程当中如何对它们进行查找。html5
当函数能够记住并访问所在的词法做用域,即便函数是在当前词法做用域以外执行,这时就产生了闭包。java
闭包在实际开发中主要用于封装变量,收敛权限,使用场景:node
4.2.1函数做为返回值webpack
function isFirstLoad(){
var _list = []//私有变量
return function(id){
if (_list.indexOf(id)>=0){
return false
}else{
_list.push(id)
return true
}
}
}
var firstLoad = isFirstLoad()
firstLoad(10) //true
firstLoad(10) //false
firstLoad(20) //true
//在isFirstLoad函数外面,根本不能修改 _list 的值!
复制代码
4.2.2函数做为参数传递:es6
var fn;
function foo() {
var a = 2;
function baz() {
console.log( a );
}
fn = baz; // 将 baz 分配给全局变量
}
function bar() {
fn(); // 妈妈快看呀,这就是闭包!
}
bar(); // 2
复制代码
将内部函数传递到所在的词法做用域之外,它都会持有对原始定义做用域的引用,不管在何处执行这个函数都会使用闭包。
原型:Prototype 是个对象,只有函数上有。它是用来存储对象的属性(数据和方法)的地方,是实现JavaScript 原型继承的基础。
原型链:
__proto__
属性指向函数的原型对象(obj. __proto__=== Foo.Prototype
)// ES6 以前须要抛弃默认的 Bar.prototype
Bar.ptototype = Object.create( Foo.prototype ); // ES6 开始能够直接修改现有的 Bar.prototype Object.setPrototypeOf( Bar.prototype, Foo.prototype ); extends Object.getPrototype(); Object.setPrototype()等;
若是忽略掉 Object.create(..) 方法带来的轻微性能损失(抛弃的对象须要进行垃圾回 收),它实际上比 ES6 及其以后的方法更短并且可读性更高。不过不管如何,这是两种完 全不一样的语法
[[Prototype]] 机制就是存在于对象中的一个内部连接,它会引用其余对象。 一般来讲,这个连接的做用是:若是在对象上没有找到须要的属性或者方法引用,引擎就 会继续在 [[Prototype]] 关联的对象上进行查找。同理,若是在后者中也没有找到须要的 引用就会继续查找它的 [[Prototype]],以此类推。这一系列对象的连接被称为“原型链”。
当一个函数被调用时,会建立一个活动记录(有时候也称为执行上下文)。这个记录会包含函数在哪里被调用(调用栈)、函数的调用方法、传入的参数等信息。this就是记录的其中一个属性,会在函数执行的过程当中用到。
若是要判断一个运行中函数的 this 绑定,就须要找到这个函数的直接调用位置。找到以后 就能够顺序应用下面这四条规则来判断 this 的绑定对象。
- 由 new 调用?绑定到新建立的对象。
- 由 call或者apply(或bind)调用?绑定到指定的对象。
- 由上下文对象调用?绑定到那个上下文对象。
- 默认:在严格模式下绑定到 undefined,不然绑定到全局对象
ES6 中的箭头函数并不会使用以上四条标准的绑定规则,而是根据当前的词法做用域来决定 this,具体来讲,箭头函数会继承外层函数调用的 this 绑定(不管 this 绑定到什么)。
间接引用
function foo() {
console.log( this.a );
}
var a = 2;
var o = { a: 3, foo: foo };
var p = { a: 4 };
o.foo(); // 3
(p.foo = o.foo)(); // 2
复制代码
赋值表达式 p.foo = o.foo 的返回值是目标函数的引用,所以调用位置是 foo() 而不是p.foo() 或者 o.foo(),这里会应用默认绑定。
忽略的this
function foo() {
console.log( this.a );
}
var a = 2;
foo.call( null ); // 2
复制代码
若是你把 null 或者 undefined做为this的绑定对象传入call、apply或者bind,这些值在调用时会被忽略,实际应用的是默认绑定规则.
return的是基本类型:
function fn() {
this.user = '追梦子';
return 1;
}
var a = new fn;
console.log(a.user); //追梦子
复制代码
return的是对象:
function fn() {
this.user = '追梦子';
return function(){};
}
var a = new fn;
console.log(a.user); //undefined
复制代码
若是返回值是一个对象,那么this指向的就是那个返回的对象,若是返回值不是一个对象那么this仍是指向函数的实例。
#####6.5.1 call() 语法:
fun.call(thisArg, arg1, arg2, ...)
复制代码
1、使用call方法调用父构造函数:
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
Product.call(this, name, price);
this.category = 'food';
}
var cheese = new Food('feta', 5);//Food {name: "feta", price: 5, category: "food"}
复制代码
2、使用call方法调用函数而且指定上下文的'this'
function greet() {
var reply = [this.animal, 'typically sleep between', this.sleepDuration].join(' ');
console.log(reply); }
var obj = {
animal: 'cats', sleepDuration: '12 and 16 hours'
};
greet.call(obj); // cats typically sleep between 12 and 16 hours
复制代码
3、使用call方法调用函数而且没有肯定第一个参数,this的值将会被绑定为全局对象,严格模式下this的值将会是undefined。
语法:
func.apply(thisArg, [argsArray])
复制代码
/* 找出数组中最大/小的数字 */
var numbers = [5, 6, 2, 3, 7];
/* 应用(apply) Math.min/Math.max 内置函数完成 */
var max = Math.max.apply(null, numbers); /* 基本等同于 Math.max(numbers[0], ...)
var min = Math.min.apply(null, numbers)
复制代码
语法:
function.bind(thisArg[, arg1[, arg2[, ...]]])
复制代码
1、建立绑定函数
this.x = 9;
var module = {
x: 81,
getX: function() { return this.x; }
};
var retrieveX = module.getX;
retrieveX(); // 返回9
// 建立一个新函数,把 'this' 绑定到 module 对象
var boundGetX = retrieveX.bind(module);
boundGetX(); // 81
复制代码
2、预设的初始参数
function list() {
return Array.prototype.slice.call(arguments);
}
var leadingThirtysevenList = list.bind(null, 37);
var list = leadingThirtysevenList(1, 2, 3);
// [37, 1, 2, 3]
复制代码
以赋值的形式拷贝引用对象,仍指向同一个地址,修改时原对象也会受到影响
const originArray = [1,2,3,4,5];
const cloneArray = originArray;
console.log(cloneArray); // [1,2,3,4,5]
cloneArray.push(6);
console.log(cloneArray); // [1,2,3,4,5,6]
console.log(originArray); // [1,2,3,4,5,6]
复制代码
彻底拷贝一个新对象,修改时原对象再也不受到任何影响:
/*
JSON.parse 是将一个 JSON 字符串转成一个 JavaScript 值或对象
JSON.stringify 是将一个 JavaScript 值转成一个 JSON 字符串
*/
const originArray = [1,2,3,4,5];
const cloneArray = JSON.parse(JSON.stringify(originArray));
console.log(cloneArray === originArray); // false
复制代码
注意: 一、具备循环引用的对象时,报错; 二、当值为函数、undefined、或symbol时,没法拷贝;
const obj = { a: 1 };
const copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }
copy.a = 2
console.log(copy) //{ a: 2 }
console.log(obj) //{a: 1}
复制代码
当你发现任何代码开始写第二遍时,就要开始考虑如何复用。通常有如下的方式:
//c是目标,p是继承源
var inherit = (function(c,p){
//F函数是一个闭包,仅用作一个缓冲
var F = function(){};
return function(c,p){
F.prototype = p.prototype;
/*使对象C试图修改自身属性时仅仅是以F函数做为对象进行修改,而不会影响到其余对象 */
c.prototype = new F();
//令目标函数c知道本身的原型
c.uber = p.prototype;
c.prototype.constructor = c;
}
})();
复制代码
class/estends
String、Number、Boolean、object、Symbol、Null、Undefined
console.log(Math.abs(0.1+0.2-0.3)<=Number.EPSILON)
/*运算符提供了装箱操做,它会根据基础类型构造一个临时对象,使得咱们能在基础类型上调用对应对象的方法。*/
Symbol.prototype.hello = () => console.log("hello");
var a = Symbol("a");
console.log(typeof a); //symbol,a 并不是对象
a.hello(); //hello,有效
复制代码
JS 中在使用运算符号或者对比符时,会自带隐式转换,规则以下:
数字 + 字符串 = 字符串, 运算顺序是从左到右 数字 + 对象, 优先调用对象的valueOf -> toString 数字 +boolean/null -> 数字 数字 + undefined -> NaN
每一种基本类型 Number、String、Boolean、Symbol在对象中都有对应的类,所谓装箱转换,正是把基本类型转换为对应的对象。
全局的 Symbol 函数没法使用new来调用,但咱们仍可利用装箱机制来获得一个 Symbol 对象
var symbolObject = (function(){ return this; }).call(Symbol("a"));
console.log(typeof symbolObject); //object
console.log(symbolObject instanceof Symbol); //true
console.log(symbolObject.constructor == Symbol); //true
复制代码
若是两边类型不一样,会有隐式转换发生。总结以下: 1. 首先看双等号先后有没有NaN,若是存在NaN,一概返回false 2. 若是有true或false,转换为1或0,再比较。 3. 若是有引用类型,优先调用valueOf。 4. 数字和字符串,转化为数字再比较。 5. null和undefined,相等。 6. 5,其他都不相等。
console.log(undefined == false); // false
console.log(null == false); // false
console.log(0 == false); // true
console.log(NaN == false); // false
console.log("" == false); // true
/*
0 == false之因此为true根据第2条。
"" == false之因此为true根据第2条,变成了""==0,再根据第4条。*/
console.log([[2]] == '2') //true
/*
[[2]]的valueOf是对象自己,不是基本类型。尝试调用toString的结果是'2'。所以变成了'2'和数字2的比较。根据第2条,相等*/
复制代码
#####11.2.4 类型转换的6个假值 0/+0,-0,“”,false,undefined,NaN.
基本类型(null): 使用 String(null)
;
基本类型(string / number / boolean / undefined) + function: 直接使用 typeof
便可;
其他引用类型(Array / Date / RegExp /Error): 调用toString
通用但很繁琐的方法:prototype
alert(Object.prototype.toString.call(d) === ‘[object Date]') -------> true;
判断封装:
let class2type = {}
'Array Date RegExp Object Error'.split(' ').forEach(e => class2type[ '[object ' + e + ']' ] = e.toLowerCase())
function type(obj) {
if (obj == null) return String(obj)
return typeof obj === 'object' ? class2type[ Object.prototype.toString.call(obj) ] || 'object' : typeof obj
}
复制代码
一般,咱们在浏览器中使用ES6的模块化支持,在 Node 中使用 commonjs 的模块化支持,分类以下:
其中,require与import的区别:
因为 Babel 的强大和普及,如今 ES6/ES7 基本上已是现代化开发的必备了。经过新的语法糖,能让代码总体更为简洁和易读。
####13.3 class / extend: 类声明与继承
yield: //暂停代码
next(): //继续执行代码
function* helloWorld() {
yield 'hello';
yield 'world';
return 'ending';
}
const generator = helloWorld();
generator.next() // { value: 'hello', done: false }
generator.next() // { value: 'world', done: false }
generator.next() // { value: 'ending', done: true }
generator.next() // { value: undefined, done: true }
复制代码
async function getUserByAsync(){
let user = await fetchUser();
return user;
}
const user = await getUserByAsync()
console.log(user)
复制代码
柯里化是一种在多有参数被提供前,挂起或‘延迟’函数执行,将多参函数转化为一元函数序列的编程技术,本质是词法做用域(闭包)原理。
var add = function(x) {
return function(y) {
return function(z) {
return x + y + z;
}
}
}
var addOne = add(1);
var addOneAndTwo = addOne(2);
var addOneAndTwoAndThree = addOneAndTwo(3);
console.log(addOneAndTwoAndThree); //6
//非柯里化实现参数求和
let add = function(...arg) {
//得到参数数组
let _args = [].slice.call(arguments);
return _args.reduce((sum, i) => {
return sum + i;
});
};
console.log(add(1, 2, 3));//6
复制代码
XMLHttpRequest对象是浏览器提供的一个API,用来顺畅地向服务器发送请求并解析服务器响应,整个过程当中,浏览器页面不会被刷新。
XMLHttpRequest只是一个JavaScript对象,确切的说,是一个构造函数,它是由客户端(即浏览器)提供的(而不是JavaScript原生的),除此以外,它有属性,有方法,须要经过new关键字进行实例化。
const xhr = new XMLHttpRequest()
该实例的属性,方法有:
open() //准备启动一个AJAX请求;
setRequestHeader() //设置请求头部信息;
send() //发送AJAX请求;
getResponseHeader() //得到响应头部信息;
getAllResponseHeader() //得到一个包含全部头部信息的长字符串;
.abort() //取消异步请求;
复制代码
responseText //包含响应主体返回文本;
responseXML /*若是响应的内容类型时text/xml或application/xml,该属性将保存包含着相应数据的XMLDOM文档;*/
status //响应的HTTP状态;
statusText //HTTP状态的说明;
readyState //表示“请求”/“响应”过程的当前活动阶段
复制代码
另外,浏览器还为该对象提供了一个onreadystatechange监听事件,每当XML实例的readyState属性变化时,就会触发该事件的发生。其可取的值以下:
0:未初始化 -- 还没有调用.open()方法; 1:启动 -- 已经调用.open()方法,但还没有调用.send()方法; 2:发送 -- 已经调用.send()方法,但还没有接收到响应; 3:接收 -- 已经接收到部分响应数据; 4:完成 -- 已经接收到所有响应数据,并且已经能够在客户端使用了;
GET请求用于获取数据,有时候咱们须要获取的数据须要经过“查询参数”进行定位,在这种状况下,咱们会将查询参数追加到URL的末尾,令服务器解析。 const query = "example.php?name=tom&age=24"//"?name=tom&age=24"便是一个查询参数
POST请求用于向服务器发送应该被保存的数据,所以POST请求自然比GET请求多须要一份须要被保存的数据,发送的数据会做为.send()方法的参数最终被发往服务器。
须要注意,.send()
方法的参数是不可为空的,也就是说,对于不须要发送任何数据的GET请求,也须要在调用.send()方法时,向其传入null值;
.open()
方法接收三个参数:请求方式,请求URL地址和是否为异步请求的布尔值。
// 该段代码会启动一个针对“example.php”的GET同步请求。
xhr.open("get", "example.php", false)
复制代码
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if(xhr.readyState === 4 && xhr.status === 200){
alert(xhr.responseText);
}
}
xhr.open("get", "example.php", true)
xhr.send(null)
复制代码
注意:为了确保跨浏览器的兼容性,必需要在调用.open()方法以前指定事件处理程序。
所谓的单线程,即程序的执行顺序就是从上到下依次执行,同一时间内只能执行一段代码。
JavaScript是单线程的,可是浏览器内部是多线程的,其异步也得靠其余线程来监听事件的响应,并将回调函数推入到任务队列等待执行。
单线程所作的就是执行栈中的同步任务,执行完毕后,再从任务队列中取出一个事件(没有事件的话,就等待事件),而后开始执行栈中相关的同步任务,不断的这样循环。
一、定时器
console.log(100)
setTimeout(function(){
console.log(200)
},1000)
console.log(300)
//100
//300
//200
二、ajax请求
console.log('start')
$.get('test.json',function(data){
console.log(data)
})
console.log('end')
三、动态<img>加载
console.log('start')
var img = document.createElement('img')
img.onload = function(){
console.log('load')
}
img.src='https://ss0.baidu.com/'
console.log('end')
//start
//end
//load
四、事件绑定
console.log('start')
var btn1 = document.getElementById('btn1')
btn1.addEventListener('click',function () {
console.log('clicked')
})
console.log('end')
//start
//end
//click
复制代码
表示后续文档的加载和渲染与js脚本的加载和执行是并行进行的,即异步执行。
加载后续文档的过程和js脚本的加载(此时仅加载不执行)是并行进行的(异步),但js脚本的执行须要等到文档全部元素解析完成以后,DOMContentLoaded事件触发前执行。
区别 1.defer和async在网络加载过程是一致的,都是异步执行的; 2.二者的区别在于脚本加载完成以后什么时候执行,defer更符合大多数场景对应用脚本加载和执行的要求; 3.若是存在多个有defer属性的脚本,那么它们是按照加载顺序执行脚本的;而对于async,它的加载和执行是牢牢挨着的,不管声明顺序如何,只要加载完成就马上执行。
从2能够看出来:因为没有标准,不一样的浏览器实现同一功能,能够须要不一样的实现方式,就要考虑浏览器兼容性了。
从1能够看出来:DOM和文档有关,这里的文档指的是网页,也就是HTML文档,和浏览器无关。
javascript中有两种事件模型:DOM0,DOM2。
分为两种
1.行内
<input type="button" id="btn" value="按钮" onclick="alert('hello world!')">
复制代码
2.元素.on事件名=函数
document.getElementById("btn").onclick = function () {
alert('hello world!');
}
复制代码
注意,一个dom对象只能注册一个同类型的函数,注册多个同类型的函数的话,就会发生覆盖,以前注册的函数就会无效。
事件冒泡:当一个元素上的事件被触发的时候,好比说鼠标点击了一个按钮,一样的事件将会在全部祖先元素中被触发。
事件捕获和事件冒泡机制以下图
在DOM2级中使用addEventListener()
和removeEventListener()
来注册和解除事件(IE8及以前版本如下用attachEvent()
添加事件和detachEvent()
删除事件)。DOM2不会发生事件的覆盖,会依次的执行各个事件函数。 addEventListener('事件名称','回调','捕获(true)/冒泡(flase)')。示例以下:
<div id = 'outer' >
<div id="inner" ></div>
</div>
<script>
var click = document.getElementById('inner');
var clickouter = document.getElementById('outer');
click.addEventListener('click',function(event){
alert('inner show');
event.stopPropagation();
},false);
clickouter.addEventListener('click',function(){
alert('outer show');
},false);
</script>
复制代码
通常状况下,咱们在不添加stopPropagation()
阻止冒泡函数时,点击inner,会先弹出inner,再弹出outer。添加了stopPropagation()
函数以后,执行完inner的事件函数以后,就不会在执行outer的事件函数了
因为事件捕获阶段没有能够阻止事件的函数,因此通常都是设置为事件冒泡。
事件委托就是利用事件冒泡机制指定一个事件处理程序,来管理某一类型的全部事件。 即:利用冒泡的原理,把事件加到父级上,触发执行效果。 好处:
<ul id='ul'>
<li>111111</li>
<li>222222</li>
<li>333333</li>
</ul>
<button id='button'>添加元素</button>
window.onload = function(){
let oUl = document.getElementById('ul');
let aLi = oUl.getElementsByTagName('li');
let but = document.getElementById('button');
let now = 3;
oUl.onmouseover = function(e){
let ev = e || window.event;
let target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == 'li'){
target.style.background = 'red';
}
}
oUl.onmouseout = function(e){
let ev = e || window.event;
let target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == 'li'){
target.style.background = '';
}
}
but.onclick = function(){
now ++;
let newLi = document.createElement('li');
newLi.innerHTML = 111111 * now;
oUl.appendChild(newLi);
}
}
复制代码
经常使用的状态码。 • 200表示服务端成功响应。 • 301表示永久重定向。 • 302表示临时重定向。 • 403表示请求被拒绝。 • 404表示服务端找不到请求的资源。 • 500表示处理请求出错。503表示服务不可用 ,504 表示网关超时。
HTTP报文就是浏览器和服务器间通讯时发送及响应的数据块。 主要分为两部分 1.包含属性的首部(header)--------------------------附加信息(cookie,缓存信息等) 2.包含数据的主体部分(body)-----------------------HTTP请求真正想要传输的部分
http缓存能够理解为在服务端和客户端之间一个缓存数据库,你只须要设置一些参数便可实现,好比缓存/不缓存/时效内缓存/时效外缓存等(默认存在缓存)。缓存规则主要分为两类,即强制缓存和对比缓存。
对于强制缓存来讲,响应header中会有两个字段来标明失效规则Expires/Cache-Control
对比缓存,顾名思义,须要进行比较判断是否可使用缓存。 可分为2种标识:
Last-Modified:第一次请求时,服务器返回资源的最后修改时间; If-Modified-Since:再次请求时,浏览器通知服务器,上次请求时返回资源的最后修改时间。
若是Last-Modified小于等于If-Modified-Since,说明资源又被改动过,则响应整片资源内容,返回状态码200;不然,响应HTTP304,告知浏览器继续使用所保存的cache。
Etag:第一次请求时,服务器返回的资源惟一标识符(生成规则由服务器决定) If-None-Match:再次请求服务器时,浏览器通知服务器缓存数据的惟一标识。
若是Etag和If-None-Match不一样,说明资源又被改动过,则响应整片资源内容,返回状态码200;不然,响应HTTP304,告知浏览器继续使用所保存的cache。
浏览器第一次请求:
总之,对于强制缓存,服务器通知浏览器一个缓存时间,在缓存时间内,下次请求,直接用缓存,不在时间内,执行比较缓存策略。 对于比较缓存,将缓存信息中的Etag和Last-Modified经过请求发送给服务器,由服务器校验,返回304状态码时,浏览器直接使用缓存。
经过不缓存html,为静态文件添加MD5或者hash标识,解决浏览器没法跳过缓存过时时间主动感知文件变化的问题
webpack提供了webpack-md5-hash插件,能够帮助咱们在项目发布时自动修改文件标识。
CDN缓存提供了分流以及访问加速等优点条件,是能够经过登陆,手动更新CDN缓存的,变相解决了浏览器缓存没法手动控制的问题。
浏览器在获得用户请求以后,经历了下面这些阶段:重定向→拉取缓存→DNS查询→创建TCP连接→发起请求→接收响应→处理HTML元素→元素加载完成
一、首先,在浏览器地址栏中输入url
二、浏览器先查看浏览器缓存-系统缓存-路由器缓存,若是缓存中有,会直接在屏幕中显示页面内容。若没有,则跳到第三步操做。
三、域名解析(DNS解析),解析获取相应的IP地址。
四、浏览器经过三次握手与远程Web服务端来创建一个TCP/IP链接
五、握手成功后,浏览器向服务器发送http请求,请求数据包。
六、服务器处理收到的请求,将数据返回至浏览器。
七、浏览器进行HTML加载,加载完后开始解析
八、其余资源下载:html解析遇到外部资源,如css\js\图片,会启用其余线程下载资源。注意,当遇到的js文件,html解析会停下来,直到js文件下载并执行完后,从新开始html的解析工做。
九、Dom树构建:在html解析同时,解析器会把解析完的html 转化为DOM对象,再进一步构建出DOM 树。
十、CSSOM树构建:当CSS下载完,解析器对css进行并生产css对象,进一步构建成CSSOM树。
十一、渲染树:DOM树和CSSO树构建完成后,浏览器就会根据这两棵树构建一颗渲染树。
十二、布局计算:渲染树构建完成之后,全部元素的位置关系和应用样式就肯定了,这是浏览器会计算全部元素的大小和绝对位置。
1三、渲染:布局计算完成后,浏览器就能够在页面上渲染元素。通过渲染引擎的处理后,整个页面就显示在屏幕上。
HTTP是一种无状态的协议,为了分辨连接是谁发起的,需本身去解决这个问题。否则有些状况下即便是同一个网站每打开一个页面也都要登陆一下
Cookies是服务器在本地机器上存储的小段文本,即访问后网站的相关信息,它随每个请求发送至同一服务器,是在客户端保持状态的方案。 Cookie的主要内容包括:名字,值,过时时间,路径和域 ,数据大小不能超过4k。
与cookie相似,但不会自动把数据发给服务器,仅在本地保存,数据大小可达5M或以上。
• localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
• sessionStorage 数据在当前浏览器窗口关闭后自动删除。
复制代码
就是首先得到一个进入的URL请求而后把它从新写成网站能够处理的另外一个URL的过程。
隐藏域在页面中对于用户是不可见的,在表单中插入隐藏域的目的在于收集或发送信息,以利于被处理表单的程序所使用。浏览者单击发送按钮发送表单的时候,隐藏域的信息也被一块儿发送到服务器。
GET和POST是HTTP协议中发送请求的两种方法,它们的区别,简单的说: GET产生一个TCP数据包;POST产生两个TCP数据包。
也就是说:对于GET方式的请求,浏览器会把http的header和data一并发送出去,服务器响应200(返回数据);而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
具体差别可表现如下5个方面:
可分为三个方面,网络传输性能、页面渲染性能以及JS阻塞性能
在浏览器接收到服务器响应后,会检测响应头部(Header),若是有Etag字段,那么浏览器就会将本次缓存写入硬盘中。 注意,在构建阶段,须要为咱们的静态资源添加md5 hash后缀,避免资源更新而引发的先后端文件没法同步的问题。
对webpack进行上线配置时,咱们要特别注意如下几点:
- JS压缩:
new webpack.optimize.UglifyJsPlugin()
- HTML压缩:
- 使用
html-webpack-plugin
自动化注入JS
、CSS
打包HTML文件- 书写HTML元素的src 或 href 属性时,能够省略协议部分
- 提取公共资源: new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', filename: 'scripts/common/vendor-[hash:5].js' })
- 提取css并压缩
extract-text-webpack-plugin
- 服务器上开启Gzip传输压缩,但注意,不要对图片文件进行Gzip压缩
1.不要在HTML里缩放图像 2.使用雪碧图(CSS Sprite) 自动化生成雪碧图的工具 3.使用字体图标(iconfont); 4.使用WebP 是能够加快图片加载速度的图片格式,叉拍云 5.使用cdn 同时使用DNS预解析技术DNS Prefetch
主要是下降重排和重绘的频率和成本
1.CSS属性读写分离
2.经过切换class或者使用元素的style.csstext属性去批量操做元素样式。
3.DOM元素离线更新 例如
display:none
对元素隐藏,在元素“消失”后进行相关操做。
4.将没用的元素设为不可见:
visibility: hidden
5.压缩DOM的深度 一个渲染层内不要有过深的子元素,少用DOM完成页面样式,多使用伪元素或者box-shadow取代。
6.图片在渲染前指定大小 由于img元素是内联元素,因此在加载图片后会改变宽高,严重的状况会致使整个页面重排,因此最好在渲染前就指定其大小,或者让其脱离文档流。
在编程的过程当中,若是咱们使用了闭包后未将相关资源加以释放,或者引用了外链后未将其置空(好比给某DOM元素绑定了事件回调,后来却remove了该元素),都会形成内存泄漏的状况发生,进而大量占用用户的CPU,形成卡顿或死机。咱们可使用chrome提供的JavaScript Profile进行测试。
HTML元素的显示呈现为一个矩形,CSS标准中称之为Box。一个HTML元素占据空间的大小由盒模型决定。在盒模型中,一个盒子由内容content、内边距padding、边框border和外边距margin共同构成,其尺寸也是这四部分的尺寸之和。 盒模型是有两种标准: • 标准模型--盒模型的宽高只是内容(content)的宽高, • IE模型中--盒模型的宽高是内容(content)+填充(padding)+边框(border)的总宽高。
Normalize.css只是一个很小的css文件,它在HTML元素样式上提供了跨浏览器的高度一致性。相比于传统的CSS reset,Normalize.css是一种现代的、为HTML5准备的优质替代方案。 Normalize vs Reset
Reset经过为几乎全部的元素施加默认样式,强行使得元素有相同的视觉效果。相比之下,Normalize.css保持了许多磨人的浏览器样式。这就意味着你不用再为全部公共的排版元素从新设置样式。当一个元素在不一样的浏览器中有不一样的默认值时,Normalize.css会力求让这些样式保持一致并尽量与现代标准符合。
它修复了常见的桌面端与移动端浏览器的bug。这每每超出了Reset所能作到的范围。关于这一点,Normalize.css修复的问题包含了HTML5元素的显示设置、预格式化文字的font-size问题、在IE9中SVG的溢出、许多出如今各浏览器和操做系统中的与表单相关的bug。
使用Reset最让人困扰的地方莫过于在浏览器调试工具中大段大段的继承链,在Normalize.css中就不会有这样的问题。
这个项目已经被拆分为多个相关却又独立的部分,这使得你可以很容易也很清楚地知道哪些元素被设置了特定的值。所以这能让你本身选择性地移除掉某些永远不会用到的部分(好比表单的通常化)。
BFC 全称为 block formatting context,中文为“块级格式化上下文” 若是一个元素具备 BFC,内部子元素再怎么翻江倒海、翻 云覆雨,都不会影响外部的元素。
父元素设置text-align: center;
(只设置水平居中) 优势:是不用计算子元素尺寸。
子元素经过absolute
配合transform()
(一样适用于块级元素)
.child{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
复制代码
absolute
(一样适用于块级元素)
.child{
width: 100px;
height: 100px;
position: absolute;
top: 50%;
left: 50%;
margin-top: -50px; /*高度的一半*/
margin-left: -50px; /*宽度的一半*/
}
复制代码
注意,须要计算子元素宽高. 4. 父元素使用flex布局(一样适用于块级元素)
//方案一:配合使用 justify-content和 align-items属性
.father{
display: flex;
justify-content: center; /*水平居中*/
align-items: center; /*垂直居中*/
}
//方案二:子元素只用margin属性,若是浏览器不兼容flex属性,有回退做用
.father{
display: flex;
}
.child{
margin: auto;
}
复制代码
margin:0 auto
配合元素的width#center{
width: 100px;
margin: 0 auto;
}
复制代码
注意,当元素处于position:absolute;时,margin:0 auto无效,须要将right于left都设为0才能够,以下所示
#center{
width: 100px;
margin: 0 auto;
position:absolute;
right:0;
left:0;
}
复制代码
法2.3.4.同上
#main{
height: 200px;
line-height: 200px;
}
复制代码
缺点:须要固定父元素的height值,而且居中元素若是是多行文本将错乱。仅适合小元素,单行文本。
法2.3.4.同上。
两大基本方法
.clearfix:after{content:'';display:table;clear:both} //ie8+
.clearfix{*zoom:1;}
复制代码
2.父元素BFC
.lbf-content { overflow: hidden; }//IE7+
复制代码
ID选择器 > 类选择器|属性选择器|伪类 > 标签|伪元素 > 通配符
css规则由选择器和声明块组成:
css优先级就是经过选择器的特殊值计算的,选择器的特殊性值表述为4个部分,用0,0,0,0表示:
a{color: yellow;} /*特殊性值:0,0,0,1*/
div a{color: green;} /*特殊性值:0,0,0,2*/
.demo a{color: black;} /*特殊性值:0,0,1,1*/
.demo input[type="text"]{color: blue;} /*特殊性值:0,0,2,1*/
.demo *[type="text"]{color: grey;} /*特殊性值:0,0,2,0*/
#demo a{color: orange;} /*特殊性值:0,1,0,1*/
div#demo a{color: red;} /*特殊性值:0,1,0,2*/
复制代码
选择器特殊性值是从左向右排序的,也就是1,0,0,0大于以0开头的全部特殊性值,行间样式的特殊性是1,0,0,0,比ID选择器优先级高。
假如特殊性相同的两条规则应用到同一个元素,css会先查看规则的权重(!important),加了权重的优先级最高;当权重相同的时候,css规则会按顺序排序,后声明的规则优先级高。
例如,伪类,:link、:visited、:hover、:active,都遵循“爱恨原则LVHA”(LoVe HAte),特殊性值相同,后声明的规则优先级高,就能够覆盖前面的。
• 文档元信息:一般是出如今head标签种,包含了描述文档自身的一些信息,诸如 title、meta、style、link、base ; • 语义相关:扩展了纯文本,表达文章结构、不一样语言要素的标签,诸如 section、nav 的标签; • 连接:提供到文档内和文档外的的连接; • 替换型标签:引入声音、图片、视频等外部元素替换自身的一类标签; • 表单:用于填写和提交信息的一类标签; • 表格:表头、表尾、单元格等表格的结构。
语义化标签是纯文本的补充,好比标题,天然段,章节等,这些内容是纯文字没法表达的,咱们就须要语义标签表达.
正确使用优势以下: • 便于团队维护和开发 • 去掉css样式后网页结构完整 • 便于阅读机器阅读,适合搜索引擎检索seo
相反,错误地使用语义标签,会给机器阅读形成混淆、增长嵌套,给 Css编写加剧负担。 但现代互联网产品里,HTML用于描述“软件界面”多过于“富文本",而软件界面里的东西,实际上几乎是没有语义的。好比说,咱们作了一个购物车功能,必定要用给商品套上ul吗?好比,加入购物车的按钮,必定要用button吗?
实际上,我认为是不必,由于这个场景里,跟文本的列表以及表单的button,已经相差很远了。因此,在软件界面,能够直接用div和span。
在移动浏览器中使用viewport元标签控制布局,包含如下内容:
<meta name="viewport" content="with=device-with,initial-scale=1,maximum-scale=1">
复制代码
HTML5不基于SGML,所以不须要对DTD进行引用,可是须要doctype来规范浏览器的行为 因此,html5只有一种:<!DOCTYPE> 可是html4.01有三种,分别是strict、transitional、frameset。
实现上:h5再也不是SGML的子集。 一、新特性:主要是关于图像,位置,存储,多任务等功能的增长,如: • 绘画canvas • 用于媒介回放的video和audio元素 • 本地离线存储localStorage,长期存储,浏览器关闭以后数据不丢失 sessionStorage的数据在浏览器关闭后自动删除 • 语意化更好的内容元素,好比 article、footer、header、nav、section • 表单控件,calendar、date、time、email、url、search; • 新的技术webworker, websocket, Geolocation; 二、移除的元素: 纯表现的元素:basefont,big,center,font, s,strike,tt,u; 对可用性产生负面影响的元素:frame,frameset,noframes; 三、处理兼容性: • IE8/IE7/IE6支持经过document.createElement方法产生的标签,能够利用这一特性让这些浏览器支持HTML5新标签,浏览器支持新标签后,还须要添加标签默认的样式。 • 使用html5shim,可让IE9或更低版本能支持html5 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
• 行内元素有:a,b,span,img(我曾觉得是block),input,strong,select
• 块级元素有:div、ul(无序)、ol(有序)、li、p等
• 空元素:<br><hr><link><script>
空元素定义:html元素的内容就是其两个标签之间的content,因此,标签之间没有内容的就是空元素
复制代码
link
和@import
的区别写法上:
<link rel="stylesheet" href="路径" />
<style type="text/css">
@import '路径'
</style>
复制代码
本质上:link属于XHTML标签,除了加载css以外,还能定义RSS,定义rel链接属性等做用。而@import是css提供的,只能用于加载css; 解析上:link是跟着页面加载同时加载的,可是@import会等到页面加载完再加载 兼容上:@import IE5以上才能识别,link无限制