基本信息javascript
模板列表
接口列表前端
基本信息java
预填数据webpack
注入接口git
基本信息github
输入数据web
输出结果promise
版本控制系统VCS
(Version control system)浏览器
产品级的分支模型:缓存
git是一个基于内容寻址的存储系统。基于文件内容,而不是基于文件。
安装
Windows: msysgit http://msysgit.github.io
Mac: brew install git
Ubuntu: apt-get install git
git config
用户配置:
git config --global user.name "Darcy" git config --global user.name text.example.com
配置级别:
git init
初始化以后会出现一个.git/目录,下面存储着包括config文件在内的几乎全部git相关文件。
git status
跟踪:track
git add
添加文件内容到暂存区
,同时文件被跟踪
。
批量添加: git add .
添加当前目录全部文件
.gitignore
若是有不但愿跟踪的文件,那么须要配置忽略文件。
仅做用于未跟踪的文件。
gitignore常见配置:github中的示例
git rm
从暂存区
删除文件。
git rm --cached
仅仅从暂存区删除
git rm
同时从暂存区和工做目录删除
git rm $(git ls-files --deleted)
删除全部被跟踪,可是在工做目录被删除的文件
git commit
提交。
git commit -m "initial commit"
git commit -a -m "initial commit"
直接提交
git log
提交历史记录。
git log
git log --oneline
只有7位hash和提交时输入的commit message
git log --color --graph --pretty=format:(此处省略2行)
更美观,且有分支链
上面的命令太长了,不可能每次都这样输入,所以须要配置别名alias
。
语法:git config --global alias.shortname <full command>
例子:git config --global alias.lg "log --color --graph --pretty=format:(此处省略2行)"
这样就能够用 git lg
来表示上面那行命令了。
别名其实也存储在gitcofig文件中
git diff
显示版本差别。
git diff
工做目录与暂存区的差别
git diff -cached[<reference>]
暂存区与某次提交的差别,默认是<HEAD>,<HEAD>指向当前的提交
git diff [<reference>]
工做目录与某次提交的差别
git checkout --<file>
撤销本地修改。
即:将工做内容从暂存区复制到工做目录。
git reset HEAD <file>
取消暂存。
即:将文件内容从上次提交复制到暂存区。
git checkout HEAD --<file>
撤销所有改动:取消暂存 + 撤销本地修改。
git branch
git branch <branch-name>
新建分支
git branch -d <branch-name>
删除指定分支
git branch -v
显示全部分支信息
git checkout
经过移动HEAD检出版本,可用于分支切换。
git checkout <branch-name>
切换分支
git checkout -b <branch-name>
新建一个分支并切换到新分支
git checkout -b <reference>
切换到其余引用对象,好比 commit id
或 标签
git checkout -
回到上一个分支(把HEAD移动到上一个分支)
git reset
将当前分支恢复到某个历史版本。如下三种模式的主要区别是内容是否会恢复到工做目录和暂存区。
git reset --mixed e33e42
--mixed是默认参数,不写也行,当前内容(即原来的提交)会被复制到暂存区
git reset --hard e33e42
--hard 时,当前内容(即原来的提交)会被复制到暂存区和工做目录
git reset --soft e33e42
--soft时,暂存区和工做目录都不会有任何改变,原来的提交变成了一个无索引的提交,有可能会被回收,能够用 git reflog
找回来
捷径:git reset HEAD^/HEAD~1/HEAD~n
HEAD的上一次提交,前第n次提交
reset
与 checkout
在操做分支与操做文件时的不一样git stash
咱们在git checkout
切换分支的时候,常常会被提示“当前有未提交的内容,请commit
或stash
”,而咱们一般是写到一半不但愿commit的,因此这时就须要git stash
。
做用是:保存目前的工做目录和暂存区状态,返回一个干净的工做空间。
git stash save 'push to stash area'
第一步:保存
git stash list
第二步:查看已有列表 会显示:stash@{0}: On master: push to stash area
git stash apply stash@{0}
第三步:把保存的内容恢复到工做目录
git stash drop stash@{0}
第四步:把对应的stash命令删除掉
git stash pop stash@{0}
捷径:第三步+第四步
git merge
假定当前在master
分支。
git merge next
合并 next 分支的内容到master分支
若有冲突,会是下面这样:
<<<<<<< HEAD next ======= origin/master >>>>>>> origin/master
====上面指当前分支的提交,下面是要merge过来的分支的提交内容。
git rebase
修剪提交历史的基线,俗称“变基”。
git rebase master
不要在共有分支使用rebase。
git tag
标签,一个不变的别名。用于标记某次发布。指向一个commit对象。
git tag v0.1 e39d0b2
打完标签以后,能够直接使用标签名切换分支: git checkout v0.1
git push
提交本地历史到远程。
git remote
git remote add origin ~/git-server
添加一个远程仓库别名origin
git remote -v
查看远程仓库信息
git fetch
获取远程仓库的提交历史。
git fetch origin/master
git merge origin/master
git pull
git pull <remote> <branch>
=git fetch + git merge
git clone
获取一个远程仓库做为本地仓库。
git clone ~/git-server test2
会克隆远程仓库到 test2目录下
封装实现
暴露接口
声明依赖
math模块:
//math.js function add(a, b) { return a + b; } function sub(a, b) { return a - b; }
caculator模块:
//caculator.js var action = "add"; function compute(a, b){ switch(action){ case "add": return add(a, b); case "sub": return sub(a, b); } }
能够看出 caculator
模块是依赖math
模块的。
math
模块特色:无封装性:变量所有散落在全局里。
接口结构不明显:若是咱们没有简化代码,那么并不能清楚的知道math
到底输出了哪些接口。
caculator
模块特色:没有依赖声明:依赖了math模块可是却没有声明。
使用全局状态:使用了action这个全局状态,应该尽可能避免。
math模块:
//math.js var math = { add: function add(a, b) { return a + b; } sub: function sub(a, b) { return a - b; } }
caculator模块:
//caculator.js var caculator = { action: "add", compute: function compute(a, b){ switch(action){ case "add": return add(a, b); case "sub": return sub(a, b); } } }
math
模块特色:结构性好:用字面量把接口进行告终构化。
访问控制差:依然没有进行控制。
caculator
模块特色:依然没有依赖声明:依赖了math模块可是却没有声明。
没法设置私有属性:action
虽然是成员属性,但在外部依然能够访问到。
IIFE
(Immediately-invoked Function Expression)解决没法设置私有属性
的问题。caculator模块:
//caculator.js var caculator = (function(){ var action = "add"; return { compute: function compute(a, b){ switch(action){ case "add": return math.add(a, b); case "sub": return math.sub(a, b); } } } })();
caculator
模块特色:依然依然没有依赖声明:依赖了math模块可是却没有声明。
有了私有属性:action
是咱们要的私有属性,compute
函数能够访问到,并且在caculator
外面没法访问到。
caculator模块:
//caculator.js var caculator = (function(m){ var action = "add"; function compute(a, b){ switch(action){ case "add": return m.add(a, b); case "sub": return m.sub(a, b); } } return { compute: conpute } })(math);
caculator
模块特色:显示了依赖声明:把math模块做为参数传了进去,而且能够对形参进行命名,这里命名为m
。
math模块仍然污染了全局变量。
必须手动进行依赖管理:math模块是手动传进去的,必须手动保证math是在这以前就被加载了。
注意return
的部分与原来不同了:学名叫 揭露模块模式review module pattern
,优势是在暴露的模块进行增删查改的时候会很是方便。
帮助咱们只暴露一个相似于namespace
的全局变量。而不是将math
这样的模块都注册在全局做用域中。
math模块:
//math.js namespace("math", [], function(){ function add(a, b) { return a + b; } function sub(a, b) { return a - b; } return { add: add, sub: sub } }) //第一个参数为模块声明,第二个参数为依赖的模块,第三个参数为模块的构成
caculator模块:
//caculator.js namespace("caculator", ["math"], function(m){ var action = "add"; function compute(a, b){ return m[action](a, b); } return { compute: compute } }
依赖是统一注册在某个地方,而不是全局中的一个变量。
namespace的实现:
cache
中缓存了全部的模块。
实际返回的是createModule
这个函数,参数包括:模块名,依赖的模块,当前模块的实现。
若是只传入了一个参数,就返回这个模块cache[name]
。
取得全部依赖的模块deps
,即保证前面的模块都已经被定义好了,这样当前模块(这里为caculator
模块)才能运行。
最后初始化模并返回定义的模块cache[name]
。
再也不污染全局环境:把模块都定义在一个namespace
变量中。
没有依赖管理:依然是咱们手动进行依赖管理。
若是这些模块分散在不一样的文件中,咱们在用的时候就要对引入的脚本顺序进行手动排序。
好比 module2.js中依赖了module1.js,那么写的时候就要先写module.js,像这样:
<body> <script src="module1.js"></script> <script src="module2.js"></script> </body>
可是咱们在实际开发过程当中的依赖老是很复杂。那是一条又长又复杂的依赖链。非要人肉分析是会抓狂的。而这实际上是模块系统的工做。
依赖管理(加载 / 注入 / 分析 / 初始化)
决定模块写法
//main.js function add(a, b){ return a + b; } function sub(a, b){ return a - b; } exports.add = add exports.sub = sub
比原来的写法多了接口暴露:exports.add = add
exports.sub = sub
//caculator.js var math = require("./math"); function Caculator(container){ //... } exports.Caculator = Caculator
比原来的写法多了依赖声明: var math = require("./math");
和 接口暴露:exports.Caculator = Caculator
。
优势:
运行时支持,模块定义很是简单:只是利用了几个全局变量exports, module, require
。
文件级别的模块做用域隔离:这几个全局变量的做用域都是文件级别的,虽然JS没有文件级别的做用域,但咱们对它进行了封装,使得使用时一个文件有一个做用域,它们使用起来很是安全。
能够处理循环依赖。
缺点:
不是标准组织的规范。
同步的require,没有考虑浏览器环境。而咱们的浏览器文件加载是一个异步的过程,这是最大的问题,这是否就意味着咱们的浏览器没办法使用了呢?固然不是。如今有不少工具好比browserify
,好比webpack
,能够帮助咱们把多个文件级别的模块打包成一个文件,这样咱们引入单个文件就能够在浏览器里使用了。
由于CommonJS自然的不适合异步环境,因此出现了自然异步的AMD(Asynchronous Module Definition)
与咱们前面的namespace很是像。
//main.js define([], function(){ function add(a, b){ return a + b; } function sub(a, b){ return a - b; } return { add: add, sub: sub } })
比原来的写法多了包裹函数:define
,第一个参数为依赖的模块列表,第二个参数为当前模块的实现。
//caculator.js define(["./math"], function(math){ function Caculator(container){ //... } return { Caculator: Caculator } }
同时AMD还支持一个简单的CommonJS写法,只不过要用一层函数包裹起来define(function(require, exports){ ... })
。
优势:
专为异步I/O环境打造,适合浏览器环境。
支持相似CommonJS的书写方式。
经过插件支持能够加载非JS资源。
成熟的打包构建工具,并可结合插件实现一些预处理的工做。
缺点:
模块定义繁琐,须要额外的函数嵌套。
只是库级别的支持,须要引入额外的库,好比requireJS。
没法处理循环依赖。
没法实现条件加载,由于只是库级别的。
//main.js function add(a, b){ return a + b; } function sub(a, b){ return a - b; } export { add, sub }
比原来的写法多了接口暴露:export {add, sub}
//caculator.js import { math } from './math'; function Caculator(container){ //... } export { Caculator }
比原来的写法多了依赖声明: import { math } from './math';
和 接口暴露:export { Caculator }
。
优势:
真正官方的规范,将来的趋势。
语言级别的支持。
适应全部的JavaScript运行时环境,包括浏览器。
能够处理循环依赖。
针对特定问题的解答,就有专业性
不控制应用程序的流程
被动的被调用
好比,一个DatePicker时间选择器是一个库,一个Backbone.view是一个框架。
控制反转 Inverse of control <···主要区别
决定应用程序生命周期
通常会集成大量的库
下面这个图很好的解释了控制反转:
框架决定了何时调用库,何时要求你的代码去实现某些功能。
框架和库,他们都是解决方案。关于解决方案,分为7各方面:
DOM
communication 通讯
Utility 工具库
Template 模板技术
Component 组件
Route 路由
Architecture MV*架构
jQuery
zepto.JS
Mootools
手势支持:Hammer.js
局部滚动:iScroll.js
高级动画:Velocity.js
视频播放:video.js
处理与服务器的请求与响应
预处理请求数据/响应数据 & Error/Success的判断封装
多种类型请求,统一接口
处理浏览器兼容性
jQuery
zepto.JS
Reqwest
qwest
以上都是异步的请求,但对于实时性要求很是高的产品好比im聊天工具,就须要当即响应。这时须要用websocket。推荐下面的库:
socket.io
提供JS原生不提供的功能
方法门面包装,使其易于使用。即shim(语言垫片),保证明现与规范一致。
异步队列 / 流程控制 好比promise
Bootstrap
Foundation
监听url变化,并通知注册的模块,进行页面切换
经过Javascript进行主动跳转
历史管理
对目标浏览器的兼容性的支持
提供一种范式帮助(强制)开发者进行模块解耦
试图与模型分离
更容易进行单元测试
更容易实现应用程序的扩展
各类框架比较的参考网站:
http://todomvc.com/
https://www.javascripting.com/
https://www.javascriptoo.com/
http://microjs.com/#
数据类型(每一个页面的每一个模块都要单独定义包含的数据类型列表)
模板资源
异步接口(请求方式,请求地址,输入参数,输出结果)
页面摘要
项目结构
初始代码
模拟数据
通用原件(logo,输入框,图标,按钮,翻页,复选框列表,loading)
通用列表(歌单。歌手,收藏的节目)
复合组件(好比评论)
浮层弹窗
一个组件(BannerSlifer)的栗子:
本地测试
异步测试
对接联调
打包发布
优化配置