我的前端进阶之路

React和Vue对比


相同点:

数据驱动视图,提供了响应式(Reactive)和组件化(Composable)的视图组件。

都有Virtual DOM,组件化开发,通过props参数进行父子组件数据的传递,都实现webComponents规范

数据流动单向

都支持服务端渲染

都有支持native的方案,React的React native,Vue的weex

不同点:

社区:React社区还是要比Vue大很多;

开发模式:React在view层侵入性还是要比Vue大很多的,React严格上只针对MVC的view层,Vue则是MVVM模式的一种实现;

数据绑定:Vue有实现了双向数据绑定,React数据流动是单向的

数据渲染:对于大规模数据渲染,React要比Vue更快,渲染机制启动时候要做的工作比较多;

数据更新方面:Vue 由于采用依赖追踪,默认就是优化状态:你动了多少数据,就触发多少更新,不多也不少。React在复杂的应用里有两个选择:

(1). 手动添加 shouldComponentUpdate 来避免不需要的 vdom re-render。

(2). Components 尽可能都用 pureRenderMixin,然后采用 redux 结构 + Immutable.js;

开发风格的偏好:React 推荐的做法是 JSX + inline style,也就是把 HTML 和 CSS 全都写进 JavaScript 了,即”all in js”;Vue进阶之后推荐的是使用 webpack + vue-loader 的单文件组件格式,即html,css,js写在同一个文件;

使用场景:React配合Redux架构适合超大规模多人协作的复杂项目;Vue则适合小快灵的项目。对于需要对 DOM 进行很多自定义操作的项目,Vue 的灵活性优于 React;

Vue要比React更好上手,具体可能体现在很多人不熟悉React的JSX语法和函数式编程的思想,以及想要发挥出React的最大威力需要学习它一系列生态的缘故;

Vue着重提高开发效率,让前端程序员更快速方便的开发应用。React着重于变革开发思想,提升前端程序员编程的深度与创造力,让前端工程师成为真正的程序员而不是UI的构建者;

gulp和webpack区别


gulp是一种工具,我们可以用它来优化前端的工作流程,比如自动刷新页面、combo、压缩css、js、编译less等等。具体体现为:在gulp的配置文件中书写一个个的task,webpack则是一种打包工具,或者说是一种模块化解决方案,实际上很大一部分人刚开始使用webpack的方式就是通过gulp-webpack这个插件,写好task来使用webpack对前端的一些文件进行打包;

gulp的处理任务需要自己去写,webpack则有现成的解决方案,只需要在webpack.config.js配置好即可;

事件模型


1、事件捕获阶段(capturing phase)。事件从document一直向下传播到目标元素, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行。

2、事件处理阶段(target phase)。事件到达目标元素, 触发目标元素的监听函数。

3、事件冒泡阶段(bubbling phase)。事件从目标元素冒泡到document, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行。

js中event的target和currentTarget的区别

arget:触发事件的元素。点了那个标签获取哪个标签

currentTarget:事件绑定的元素。

currentTarget始终是监听事件者,而target是事件的真正发出者

两者在没有冒泡的情况下,是一样的值,但在用了事件委托的情况下,就不一样了,例如:


我的前端进阶之路_第1张图片

事件捕获阶段:事件从最上一级标签开始往下查找,直到捕获到事件目标(target)。

事件冒泡阶段:事件从事件目标(target)开始,往上冒泡直到页面的最上一级标签


我的前端进阶之路_第2张图片

DOM事件流:同时支持两种事件模型:捕获型事件和冒泡型事件,但是,捕获型事件先发生。两种事件流会触及DOM中的所有对象,从document对象开始,也在document对象结束

假设一个元素div,它有一个下级元素p。

     

元素

这两个元素都绑定了click事件,如果用户点击了p,它在div和p上都触发了click事件,那这两个事件处理程序哪个先执行呢?事件顺序是什么?

两种模型

以前,Netscape和Microsoft是不同的实现方式。

Netscape中,div先触发,这就叫做事件捕获。

Microsoft中,p先触发,这就叫做事件冒泡。

两种事件处理顺序刚好相反。IE只支持事件冒泡,Mozilla, Opera 7 和 Konqueror两种都支持,旧版本的Opera's 和 iCab两种都不支持 。

