likes
comments
collection
share

肝完这份前端毒鸡汤,你就是赚到了(篇幅较长,建议收藏慢慢细品)

作者站长头像
站长
· 阅读数 20

最近看到一份非常有意思的前端知识点清单整合,然后就滋生了一个想法emmmm....

肝完这份前端毒鸡汤,你就是赚到了(篇幅较长,建议收藏慢慢细品)

小编根据清单重新画了一个图,然后决定对下方这个图罗列的知识点做一个系统的整合(征服欲燃起了熊熊大火)。工作之余,小编花了大概一周多的时间整理,篇幅较长,建议收藏慢慢细品。

肝完这份前端毒鸡汤,你就是赚到了(篇幅较长,建议收藏慢慢细品)

Javascript基础

变量和类型

1.变量

js的变量,说白了就相当于是一个存储数据的‘容器’。我们在定义变量的时候需要注意一下几点:

  • 变量名大小对大小写字母敏感;
  • 变量名须以字母开头(也能以 $ 和 _ 符号开头,但是不建议);

2.类型

js规定的数据类型有八种:Boolean, String, Number, Null, Undefined, bigInt, Symbol, Object

  • 基本类型有六种: Boolean, String, Number, Null, Undefined,Symbol
  • 引用数据类型有一种: Object(在JS中除了基本数据类型以外的都是对象,Data, function, Array,正则表达式都是对象)

注意:SymbolES6 引入的一种新的原始数据类型,表示独一无二的值。

拓展: 关于nullundefined的区别和相似之处。于nullundefined在一定程度上及其相似,但是又有着细微的区别。

null表示的是‘没有对象’,即该处不应该有值。(也可以这样理解,null是已经定义但是值为空,分配内存);

  • 作为函数的参数,表示该函数的参数不是对象。
  • 作为对象原型链的终点。

undefined表示“未定义”,一个特殊值,通常用于指示变量尚未赋值,其值就为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();

此处的ffunc实例化之后的一个构造函数,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属性,会指向创建对象的函数本身。此外,所有的实例对象都可以访问constructor属性,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

小结:

  1. __proto__是对象的属性,prototype是构造函数的属性,__proto__总指向prototype;
  2. 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()函数内部声明了num1one()此时就是一个局部作用域,在内部没有声明num1的情况下,是会直接获取全局变量num1

但是在局部作用域声明了num1之后,num1这个变量会提升。如第一个例子,当第一次console.log(num1)的时候,就相当于var num1,定义了一个变量但没有赋值,第二次打印,会打印出赋值之后的num1,就像上面的第二个例子。

拓展:在这里,想拓展一下几种常见的声明变量的方式。

  • var :如果在当前函数内部声明一个变量,则作用范围在函数内部;如果在最外层声明,则作为全局变量;如果未使用var定义直接使用变量,则会报错;
  • const:具有块级作用域的特征,同一个作用域中,变量名只能声明一次,不存在变量提升。const声明的变量必须是个常量。
  • let: 跟const几乎类似,但是最主要的区别是let声明的是一个变量,const声明的必须是个常量。

不同之处:

*var存在变量提升,letconst不会;

  • var在函数内部同一个变量可以重复声明,而在同一个块级作用域内部,letconst只能声明一次,并且const声明的是个常量,不能修改;
  • var 声明的变量属于函数作用域,letconst 声明的变量属于块级作用域

2.闭包

简单的说,闭包有两个作用:一就是能够读取其他函数内部变量的函数(也就是读取自身函数以外的变量)。二是让这些外部变量始终保存在内存中。

闭包可以避免使用全局变量,防止变量污染,但是过多使用会造成内存泄露。

举个例子,我想要获取一个函数内部的变量:

var num = 200;
function f1() {
    var num = 100;
    return num
};
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是单线程的描述性脚本语言,与javaC#等编译性语言不同,它不需要进行编译成中间语言,而是由浏览器进行动态地解析与执行。所以,弄懂它的执行机制是很有必要的。

由于javascript是单线程的,为了防止在网页加载过程中由于图片音乐等过大文件而导致加载阻塞,从而衍生出了‘同步任务’和‘异步任务’。我们可以先看一下如下流程图:

肝完这份前端毒鸡汤,你就是赚到了(篇幅较长,建议收藏慢慢细品)

通过上图可以较为清晰的看到任务执行的流程。

在同步任务和异步任务之外,执行任务的时候还定义了‘宏观任务’和‘微观任务’两种。一般来说:

  • macro-task(宏任务):包括整体代码scriptsetTimeoutsetInterval
  • micro-task(微任务):Promiseprocess.nextTick(node.js);

