最近看到一份非常有意思的前端知识点清单整合,然后就滋生了一个想法emmmm....
小编根据清单重新画了一个图,然后决定对下方这个图罗列的知识点做一个系统的整合(征服欲燃起了熊熊大火)。工作之余,小编花了大概一周多的时间整理,篇幅较长,建议收藏慢慢细品。
1.变量
js
的变量,说白了就相当于是一个存储数据的‘容器’。我们在定义变量的时候需要注意一下几点:
$
和 _ 符号开头,但是不建议);2.类型
js
规定了几种数据类型:
Boolean
, String
, Number
, Null
, Undefined
Object
)、数组(Array
)、函数(Function
)注意:Symbol
是 ES6
引入的一种新的原始数据类型,表示独一无二的值。
拓展: 关于null
和undefined
的区别和相似之处。于null
和undefined
在一定程度上及其相似,但是又有着细微的区别。
null
表示的是‘没有对象’,即该处不应该有值。(也可以这样理解,null是已经定义但是值为空,分配内存);
undefined
表示‘缺少值’,就是此处应该有一个值,但是还没有定义(未定义,也未被赋值,不分配内存)。
undefined
(较为常见)。undefined
。undefined
。undefined
。说到原型和原型链,不免得说一下构造函数。
构造函数是一种特殊的方法。主要用来在创建对象时初始化对象。每个构造函数都有prototype
(原型)属性。构造函数的出现是为了解决使用Object
构造函数和字面量表示法不方便创建大量重复对象的问题。看个例子:
function func(name){ this.name=name; this.sayHello=function(){ alert('my name is '+this.name); } } var f=new func('phoebe'); f.sayHello(); 复制代码
此处的f
是func
实例化之后的一个构造函数,new
是用来实例化函数的一种手段。而func
的构造函数实际上是js
内置的function
,实际上function func(name){}
等价于var func = function (name){}
。到这里相信你大概已经明白了何为构造函数。
知晓了构造函数的概念之后,我们来探讨一下原型和原型链。
1.原型
prototype
每个构造函数在创建时都会自动创建一个prototype属性,我们可以在这个属性当中添加新的属性和方法,添加的属性和方法可以为这个函数所使用。将这个函数实例化后的实例也可以使用新添加的属性和方法。这个prototype属性指向的对象,包括自带的属性和我们添加的属性、方法,可以把它指向的对象的内容集合称为构造函数的原型。
注意prototype是构造函数才有的属性。
__ proto __
__proto__
是每个对象自带的属性,属性值是当前实例所属类的原型(prototype
),原型对象中有一个属性constructor
, 它指向函数对象。
举了例子:
function Example() {} var ExampleOne = new Example() console.log(ExampleOne.__proto__ === Example.prototype) // true console.log(Example.prototype.constructor===Example) // true // ExampleOne是个实例对象,带有的是__proto__属性,Example是个构造函数,带的是prototype属性 复制代码
图解:
constructor
每个函数都会有一个原型对象,该原型对象有一个constructor
属性,会指向创建对象的函数本身。此外,所有的实例对象都可以访问onstructor
属性,constructor
属性是创建实例对象的函数的引用。
2.原型链
一般,每个对象都会有一个原型__proto__
,这个原型也有它自己的原型,将这些原型连接起来,形成一个原型链。在查找某一特定属性时,会先去这个对象里去找,如果对象上没有的话就会去它的原型对象里面去,单还是没有的话,会再去向原型对象的原型对象里去寻找。 这个寻找的操作被委托在整个原型链上,我们称之为原型链。
图解:
举个例子:
function Example(){} var ExampleOne = new Example(); //new实例化 console.log(ExampleOne.__proto__ === Example.prototype); // true console.log(Example.prototype.__proto__ === Object.prototype) //true console.log(Object.prototype.__proto__) //null Example.__proto__ == Function.prototype; //true console.log(Function.prototype)// function(){} (这是个空函数) var number = new Array() console.log(number.__proto__ == Array.prototype) // true console.log( Array.prototype.__proto__ == Object.prototype) // true console.log(Array.prototype) // [] (这是个空数组) console.log(Object.prototype.__proto__) //null console.log(Array.__proto__ == Function.prototype)// true 复制代码
小结:
__proto__
是对象的属性,prototype
是构造函数的属性,__proto__
总指向prototype
;prototype
在构造函数创建时会自动生成,它总会被__proto__
指向。1.作用域
我们先来说一下变量的作用域。变量的作用域一般分为两种:全局作用域和局部作用域。
全局作用域:函数最外层定义的变量,任何函数内部都可以访问到。
例如
var a = '1'; function change() { console.log(a) }; change() // 1 复制代码
局部作用域: 和全局作用域不同,局部作用域只能允许自身内部调用变量,外部函数无法访问。
例如:
function num() { var b='2' }; num(); console.log(b) // b is not defined 复制代码
需要注意的是,在函数内部声明一个变量的时候,一定要记住得用var
定义,不然相当于声明了一个全局变量。
例如:
function change() { num=2; } change(); console.log(num) // 2 复制代码
需要注意的是,函数内部存在的变量提升问题。
我们先看下面例子:
var num1 = 1; function one() { console.log(num1); // undefined var num1 = 2; console.log(num1) // 2 } 复制代码
其实上面的例子等价于:
var num1 = 1; function one() { var num1 console.log(num1); // undefined num1 = 2; console.log(num1) // 2 } 复制代码
不难看出,这是存在在函数内部变量提升的现象。
或许对概念不清晰的童鞋对于第一个例子会有点疑惑,认为第一个打印出来的应该是1,而不是undefined
(寄拖鞋警告一次)。
为什么呢?其实one()
函数内部声明了num1
,one()
此时就是一个局部作用域,在内部没有声明num1
的情况下,是会直接获取全局变量num1
。
但是在局部作用域声明了num1
之后,num1
这个变量会提升。如第一个例子,当第一次console.log(num1)
的时候,就相当于var num1
,定义了一个变量但没有赋值,第二次打印,会打印出赋值之后的num1
,就像上面的第二个例子。
拓展:在这里,想拓展一下几种常见的声明变量的方式。
var
:如果在当前函数内部声明一个变量,则作用范围在函数内部;如果在最外层声明,则作为全局变量;如果未使用var
定义直接使用变量,则会报错;const
:具有块级作用域的特征,同一个作用域中,变量名只能声明一次,不存在变量提升。const
声明的变量必须是个常量。let
: 跟const
几乎类似,但是最主要的区别是let
声明的是一个变量,const
声明的必须是个常量。不同之处:
*var
存在变量提升,let
和const
不会;
var
在函数内部同一个变量可以重复声明,而在同一个块级作用域内部,let
和const
只能声明一次,并且const
声明的是个常量,不能修改;var
声明的变量属于函数作用域,let
和 const
声明的变量属于块级作用域2.闭包
简单的说,闭包有两个作用:一就是能够读取其他函数内部变量的函数(也就是读取自身函数以外的变量)。二是让这些外部变量始终保存在内存中。
闭包可以避免使用全局变量,防止变量污染,但是过多使用会造成内存泄露。
举个例子,我想要获取一个函数内部的变量:
var num = 200; function f1() { var num = 100; return a }; f1() // 100 var fn = f1(); fn() // fn is not a function 复制代码
这显然是不行的,fn
获取不到f1
内部的变量。这时候我们可以考虑在f1
内部返回一个函数看看结果:
var num = 200; function f1() { var num = 100; return function () { return num } }; var fn = f1(); fn() // 100 复制代码
通过在函数内部返回一个函数,外部函数可以根据返回的函数获取到原来函数内部的变量,这就体现了闭包的作用。
想研究的更透彻欢迎猛戳:
developer.mozilla.org/zh-CN/docs/…
javascipt
是单线程的描述性脚本语言,与java
或C#
等编译性语言不同,它不需要进行编译成中间语言,而是由浏览器进行动态地解析与执行。所以,弄懂它的执行机制是很有必要的。
由于avascript
是单线程的,为了防止在网页加载过程中由于图片音乐等过大文件而导致加载阻塞,从而衍生出了‘同步任务’和‘异步任务’。我们可以先看一下如下流程图:
通过上图可以较为清晰的看到任务执行的流程。
在同步任务和异步任务之外,执行任务的时候还定义了‘宏观任务’和‘微观任务’两种。一般来说:
macro-task
(宏任务):包括整体代码script
,setTimeout
,setInterval
;micro-task
(微任务):Promise
,process.nextTick
;任务一开始执行的时候,会进入到相应的Event Queue
当中。事件循环的顺序,决定js代码的执行顺序。进入整体代码(宏任务)后,开始第一次循环。接着执行所有的微任务。然后再次从宏任务开始,找到其中一个任务队列执行完毕,再执行所有的微任务。
虽然说js
是单线程的,但是并不是简单意义上的就是按顺序往下执行。通过以上所讲的这些执行顺序,相信你们应该在心里有个大概的思路了(拖鞋警告二)。看个例子(网上搜的,就得解释的可以就拿过来了):
console.log('1'); setTimeout(function() { console.log('2'); process.nextTick(function() { console.log('3'); }) new Promise(function(resolve) { console.log('4'); resolve(); }).then(function() { console.log('5') }) }) process.nextTick(function() { console.log('6'); }) new Promise(function(resolve) { console.log('7'); resolve(); }).then(function() { console.log('8') }) setTimeout(function() { console.log('9'); process.nextTick(function() { console.log('10'); }) new Promise(function(resolve) { console.log('11'); resolve(); }).then(function() { console.log('12') }) 复制代码
最终输出的顺序是:1,7,6,8,2,4,3,5,9,11,10,12
。有没有跟你所预想的一样?如果是,那么恭喜这位童鞋,你已经大致掌握了js
的执行机制了。如果不是,那就往下瞅瞅。
第一轮事件循环流程分析如下:
整体script
作为第一个宏任务进入主线程,遇到console.log
,输出1。
遇到setTimeout
,其回调函数被分发到宏任务Event Queue
中。我们暂且记为setTimeout1
。
遇到process.nextTick()
,其回调函数被分发到微任务Event Queue
中。我们记为process1
。
遇到Promise
,new Promise
直接执行,输出7
。then
被分发到微任务Event Queue
中。我们记为then1
。
又遇到了setTimeout
,其回调函数被分发到宏任务Event Queue
中,我们记为setTimeout2
。
宏观任务(Event Queue ) |
微观任务(Event Queue ) |
---|---|
setTimeout1 |
process1 |
setTimeout2 |
then1 |
上表是第一轮事件循环宏任务结束时各Event Queue
的情况,此时已经输出了1和7。
我们发现了process1
和then1
两个微任务。
执行process1
,输出6。
执行then1
,输出8。
第一轮事件循环正式结束,这一轮的结果是输出1,7,6,8
。那么第二轮时间循环从setTimeout1
宏任务开始:
首先输出2。
接下来遇到了process.nextTick()
,同样将其分发到微任务Event Queue
中,记为process2
。new Promise
立即执行输出4,then
也分发到微任务Event Queue
中,记为then2
。
宏观任务(Event Queue ) |
微观任务(Event Queue ) |
---|---|
setTimeout2 |
process2 |
then2 |
第二轮事件循环宏任务结束,我们发现有process2
和then2
两个微任务可以执行。
输出3。
输出5。
第二轮事件循环结束,第二轮输出2,4,3,5
。
第三轮事件循环开始,此时只剩setTimeout2
了,执行。
直接输出9。
将process.nextTick()
分发到微任务Event Queue
中。记为process3
。
直接执行new Promise
,输出11。
将then
分发到微任务Event Queue
中,记为then3
。
宏观任务(Event Queue ) |
微观任务(Event Queue ) |
---|---|
process3 |
|
then3 |
第三轮事件循环宏任务执行结束,执行两个微任务process3
和then3
。
输出10。
输出12。
第三轮事件循环结束,第三轮输出9,11,10,12
。
最终整段代码,共进行了三次事件循环,完整的输出为1,7,6,8,2,4,3,5,9,11,10,12
。
(需要注意的是,node
环境下的事件监听依赖libuv与前端环境不完全相同,输出顺序可能会有误差)
最后补充一点,谨记javascript
是一门单线程语言,而Event Loop
是javascript
的执行机制。
关于javascript
的语法和API
,这里就不过多介绍了。附上几个链接,可以详细的看一下:
HTML
,超文本标记语言,是一种标识性的语言。它是撑起页面框架结构的重要部分。
HTML
部分的内容较为基础,前端的童鞋肯定是很熟悉的。但是这里还是要附上链接:
www.w3school.com.cn/html/html_j…
css
,层叠样式表,用来修饰页面。除了了解css
的基本用法之外,小编在这里想记录几个面试经常被问到的有关样式的硬核问题。
1.常用的几种布局方式
float:left;
和float:right;
设置布局,注意清除浮动。@media
,详情可参考:www.runoob.com/cssref/css3…BFC
BFC
是什么
BFC(Block Formatting Context)
块级格式化上下文,是用于布局块级盒子的一块渲染区域。BFC是web页面CSS视觉渲染的一部分,用于决定块盒子的布局及浮动相互影响范围的一个区域。
BFC
的作用
BFC
是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然。
我们可以用BFC来阻止元素被浮动元素覆盖、阻止浏览器因为四舍五入造成的多列布局换行的情况、阻止相邻元素的margin合并等。同时,BFC还可以包含浮动元素。
BFC
的约束规则
(1)内部的元素会在垂直方向上一个接着一个的放置。计算BFC
的高度时,需要注意浮动元素也参与计算;
(2)Box
垂直方向的距离由margin
决定。注意:属于同一个BFC
的两个相邻的Box
的margin
会发生重叠;
(3)生成BFC
元素的子元素中,每一个子元素的margin
与包含块的左边界border
相接触(对于从左到右的格式化,否则相反),就算是在浮动中也一样;
(4)BFC
的区域不会与float box
重叠。
(5)BFC
相当于页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。相反也一样。
BFC
可以解决哪些问题
margin
重叠问题、文本不环绕浮动元素问题、包裹浮动元素没有高度问题(父元素塌陷问题)等。
BFC
触发方式(一种即可)
(1)float
的值不为none
;
(2)overflow
的值不为visible
;
(3)display
的值为table-cell
、tabble-caption
和inline-block
之一;
(4)position
的值不为static
或则releative
中的任何一个;
BFC
布局与普通文档流布局区别
普通文档流布局规则
(1)浮动的元素是不会被父级计算高度;
(2)非浮动元素会覆盖浮动元素的位置;
(3)margin
会传递给父级;
(4)两个相邻元素上下margin
会重叠;
BFC
布局规则
(1)浮动的元素会被父级计算高度(父级触发了BFC
);
(2)非浮动元素不会覆盖浮动元素位置(非浮动元素触发了BFC
);
(3)margin
不会传递给父级(父级触发了BFC
);
(4)两个相邻元素上下margin
会重叠(给其中一个元素增加一个父级,然后让他的父级触发BFC
);
3.CSS3
有哪些新特性
新增各种CSS
选择器, 新增圆角(borser-radiuis
),多列布局(multi-column layout
),阴影和反射(multi-column layout
),文字特效(text-shadow
),线性渐变(gradient
),旋转(transform
)以及缩放、定位、倾斜、动画,多背景等。
4.CSS
的性能优化
expression
表达式[IE]
以及filter
属性[IE]
;CSS
的样式尽可能的采取缩写形式,例如给盒子margin
,padding
值等;content.left{...}
,content.right{...}
等,直接用.left{...}
,.right{...}
代替会更加快;5.CSS
预处理
css
预处理器是用一种专门的语言,进行网页的样式设计,之后在被编译为正常的css
文件,以供项目使用。使用css
预处理语言使得css
更加简洁、方便修改、可读性强、适应新强并且更易于代码的维护。
(此处将会持续更新)
其实前端最主要用到的网络协议主要有TCP
,UDP
,HTTP
,FTP
, IP
,ICMP
,IGMP
, ARP
,RARP
等协议。我们可以看看如下图(摘自网页,主要是为了描述):
1.分层对应的协议
TCP/UDP
协议;HTTP
,FTP
协议;IP
,ICMP
,IGMP
协议;ARP
,RARP
协议;2.TCP
三次握手和四次挥手(图片摘自百度)
先看三次握手:
第一次握手: 客户端将含有“同步序列号(SYN
)”标志位的数据段发送给服务端请求链接;
第二次握手:服务器用一个带有“确认应答(ACK
)”和“同步序列号(SYN
)”标志位的数据段响应客户端;
第三次握手:客户端收到数据后,发送一个数据段确认收到服务器的数据段,服务器收到数据确认无误,开始传送实际数据;
四次挥手:
第一次挥手:客户端发送一个FIN
和一个seq
,用来关闭客户端到服务器端的数据传送,客户端进入fin_wait1
状态;
第二次挥手:服务端收到FIN
后,返回一个ACK
给客户端,同时,将seq
的值+1作为确认序号一并返回(确认序号为收到序号+1),服务端进入close_wait
状态;
第三次挥手:服务端发送FIN
和一个值为n的seq
给客户端,用来关闭服务端的数据传输,服务端进入last_wait
状态;
第四次挥手:客户端收到 FIN
后, 客户端进入time_wait
状态,接着发送一个ACK
和一个带值为n+1
的seq
给服务端(确认序号为收到序号 +1 ) ,服务端进入close
状态,完成四次挥手。
3.有关建立链接是三次握手,关闭的时候是四次握手的问题。
因为当服务端收到客户端的SYN
连接请求报文后,可以直接发送SYN+ACK
报文。其中ACK
报文负责响应,SYN
报文负责同步。但是在关闭连接时,当服务端收到FIN
报文时,很可能并不会立即关闭socket
,此时只能先回复一个ACK
报文,来通知客户端,"你发的FIN
报文我收到了"。只有等到服务端所有的报文都发送完了,才能发送FIN
报文,因此不能一起发送。所以需要四步握手。
小编我对于这块了解其实不是很深,但是我感觉是,每种编程语言都有不一样的设计模式。设计模式强调的偏向于一个设计问题的解决办法,可以理解为是一套可以被反复使用,供多数人知晓的,经过分类编目的,代码设计经验的总结。(有不对的地方望大佬们指正)。
设计模式和框架以及架构还是有所区别的:
以上的这几部分,emmm好好看书,多动脑多动手,慢慢提高吧,
关于运行环境,单看标题可能下意识会有点丈二的和尚摸不着头脑的感觉。可能是觉得范围太大,亦或者是概念模糊,其实小编也是这样。不过小编之前阅读过一篇文章,里边简略的介绍了运行环境,可分为如下几点:
加载资源的形式
有分为输入url
(或跳转页面)加载html
和加载html
中的静态资源两种。
加载一个资源的过程
首先浏览器根据DNS
服务器得到域名的IP
地址,然后向这个IP
的机器发送http
请求,接着服务器收到、处理并返回http
请求,最后浏览器得到返回内容。
浏览器渲染页面的过程
首先是浏览器根据HTML
结构生成DOMTree
,然后根据CSS
生成CSSOM
(视图模块),接着将DOM
和CSSOM
整合形成RenderTree
(渲染树),最后根据RenderTree
开始渲染和展示。注意,当遇到script
时,会执行并阻塞渲染。
输入url
到得到html
的过程
浏览器根据DNS
服务器得到域名的IP
地址->向这个IP
的机器发送http
请求->服务器收到、处理并返http
请求->浏览器得到返回内容。
window.onload
和DOMContentLoaded
区别
window.addEventListener('load',function( ){...})//页面所有资源全部加载完才执行 document.addEventListener('DOMContentLoaded',function( ){...})//DOM渲染完即可执行,此时图片视频可能没加载完 复制代码
性能优化
CPU
计算,减少网络请求;要实现以上两种优化,可以从两方面入手:
cdn
、使用ssr
后端渲染,数据库直接输出到html
中;script
放置在最后(渲染机制,js会阻碍渲染,对加载页面不友好)、使用图片懒加载、减少DOM
查询,对DOM
查询做缓存、减少DOM
操作,多个操作尽量合并在一起执行、事件节流(不要频繁触发)、尽早执行操作。跨站脚本攻击(Cross-site scripting
,简称XSS
)
是一种网站应用程序的安全漏洞攻击,是代码注入的一种。它允许恶意用户将代码注入到网页上,其他用户在观看网页时就会受到影响。这类攻击通常包含了HTML
以及用户端脚本语言。
跨站请求伪造(Cross-site request forgery
,简称XSRF
)
是一种对网站的恶意利用。与XSS
不同,XSS
利用站点内的信任用户,而CSRF
则通过伪装来自受信任用户的请求来利用受信任的网站。CSRF
比XSS
更具危险性。
预防措施:有 Token验证、Referer验证、隐藏令牌 三种。
推荐有需要的童鞋到MDN上去了解。
附上链接: developer.mozilla.org/zh-CN/docs/…
前不久小编刚好看到知乎某位大佬写的一片关于浏览器原理的文章,感觉通俗易懂,分析的透彻,有想了解的童鞋也可以去了解一下。
附上链接:zhuanlan.zhihu.com/p/47407398
Node
,简单的说是运行在服务器的javascript
,它是一个基于Chrome
javascript
运行时建立的一个平台,同时也是一个事件驱动I/O
服务端javascript
环境,基于Google
的V8
引擎,V8
引擎执行javascript
的速度非常快,性能非常好。
想大致了解node
的可以参考一下链接:
www.runoob.com/nodejs/node…
想全面了解的可以把目光转向:nodejs.cn/api/assert.…
在构建前端项目的时候,需要考虑如何搭建前端框架。一般来说,有两种方式:一是采用现有的前端框架(比较省时便捷,后期只需要按照需求往内填充业务逻辑即可);第二种是自己来搭建项目框架。
ant design
以及element
等是前端经常用到的一些组件库,其中,也不乏好用的前端框架模板。例如create-react-app
,react-starter-kit
,react-bolierplate
,ant-design-pro
等,这些都是较为常用的模板。一般来说,提供的模板都会有一个较为统一的文件规范,这些有需要的童鞋可以自己去ant design
的官网了解一下,小编这里就不缀述了。
官网链接: ant.design/components/…
至于如何使用,官网上有详细的讲解。除此之外,在git
上clone
到本地的时候,需要将其初始化再运行,这点不要忘记啦。对于刚接触前端的童鞋,再看到这部分内容,想要着手实验的时候,得先熟悉node.js的使用,切记。
以下是小编很久之前自己着手搭建的一个简易的框架,多少坑还是自己亲脚踩过,能力才能提高。文章详细的步骤都已经写上了,有疑问的地方欢迎留言(不足之处欢迎指出)。附上链接:juejin.im/post/5b6049…
nginx
的概念Nginx
是由俄罗斯的程序设计师lgor Sysoev
所开发一个高性能的HTTP
和反向代理服务器,也是一个IMAP/POP3/SMTP
代理服务器;Web
服务器/反向代理服务器以及电子邮件代理服务器,并在一个BSD-like
协议下发行;nginx
的并发能力确实在同类型的网页服务器中表现较好;Apache\lighttpd
具有占有内存少,稳定性高等优势,并且依靠并发能力强,丰富的模块库以及友好灵活的配置而闻名;Linux
操作系统下,nginx
使用epoll
事件模型,得益于此,nginx
在Linux
操作系统下效率相当高。同时Nginx
在OpenBSD
或FreeBSD
操作系统上采用类似于Epoll
的高效事件模型kqueue
;Nginx
既可以在内部直接支持 Rails
和 PHP
程序对外进行服务,也可以支持作为 HTTP
代理服务对外进行服务。Nginx
采用C
进行编写,不论是系统资源开销还是CPU
使用效率都比 Perlbal
要好很多;nginx
做反向代理。并且多台服务器可以平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置的情况。nginx
的应用场景http
服务器,Nginx
是一个http
服务可以独立提供http
服务。可以做网页静态服务器。nginx
做反向代理。多台服务器可以平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置的情况。在编写项目的过程中,我们在按规定的项目周期之内完成之余,还需要考虑的是项目的加载速率以及性能优化。友好的页面展示以及运行能给用户留下不错的印象,这是前端开发人员成功的一小步。
在前端开发过程中,要想页面展示的更安全更快,需要做到以下几点:
http
请求;Expires
或者Cache-Control
;ajax
请求;CDN
;gzip
压缩返回数据,最小化js
文件和css
文件,将css
和js
独立成外部文件);cookie
(减小cookie
的体积,合理设置Cookie
域,设置合理的cookie
过期时间,使用域分离)css
放在页面顶部加载,js
放在页面底部加载)什么是持续集成?持续集成是一种软件开发实践,是指团队开发项目过程中,集成各自所负责的项目部分到同一个地方。通过每个成员每天至少集成一次,一天可能会集成多次。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。
举个最简单的例子,项目git
提交以及构建。一个前端项目由两个前端开发人员负责,每个人负责一部分,项目在git
上有个master
分支(项目主分支)。开发人员拉取代码到本地,需建立一个本地分支如(如dev
)。当开发人员开发过程中,部分内容完成了需要提交,在拉取最新版本代码,合并代码无误的情况下,将自己本地建立的分支内容提交到git
,确保代码无误,并入到master
分支,最后构建项目。小编大概理解的是这样。
持续集成可以降低风险,减少重复。同时,不受时间地点的控制,随时可以生成部署的软件,从而提高开发效率。
在前端开发中,版本控制也是重要的一环。
举个例子,在开发人员拉取最近的代码,然后合并提交了之后,发现了问题,这时候可以回滚到上一版本。主分支同理,在发现问题或是需求忽然变更到原始版本的时候可以回退到原始任意版本。这在一定程度上为开发过程中的突发状况提供了便利。
再举个例子:在开发过程中,经常会变成一些内容,比如页面样式以及js
。在最开始的时候,定义了一个one.css
和one.js
的文件并引入:
<link rel="stylesheet" href="one.css"></link> <script src="one.js"></script> 复制代码
提交构建完之后,浏览器打开,考虑到缓存的问题,浏览器会缓存这次的样式以及js
。之后需求变更,更改了一部分样式,构建完之后,打开看到样式没有变更。原因是因为浏览器缓存了之前的样式以及js
,并没有更新。这时,可以选择给改变的样式以及js
添加一个版本号:
<link rel="stylesheet" href="one.css?v=0.01"></link> <script src="one.css?v=0.01"></script> 复制代码
但是每次更新代码都要手动更改版本号,这显然不合理。这时候我们可以考虑,利用生成hash
值,来判断文件内容是否变化。
需要注意的是,我们发布项目的时候,资源文件和主文件是分开发的,资源文件部署在CDN
中,主文件部署在服务器。在发布的时候,将资源文件变成非覆盖式发布,解决新版和旧版资源文件共存问题。然后先发资源文件,在资源文件部署成功后,在发主文件,这样可以避免很多问题。
<link rel="stylesheet" href="one.o3289.css"></link> <script src="one.o3289.js"></script> 复制代码
最后代码呈现的样子。
懂了么?嗯?还是不明白的话....
关于TypeScript
,小编我也是趁着这次总结,去学习了一下阮一峰老师写的文档,收获颇多。
附上链接:ts.xcatliu.com/
关于react
部分,小编用的也是这个,有js基础的可以去看看react
官网,熟悉一下react
的使用,代码规范以及生命周期等。
附上链接:reactjs.org/
要是刚接触前端的童鞋,可以转身先看看阮一峰老师写的这本书,再结合react
官网学习。
链接:caibaojian.com/es6/
vue小编其实不是很擅长,之前跑去它家的官网看了一遍文档,当下感觉还行,但是因为现在的项目一般用的是react
,其实现在已经是云里雾里,忘得差不多了,害。
附上链接: cn.vuejs.org/
有兴趣的童鞋可以去瞅瞅。
对于多端开发,小编的理解其实是这样的:
当一个项目明确了需求之后,在开发的过程中极大程度生会多端共同配合开发。就比如一款产品,除了有后台和web
端开发,还需要开发小程序以及APP
,这就需要多端共同配合。
传统方式开发会花费更多的时间,写更多的代码,对于项目上线和发布都会有一定时间限制,不能做到同时发布,也需要对应着每一端,相应的开发写对应的代码。消耗更多的时间和资源的同时,开发速度和效果也没有预期的高。不过在现在的开发框架中,已经出现了许多的多端开发框架,这种基本都是用于移动端的开发。对于现在开发的需求,是大大的提升了开发者的速度,和大大减少了项目多端分布的开发短板。
现在大部分的项目,涉及到多端开发的概率很大,就比如小编最近刚结束提测的这个项目,就是web
端结合微信小程序的开发(在react
和微信小程序间来回摩擦,被迫切换自如诶)。但是在一般情况下,一个前端很少会有一个人负责多端开发的情况出现(也只是小编理解的一般情况,不排除小公司一个人当多个人使)。一个项目中负责web
端的就只负责web
端,负责小程序的会另外分配人员。
但是作为一名前端程序员(媛),对于多端开发得有一个概念性的理解。
鉴于小编目前用的是react
,在这里就着重讲解一下react
有关数据流的部分。
简单来讲,react
是自顶向下的单向数据流,通过setState
来改变state
的状态。在管理数据流部分,react
经常配合redux
一起使用,这样可以有效的避免组件臃肿的问题。同时,还能实现跨组件通信、状态同步以及状态共享,处理异步数据流,让组件变得可预知。
redux
是由flux
衍生出来的,是flux
的进化版。redux
有三大原则:唯一数据源,保持只读状态,数据状态只能通过纯函数完成。
redux
提供了store
,action
和reduce
三个API
:
store
(Redux
应用只有一个单一的 store
)state
;getState()
方法获取 state
;dispatch(action)
方法更新 state
;subscribe(listener)
注册监听器;subscribe(listener)
返回的函数注销监听器action
store
的有效载荷。它是 store
数据的唯一来源,一般通过 store.dispatch()
将 action
传到 store
。reduce
actions
并发送到 store
,store
收到action
后,需要给出一个新的状态来更新页面,这种state
的计算过程就叫做reducer
。数据流过程简述: 简单的说就是,在界面中用户通过ispatch
,触发action
;store
调用reducer
,并且传入当前state
和action
,更新state
并返回新的state
;view
更新。
在这里,主要列述一下小编目前用到的以及了解过的库吧,毕竟组件库啊框架之类的有很多,但是实用的肯定是自己最经常用到而且用的比较顺手的。
1.前端UI组件库
Ant Design Pro
更多:landing.ant.design/
以上是小编目前较为经常用到的实用库。
另外,附上最近看到的一个较为全面的实用库整理的链接:www.luoxiao123.cn/1196.html
关于前端开发测试,小编的理解是,在写完代码后检查所实现的功能是否符合项目需求,界面样式排版是否符合UI设计等。
有关前端测试,可以分为以下几种类型:
E2E
测试关于这部分,了解一下就好,毕竟还有测试组不是小哥哥小姐姐的么嘿嘿
作为一名前端,了解一门相关的后端语言其实很有必要,例如java/php/python
等。现在很多公司面试的时候都会要求至少掌握或了解一门后台语言,技多不压身,多学习了解提升自身技能是硬道理。
主要是,掌握了基本的后台技能,在写前端项目的时候,遇到问题,跟后端沟通起来相对来说也比较方便。
性能优化的目的主要还是让页面加载的更快,对用户操作响应更及时,为用户带来更好的用户体验,对于开发者来说优化能够减少页面请求数,能够节省资源。
关于性能优化,前面小编已经有所介绍,有忘记的童鞋可以往上翻翻。
关于前端安全,其实主要常见的还是XSS
(跨站脚本攻击)和CSRF
(跨站请求伪造),这两部分文章中已经做了较为详细的解释。
在这里有一点需要注意的是“点击劫持”。
概念: 点击劫持 指第三方网站通过iframe
内嵌某一个网站,并且将iframe
设置为透明不可见,将其覆盖在其他经过伪装的DOM
上,伪装的可点击DOM
(按钮等)与实际内嵌网站的可点击DOM
位置相同,当用户点击伪装的DOM
时,实际上点击的是iframe
中内嵌的网页的DOM
从而触发请求操作。点击劫持的最大特点是用户自己触发了点击事件,但是毫不知情。
解决方案:
作为一名前端工作者,小编(以组内大佬小哥为模板)列举一下与前端业务相关的事项:
UI
设计师给的设计图实现布局;PS
以及切图软件等相关工具(不能遇到一点样式问题就去找设计人员,自己会的话改改更快,小编亲鉴);目前小编觉得大概就这几个,如果觉得有写漏的,欢迎下方留言。
到这里基本结束啦。整理的过程中,由于有些概念性的东西怕说不明白误人子弟,就在网上搜了一些例子讲解。
小编年少轻狂,之前口出狂言,立下flag说每隔两个礼拜出一篇文章,害。不过每次整理知识点,小编都能收获很多,希望也能帮助有需要的人。还是内句老话,若有不足,请留言指出。若对您有所帮助,emmmmm