事件捕获

当你使用事件捕获时,父级元素先触发,子级元素后触发,即div先触发,p后触发。

事件冒泡

当你使用事件冒泡时,子级元素先触发,父级元素后触发,即p先触发,div后触发。

W3C模型

W3C模型是将两者进行中和,在W3C模型中,任何事件发生时,先从顶层开始进行事件捕获,直到事件触发到达了事件源元素。然后,再从事件源往上进行事件冒泡,直到到达document。

程序员可以自己选择绑定事件时采用事件捕获还是事件冒泡,方法就是绑定事件时通过addEventListener函数,它有三个参数,第三个参数若是true,则表示采用事件捕获,若是false,则表示采用事件冒泡。

ele.addEventListener('click',doSomething2,true)

true=捕获

false=冒泡

传统绑定事件方式

在一个支持W3C DOM的浏览器中,像这样一般的绑定事件方式,是采用的事件冒泡方式。

ele.onclick = doSomething2

IE浏览器

如上面所说,IE只支持事件冒泡,不支持事件捕获,它也不支持addEventListener函数,不会用第三个参数来表示是冒泡还是捕获,它提供了另一个函数attachEvent。

ele.attachEvent("onclick", doSomething2);

附:事件冒泡(的过程):事件从发生的目标(event.srcElement||event.target)开始,沿着文档逐层向上冒泡,到document为止。

事件的传播是可以阻止的:

• 在W3c中,使用stopPropagation()方法

• 在IE下设置cancelBubble = true;

在捕获的过程中stopPropagation();后,后面的冒泡过程也不会发生了~

3.阻止事件的默认行为,例如click 后的跳转~

• 在W3c中,使用preventDefault()方法;

• 在IE下设置window.event.returnValue = false;

浏览器缓存机制


可参考地址:浏览器缓存机制

Expires策略

Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。Expires 是HTTP 1.0的东西,现在默认浏览器均默认使用HTTP 1.1,所以它的作用基本忽略。

Cache-Control策略

Cache-Control与Expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓读取数据还是重新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires

以上是设置缓存时间的两种方法。那么当缓存时间过了咋整呢?有人肯定说了,那就再次发起请求啊,这是对的。问题是如果服务器资源并没有更新呢?比如说我有一个jQuery.js文件已经缓存了,当它的缓存时间到了之后服务器的jQuery.js文件也没有更新,那实际上我们直接使用本地缓存的文件就可以啊!没必要浪费带宽和时间去重新请求一个新的文件啊!这时候我们就需要再进一步看一下HTTP协议里这几个参数的作用了。

Last-Modified/If-Modified-Since

首先Last-Modified/If-Modified-Since要配合Cache-Control使用。

Last-Modified:标示这个响应资源的最后修改时间。web服务器在响应请求时,告诉浏览器资源的最后修改时间(这个参数是和Cache-Control一起过来的)。

If-Modified-Since:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Last-Modified声明,则再次向web服务器请求时带上头If-Modified-Since,表示请求时间。web服务器收到请求后发现有头If-Modified-Since ,则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被改动过,则响应整片资源内容(写在响应消息包体内),HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应HTTP 304 (无需包体,节省浏览),告知浏览器继续使用所保存的cache。

ETag/If-None-Match

Etag/If-None-Match也要配合Cache-Control使用。

Etag:web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器觉得)。Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。

If-None-Match:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求时带上头If-None-Match(Etag的值)。web服务器收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,决定返回200或304。

ETag和Last-Modified

HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:

Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间

如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存

有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形

Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。


我的前端进阶之路_第3张图片

Ajax的状态值与HTTP状态码


Ajax的状态值

0: (未初始化)还没有调用open()方法;

1: (载入)已经调用open()方法,正在派发请求,send()方法还未被调用;

2: (载入完成)send()已经调用,响应头和响应状态已经返回;

3: (交互)响应体下载中; responseText中已经获取了部分数据;

4: (完成)响应内容已经解析完成,用户可以调用。

HTTP状态码

200 & OK: 请求成功;

204 & No Content: 请求处理成功,但没有资源可以返回;

206 & Partial Content: 对资源某一部分进行请求(比如对于只加载了一般的图片剩余部分的请求);

301 & Move Permanently: 永久性重定向;