任务一开始执行的时候,会进入到相应的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

遇到Promisenew Promise直接执行,输出7then被分发到微任务Event Queue中。我们记为then1

又遇到了setTimeout,其回调函数被分发到宏任务Event Queue中,我们记为setTimeout2

宏观任务(Event Queue 微观任务(Event Queue
setTimeout1 process1
setTimeout2 then1

上表是第一轮事件循环宏任务结束时各Event Queue的情况,此时已经输出了1和7。

我们发现了process1then1两个微任务。

执行process1,输出6。

执行then1,输出8。

第一轮事件循环正式结束,这一轮的结果是输出1,7,6,8。那么第二轮时间循环从setTimeout1宏任务开始:

首先输出2。

接下来遇到了process.nextTick(),同样将其分发到微任务Event Queue中,记为process2new Promise立即执行输出4,then也分发到微任务Event Queue中,记为then2

宏观任务(Event Queue 微观任务(Event Queue
setTimeout2 process2
then2

第二轮事件循环宏任务结束,我们发现有process2then2两个微任务可以执行。

输出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

第三轮事件循环宏任务执行结束,执行两个微任务process3then3

输出10。

输出12。

第三轮事件循环结束,第三轮输出9,11,10,12

最终整段代码,共进行了三次事件循环,完整的输出为1,7,6,8,2,4,3,5,9,11,10,12

(需要注意的是,node环境下的事件监听依赖libuv与前端环境不完全相同,输出顺序可能会有误差)

最后补充一点,谨记javascript是一门单线程语言,而Event Loopjavascript的执行机制。

语法和API

关于javascript的语法和API,这里就不过多介绍了。附上几个链接,可以详细的看一下:

肝完这份前端毒鸡汤,你就是赚到了(篇幅较长,建议收藏慢慢细品)


HTML和CSS

HTML

HTML,超文本标记语言,是一种标识性的语言。它是撑起页面框架结构的重要部分。

HTML部分的内容较为基础,前端的童鞋肯定是很熟悉的。但是这里还是要附上链接: www.w3school.com.cn/html/html_j…

CSS

css,层叠样式表,用来修饰页面。除了了解css的基本用法之外,小编在这里想记录几个面试经常被问到的有关样式的硬核问题。

1.常用的几种布局方式

  • 固定布局:最外层盒子宽度固定且不能移动,里面的各个模块也是固定宽度而不是百分比。无论访问者的屏幕的分辨率是多少,网页都显示为和其他访问者相同的宽度。
  • 流式布局(自适应布局):盒子宽高按百分比(故而也称之为百分比布局)。
  • 定位布局: 使用决定定位,相对定位和固定定位的布局
  • 浮动布局:使用float:left;float:right;设置布局,注意清除浮动。
  • 响应式布局(媒体查询): 使用@media,详情可参考:www.runoob.com/cssref/css3…
  • 弹性布局(伸缩布局):献上阮一峰老师的细致分析文档:www.ruanyifeng.com/blog/2015/0…
  1. 关于BFC
  • BFC是什么

    BFC(Block Formatting Context)块级格式化上下文,是用于布局块级盒子的一块渲染区域。BFC是web页面CSS视觉渲染的一部分,用于决定块盒子的布局及浮动相互影响范围的一个区域。

  • BFC的作用

    BFC是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然。

    我们可以用BFC来阻止元素被浮动元素覆盖阻止浏览器因为四舍五入造成的多列布局换行的情况阻止相邻元素的margin合并等。同时,BFC还可以包含浮动元素。

  • BFC的约束规则

    (1)内部的元素会在垂直方向上一个接着一个的放置。计算BFC的高度时,需要注意浮动元素也参与计算;

    (2)Box垂直方向的距离由margin决定。注意:属于同一个BFC的两个相邻的Boxmargin会发生重叠;

    (3)生成BFC元素的子元素中,每一个子元素的margin与包含块的左边界border相接触(对于从左到右的格式化,否则相反),就算是在浮动中也一样;

    (4)BFC的区域不会与float box重叠。

    (5)BFC相当于页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。相反也一样。

  • BFC可以解决哪些问题

    margin重叠问题、文本不环绕浮动元素问题、包裹浮动元素没有高度问题(父元素塌陷问题)等。

  • BFC触发方式(一种即可)

    (1)float的值不为none

    (2)overflow的值不为visible;

    (3)display的值为table-celltabble-captioninline-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选择器, 新增圆角(border-radius),多列布局(multi-column layout),阴影和反射(multi-column layout),文字特效(text-shadow),线性渐变(gradient),旋转(transform)以及缩放、定位、倾斜、动画,多背景等。

4.CSS的性能优化

  • 尽量的避免使用expression表达式[IE]以及filter属性[IE]
  • CSS的样式尽可能的采取缩写形式,例如给盒子marginpadding值等;
  • 适当减少使用不必要的并行规则,例如content.left{...},content.right{...}等,直接用.left{...},.right{...}代替会更加快;
  • 尽量减少规则层数,层数越多,定位越慢(非常慢),使用一个有语义的选择器往往能够取得更好的效率;
  • 利用好继承机制;
  • 尽量减少重布局以及重绘;

5.CSS预处理

css预处理器是用一种专门的语言,进行网页的样式设计,之后在被编译为正常的css文件,以供项目使用。使用css预处理语言使得css更加简洁、方便修改、可读性强、适应新强并且更易于代码的维护。

(此处将会持续更新)


计算机基础

编译原理

网络协议

其实前端最主要用到的网络协议主要有TCPUDPHTTPFTPIPICMPIGMPARPRARP等协议。我们可以看看如下图(摘自网页,主要是为了描述):

肝完这份前端毒鸡汤,你就是赚到了(篇幅较长,建议收藏慢慢细品)

1.分层对应的协议

  • 传输层中,主要有TCP/UDP协议;
  • 应用层中,主要有HTTPFTP协议;
  • 网络层中,主要有IPICMPIGMP协议;
  • 网络接口层中,主要有 ARPRARP协议;

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+1seq给服务端(确认序号为收到序号 +1 ) ,服务端进入close状态,完成四次挥手。

3.有关建立链接是三次握手,关闭的时候是四次握手的问题。

因为当服务端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文负责响应,SYN报文负责同步。但是在关闭连接时,当服务端收到FIN报文时,很可能并不会立即关闭socket,此时只能先回复一个ACK报文,来通知客户端,"你发的FIN报文我收到了"。只有等到服务端所有的报文都发送完了,才能发送FIN报文,因此不能一起发送。所以需要四步握手。

设计模式

小编我对于这块了解其实不是很深,但是我感觉是,每种编程语言都有不一样的设计模式。设计模式强调的偏向于一个设计问题的解决办法,可以理解为是一套可以被反复使用,供多数人知晓的,经过分类编目的,代码设计经验的总结。(有不对的地方望大佬们指正)。 常用的设计模式有:单例模式,观察者模式,构造函数模式,工厂模式,原型模式等。

设计模式和框架以及架构还是有所区别的:

  • 于框架而言,设计模式所讲的的是对单一问题的设计思路和解决方法,一个模式可应用于不同的框架和被不同的程序语言所实现;而框架则是一个应用的体系结构,是一种或多种设计模式和代码的混合体。设计模式的思想可以在框架设计中进行应用。
  • 于架构而言,设计模式除了是对单一问题的设计思路和解决方法之外,范畴比较小;而架构是高层次的针对体系结构的一种设计思路,范畴比较大。一个架构中可能会出现多个设计模式的思想。

数据结构和算法

JS编译能力

手动实现前端轮子

数据结构

算法

以上的这几部分,emmm好好看书,多动脑多动手,慢慢提高吧,


运行环境

关于运行环境,单看标题可能下意识会有点丈二的和尚摸不着头脑的感觉。可能是觉得范围太大,亦或者是概念模糊,其实小编也是这样。不过小编之前阅读过一篇文章,里边简略的介绍了运行环境,可分为如下几点:

  1. 加载资源的形式

    有分为输入url(或跳转页面)加载html和加载html中的静态资源两种。

  2. 加载一个资源的过程

    首先浏览器根据DNS服务器得到域名的IP地址,然后向这个IP的机器发送http请求,接着服务器收到、处理并返回http请求,最后浏览器得到返回内容。

  3. 浏览器渲染页面的过程

    首先是浏览器根据HTML结构生成DOMTree,然后根据CSS生成CSSOM(视图模块),接着将DOMCSSOM整合形成RenderTree(渲染树),最后根据RenderTree开始渲染和展示。注意,当遇到script时,会执行并阻塞渲染。

  4. 输入url到得到html的过程

    浏览器根据DNS服务器得到域名的IP地址->向这个IP的机器发送http请求->服务器收到、处理并返http请求->浏览器得到返回内容。

  5. window.onloadDOMContentLoaded区别

    window.addEventListener('load',function( ){...})//页面所有资源全部加载完才执行
    document.addEventListener('DOMContentLoaded',function( ){...})//DOM渲染完即可执行,此时图片视频可能没加载完
    
  6. 性能优化

  • 多用内存、缓存或其他方法;
  • 减少CPU计算,减少网络请求;

要实现以上两种优化,可以从两方面入手:

  • 优化资源加载:例如静态资源压缩、静态资源缓存、使用cdn、使用ssr后端渲染,数据库直接输出到html中;
  • 优化渲染:在放置样式以及脚本代码时,样式最好放置在head标签内,script放置在最后(渲染机制,js会阻碍渲染,对加载页面不友好)、使用图片懒加载、减少DOM查询,对DOM查询做缓存、减少DOM操作,多个操作尽量合并在一起执行、事件节流(不要频繁触发)、尽早执行操作。
  1. 安全性
  • 跨站脚本攻击(Cross-site scripting,简称XSS

    是一种网站应用程序的安全漏洞攻击,是代码注入的一种。它允许恶意用户将代码注入到网页上,其他用户在观看网页时就会受到影响。这类攻击通常包含了HTML以及用户端脚本语言。

  • 跨站请求伪造(Cross-site request forgery,简称XSRF

    是一种对网站的恶意利用。与XSS不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。CSRFXSS更具危险性。

预防措施:有 Token验证、Referer验证、隐藏令牌 三种。

浏览器API

推荐有需要的童鞋到MDN上去了解。

附上链接: developer.mozilla.org/zh-CN/docs/…

浏览器原理

前不久小编刚好看到知乎某位大佬写的一片关于浏览器原理的文章,感觉通俗易懂,分析的透彻,有想了解的童鞋也可以去了解一下。

附上链接:zhuanlan.zhihu.com/p/47407398

Node

Node,简单的说是运行在服务器的javascript,它是一个基于Chrome javascript运行时建立的一个平台,同时也是一个事件驱动I/O服务端javascript环境,基于GoogleV8引擎,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/…

至于如何使用,官网上有详细的讲解。除此之外,在gitclone到本地的时候,需要将其初始化再运行,这点不要忘记啦。对于刚接触前端的童鞋,再看到这部分内容,想要着手实验的时候,得先熟悉node.js的使用,切记。

以下是小编很久之前自己着手搭建的一个简易的框架,多少坑还是自己亲脚踩过,能力才能提高。文章详细的步骤都已经写上了,有疑问的地方欢迎留言(不足之处欢迎指出)。附上链接:juejin.cn/post/684490…

nginx

  1. nginx的概念
  • Nginx是由俄罗斯的程序设计师lgor Sysoev所开发一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器;
  • 它是一款轻量级的Web服务器/反向代理服务器以及电子邮件代理服务器,并在一个BSD-like协议下发行;
  • 其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好;
  • 它相较于Apache\lighttpd具有占有内存少,稳定性高等优势,并且依靠并发能力强,丰富的模块库以及友好灵活的配置而闻名;
  • Linux操作系统下,nginx使用epoll事件模型,得益于此,nginxLinux操作系统下效率相当高。同时NginxOpenBSDFreeBSD操作系统上采用类似于Epoll的高效事件模型kqueue
  • 它作为负载均衡服务:Nginx 既可以在内部直接支持 RailsPHP 程序对外进行服务,也可以支持作为 HTTP代理服务对外进行服务。Nginx采用C进行编写,不论是系统资源开销还是CPU使用效率都比 Perlbal 要好很多;
  • 反向代理,负载均衡。当网站的访问量达到一定程度后,单台服务器不能满足用户的请求时,需要用多台服务器集群可以使用nginx做反向代理。并且多台服务器可以平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置的情况。
  1. nginx的应用场景
  • 应用于虚拟主机,可以实现在一台服务器虚拟出多个网站。
  • 应用于http服务器,Nginx是一个http服务可以独立提供http服务。可以做网页静态服务器。
  • 反向代理,负载均衡。当某一网站的访问量达到一定程度后,单台服务器不能满足用户的请求时,需要用多台服务器集群,可以使用nginx做反向代理。多台服务器可以平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置的情况。

开发提速

在编写项目的过程中,我们在按规定的项目周期之内完成之余,还需要考虑的是项目的加载速率以及性能优化。友好的页面展示以及运行能给用户留下不错的印象,这是前端开发人员成功的一小步。

在前端开发过程中,要想页面展示的更安全更快,需要做到以下几点:

  • 减少http请求;
  • 合并脚本文件;
  • 指定Expires或者Cache-Control
  • 缓存ajax请求;
  • 移除重复的js;
  • 避免重定向;
  • 使用CDN
  • 减小返回数据的体积(可使用gzip压缩返回数据,最小化js文件和css文件,将cssjs独立成外部文件);
  • 优化cookie(减小cookie的体积,合理设置Cookie域,设置合理的cookie过期时间,使用域分离)
  • 优化浏览器加载(将css放在页面顶部加载,js放在页面底部加载)

持续集成

什么是持续集成?持续集成是一种软件开发实践,是指团队开发项目过程中,集成各自所负责的项目部分到同一个地方。通过每个成员每天至少集成一次,一天可能会集成多次。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

举个最简单的例子,项目git提交以及构建。一个前端项目由两个前端开发人员负责,每个人负责一部分,项目在git上有个master分支(项目主分支)。开发人员拉取代码到本地,需建立一个本地分支如(如dev)。当开发人员开发过程中,部分内容完成了需要提交,在拉取最新版本代码,合并代码无误的情况下,将自己本地建立的分支内容提交到git,确保代码无误,并入到master分支,最后构建项目。小编大概理解的是这样。

持续集成可以降低风险,减少重复。同时,不受时间地点的控制,随时可以生成部署的软件,从而提高开发效率。

版本控制

在前端开发中,版本控制也是重要的一环。

举个例子,在开发人员拉取最近的代码,然后合并提交了之后,发现了问题,这时候可以回滚到上一版本。主分支同理,在发现问题或是需求忽然变更到原始版本的时候可以回退到原始任意版本。这在一定程度上为开发过程中的突发状况提供了便利。

再举个例子:在开发过程中,经常会变成一些内容,比如页面样式以及js。在最开始的时候,定义了一个one.cssone.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

关于TypeScript,小编我也是趁着这次总结,去学习了一下阮一峰老师写的文档,收获颇多。

附上链接:ts.xcatliu.com/

React

关于react部分,小编用的也是这个,有js基础的可以去看看react官网,熟悉一下react的使用,代码规范以及生命周期等。

附上链接:reactjs.org/

要是刚接触前端的童鞋,可以转身先看看阮一峰老师写的这本书,再结合react官网学习。

链接:caibaojian.com/es6/

Vue

vue小编其实不是很擅长,之前跑去它家的官网看了一遍文档,当下感觉还行,但是因为现在的项目一般用的是react,其实现在已经是云里雾里,忘得差不多了,害。

附上链接: cn.vuejs.org/

有兴趣的童鞋可以去瞅瞅。

多端开发

对于多端开发,小编的理解其实是这样的:

当一个项目明确了需求之后,在开发的过程中极大程度生会多端共同配合开发。就比如一款产品,除了有后台和web端开发,还需要开发小程序以及APP,这就需要多端共同配合。

传统方式开发会花费更多的时间,写更多的代码,对于项目上线和发布都会有一定时间限制,不能做到同时发布,也需要对应着每一端,相应的开发写对应的代码。消耗更多的时间和资源的同时,开发速度和效果也没有预期的高。不过在现在的开发框架中,已经出现了许多的多端开发框架,这种基本都是用于移动端的开发。对于现在开发的需求,是大大的提升了开发者的速度,和大大减少了项目多端分布的开发短板。

现在大部分的项目,涉及到多端开发的概率很大,就比如小编最近刚结束提测的这个项目,就是web端结合微信小程序的开发(在react和微信小程序间来回摩擦,被迫切换自如诶)。但是在一般情况下,一个前端很少会有一个人负责多端开发的情况出现(也只是小编理解的一般情况,不排除小公司一个人当多个人使)。一个项目中负责web端的就只负责web端,负责小程序的会另外分配人员。

但是作为一名前端程序员(媛),对于多端开发得有一个概念性的理解。

数据流管理

鉴于小编目前用的是react,在这里就着重讲解一下react有关数据流的部分。

简单来讲,react是自顶向下的单向数据流,通过setState来改变state的状态。在管理数据流部分,react经常配合redux一起使用,这样可以有效的避免组件臃肿的问题。同时,还能实现跨组件通信、状态同步以及状态共享,处理异步数据流,让组件变得可预知。

redux是由flux衍生出来的,是flux的进化版。redux有三大原则:唯一数据源,保持只读状态,数据状态只能通过纯函数完成。

redux提供了storeactionreduce三个API:

  1. storeRedux 应用只有一个单一的 store
  • 维持应用的 state
  • 提供 getState() 方法获取 state
  • 提供 dispatch(action) 方法更新 state
  • 通过 subscribe(listener) 注册监听器;
  • 通过 subscribe(listener) 返回的函数注销监听器
  1. action
  • 把数据从应用传到 store 的有效载荷。它是 store 数据的唯一来源,一般通过 store.dispatch()action 传到 store
  1. reduce
  • 指定了应用状态的变化如何响应 actions 并发送到 storestore收到action后,需要给出一个新的状态来更新页面,这种state的计算过程就叫做reducer

数据流过程简述: 简单的说就是,在界面中用户通过dispatch,触发actionstore调用reducer,并且传入当前stateaction,更新state并返回新的stateview更新。

实用库

在这里,主要列述一下小编目前用到的以及了解过的库吧,毕竟组件库啊框架之类的有很多,但是实用的肯定是自己最经常用到而且用的比较顺手的。

1.前端UI组件库

  1. 前端框架
  1. 前端自动化构建工具
  1. 前端自动化模块管理工具
  1. 前端自动化css预处理器
  1. js框架
  1. 前端框架模板(开箱即食)
  1. 图表绘制
  1. 日期格式化
  1. Icon组件

以上是小编目前较为经常用到的实用库。

另外,附上最近看到的一个较为全面的实用库整理的链接:www.luoxiao123.cn/1196.html

开发测试

关于前端开发测试,小编的理解是,在写完代码后检查所实现的功能是否符合项目需求,界面样式排版是否符合UI设计等。

有关前端测试,可以分为以下几种类型:

  • 单元测试
  • 集成测试
  • 样式测试
  • E2E测试
  • 测试覆盖率与代码变异测试
  • 代码变异测试

关于这部分,了解一下就好,毕竟还有测试组不是小哥哥小姐姐的么嘿嘿


项目及业务

后端技能

作为一名前端,了解一门相关的后端语言其实很有必要,例如java/php/python等。现在很多公司面试的时候都会要求至少掌握或了解一门后台语言,技多不压身,多学习了解提升自身技能是硬道理。

主要是,掌握了基本的后台技能,在写前端项目的时候,遇到问题,跟后端沟通起来相对来说也比较方便。

性能优化

性能优化的目的主要还是让页面加载的更快,对用户操作响应更及时,为用户带来更好的用户体验,对于开发者来说优化能够减少页面请求数,能够节省资源。

关于性能优化,前面小编已经有所介绍,有忘记的童鞋可以往上翻翻。

前端安全

关于前端安全,其实主要常见的还是XSS(跨站脚本攻击)和CSRF(跨站请求伪造),这两部分文章中已经做了较为详细的解释。

在这里有一点需要注意的是“点击劫持”。

概念: 点击劫持 指第三方网站通过iframe内嵌某一个网站,并且将iframe设置为透明不可见,将其覆盖在其他经过伪装的DOM上,伪装的可点击DOM(按钮等)与实际内嵌网站的可点击DOM位置相同,当用户点击伪装的DOM时,实际上点击的是iframe中内嵌的网页的DOM从而触发请求操作。点击劫持的最大特点是用户自己触发了点击事件,但是毫不知情

解决方案:

  • javascript 禁止内嵌
  • X-FRAME-OPTIONS 禁止内嵌
  • 其他辅助手段如 添加验证码

业务相关

作为一名前端工作者,小编(以组内大佬小哥为模板)列举一下与前端业务相关的事项:

  • 具备良好的团队沟通技能,能按照产品给出的原型实现相关的功能,按照UI设计师给的设计图实现布局;
  • 具有一定的审美,对界面颜色搭配,样式布局等有很好的把控与设计;
  • 会使用PS以及切图软件等相关工具(不能遇到一点样式问题就去找设计人员,自己会的话改改更快,小编亲鉴);

目前小编觉得大概就这几个,如果觉得有写漏的,欢迎下方留言。


总结

到这里基本结束啦。整理的过程中,由于有些概念性的东西怕说不明白误人子弟,就在网上搜了一些例子讲解。

小编年少轻狂,之前口出狂言,立下flag说每隔两个礼拜出一篇文章,害。不过每次整理知识点,小编都能收获很多,希望也能帮助有需要的人。还是内句老话,若有不足,请留言指出。若对您有所帮助,emmmmm

肝完这份前端毒鸡汤,你就是赚到了(篇幅较长,建议收藏慢慢细品)