302 & Found: 临时性重定向;

303 & See Other: 请求资源存在另一个URI,应使用get方法请求;

304 & Not Modified: 服务器判断本地缓存未更新,可以直接使用本地的缓存;

307 & Temporary Redirect: 临时重定向;

400 & Bad Request: 请求报文存在语法错误;

401 & Unauthorized: 请求需要通过HTTP认证;

403 & Forbidden: 请求资源被服务器拒绝,访问权限的问题;

404 & Not Found: 服务器上没有请求的资源;

500 & Internal Server Error: 服务器执行请求时出现错误;

502 & Bad Gateway: 错误的网关;

503 & Service Unavailable: 服务器超载或正在维护,无法处理请求;

504 & Gateway timeout: 网关超时;

什么是原型链


详细地址:原型链详解

访问一个对象的属性时,先在基本属性中查找,如果没有,再沿着__proto__这条链向上找,这就是原型链。

​ 在执行代码之前,把将要用到的所有的变量都事先拿出来,有的直接赋值了,有的先用undefined占个空——执行上下文环境。

​ 作用域链,是由当前环境与上层环境的一系列变量对象组成,它保证了当前执行环境对符合访问权限的变量和函数的有序访问。

​ 每一个对象都会在内部链接到另一个对象(该对象的原型对象),该对象有一个原型prototype,当访问对象的属性或是方法的时候,不仅仅会在原对象上查找,还会顺着原型链在原型对象的原型链上查找,直到查到null(所有原型链的顶层)为止。原型是JavaScript实现继承的基础,new关键字做的主要的事情就是将实例对象的__proto__属性指向原型对象的prototype。

什么是闭包


闭包是javascript支持头等函数的一种方式,它是一个能够引用其内部作用域变量(在本作用域第一次声明的变量)的表达式,这个表达式可以赋值给某个变量,可以作为参数传递给函数,也可以作为一个函数返回值返回。

闭包是函数开始执行的时候被分配的一个栈帧,在函数执行结束返回后仍不会被释放(就好像一个栈帧被分配在堆里而不是栈里!)

闭包的应用:

比如写柯里化函数的时候利用闭包,保存参数在内存中;

varcurrying =function(fun){

//格式化arguments

varargs =Array.prototype.slice.call(arguments,1);

returnfunction(){

//收集所有的参数在同一个数组中,进行计算

var_args = args.concat(Array.prototype.slice.call(arguments));

returnfun.apply(null, _args);

    };

}

图片懒加载与预加载


图片懒加载的原理就是暂时不设置图片的src属性,而是将图片的url隐藏起来,比如先写在data-src里面,等某些事件触发的时候(比如滚动到底部,点击加载图片)再将图片真实的url放进src属性里面,从而实现图片的延迟加载

图片预加载,是指在一些需要展示大量图片的网站,实现图片的提前加载。从而提升用户体验。常用的方式有两种,一种是隐藏在css的background的url属性里面,一种是通过javascript的Image对象设置实例对象的src属性实现图片的预加载。相关代码如下:

CSS预加载图片方式:

#preload-01{background:url(http://domain.tld/image-01.png) no-repeat -9999px-9999px; }

#preload-02{background:url(http://domain.tld/image-02.png) no-repeat -9999px-9999px; }

#preload-03{background:url(http://domain.tld/image-03.png) no-repeat -9999px-9999px; }

Javascript预加载图片的方式:

functionpreloadImg(url){

varimg =newImage();

img.src = url;

if(img.complete) {

//接下来可以使用图片了

//do something here

}else{

img.onload =function(){

//接下来可以使用图片了

//do something here

};

}

}

跨域


跨域的方式有很多种,最常用的是jsonp主要利用了script的开放策略:通过script标签引入一个js或者是一个其他后缀形式(如php,jsp等)的文件,此文件返回一个js函数的调用。缺点在于只支持get请求而且存在安全问题,可能会导致CSRF,因为请求的数据来源于其他网站,因为恶意攻击者可以利用这段代码进行请求,获取数据,有可能会泄露用户密码等重要信息

关于cors在维基百科上的定义是这样的:跨域资源共享(CORS )是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源。而这种访问是被同源策略所禁止的。CORS系统定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。它是一个妥协,有更大的灵活性,但比起简单地允许所有这些的要求来说更加安全。

CORS跨域,关键在于服务器,如果服务器实现了CORS跨域的接口,那么就可以使用ajax(请求路径为绝对路径)进行跨域请求。CORS请求分为两种,一种是简单请求,一种是非简单请求。简单请求是指请求方法在HEAD,GET,POST三者之间并且请求头信息局限在

Accept

Accept-Language

Content-Language

Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

非简单请求请求头:

(1)Access-Control-Request-Method

该字段是必须的,用来列出浏览器的CORS请求会用到哪些HTTP方法

(2)Access-Control-Request-Headers

该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段

执行简单请求的时候,浏览器会在请求头信息增加origin字段,服务器据此来判断请求域名是否在许可范围之内,来决定是否返回Access-Control-Allow-Origin字段。响应头有以下几种:

(1)Access-Control-Allow-Origin

该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。

(2)Access-Control-Allow-Credentials

该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。

(3)Access-Control-Expose-Headers

该字段可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。

(4)Access-Control-Max-Age

Access-Control-Max-Age首部字段指明了预检请求的响应的有效时间。

(5)Access-Control-Allow-Methods

Access-Control-Allow-Methods首部字段用于预检请求的响应。其指明了实际请求所允许使用的 HTTP 方法。

(6)Access-Control-Allow-Headers

Access-Control-Allow-Headers首部字段用于预检请求的响应。其指明了实际请求中允许携带的首部字段。

其他方法:document.domin,html5的postMessage,window.name等

函数节流和函数防抖


函数节流让指函数有规律的进行调用,应用场景:window.resize,游戏中子弹发射(1s只能发射一颗子弹)等;

函数防抖让函数在”调用’’之后的一段时间后生效,应用场景:输入框(例:在用户停止输入的500ms后再处理用户数据)。

//函数节流

/*

* @params {Function} fun 调用函数

* @params {delay} number 延迟时间

*/

constthrottle =(fun, delay, ...rest) =>{

      let last =null;

      return()=>{

              const now = +newDate();

              if(now - last > delay) {

                    fun(rest);

                    last = now;

              }

       }

}

//实例

constthrottleExample  = throttle(()=>console.log(1),1000);

//调用

throttleExample();

throttleExample();

throttleExample();

//函数防抖

constdebouce =(fun, delay, ...rest) =>{

            let timer =null;

            return()=>{

                     clearTimeout(timer);

                     timer = setTimeout(()=>{

                             fun(rest);

                      }, delay);

              }

}

//实例

constdebouceExample = debouce(()=>console.log(1),1000);

//调用

debouceExample();

debouceExample();

debouceExample();

AMD和CMD的区别


AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。

CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。

对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible.

CMD 推崇依赖就近,AMD 推崇依赖前置

AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单一。比如 AMD 里,require 分全局 require 和局部 require,都叫 require。CMD 里,没有全局 require,而是根据模块系统的完备性,提供 seajs.use 来实现模块系统的加载启动。CMD 里,每个 API 都简单纯粹

BFC


http://www.cnblogs.com/lhb25/p/inside-block-formatting-ontext.htmlBFC详解

浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不为“visiable”的块级盒子,都会为他们的内容创建新的BFC(块级格式上下文)。本身根元素就处在一个大的BFC中,BFC中元素竖直排列,IFC(行内格式上文)中的元素横向排列

块格式化上下文由以下之一创建:

根元素或其它包含它的元素

浮动 (元素的float不是none)

绝对定位的元素 (元素具有position为absolute或fixed)

内联块 inline-blocks (元素具有display: inline-block)

表格单元格 (元素具有display: table-cell,HTML表格单元格默认属性)

表格标题 (元素具有display: table-caption, HTML表格标题默认属性)

块元素具有overflow,且值不是visible

display: flow-root;—来自MDN

用处:

设置父元素为BFC清除子元素浮动;

解决上面的margin合并问题;

用于布局

new关键字的过程


创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。

属性和方法被加入到 this 引用的对象中。

新创建的对象由 this 所引用,并且最后隐式的返回 this 。

var obj = {};

obj.__proto__ = Base.prototype;//Base为构造函数

Base.call(obj);

return obj

你可能感兴趣的:(我的前端进阶之路)