- 模块系统
- 核心模块
- 第三方模块
- 自己写的模块
- 加载规则以及加载机制
- 循环加载的问题
- npm
- package.json
- Express
- 第三方web开发框架
- 高度封装了http模块
- 提高编码效率,更加专注于业务,而非底层细节
- 学习过程知其所以然
- 增删改查
- 使用文件来保存数据(锻炼异步编码),遇到业务能够自己封装
- MongoDB(数据库)
- (所有方法都封装好了)
软件版本
- 涉及到软件工程知识
- x.x.x
- 第一个数字代表大版本,新增功能比较多,甚至可能去除了某些功能
- 第二个数字:加入了新功能
- 第三个数字:修复bug,提升了性能
- 一般是客户端软件、技术框架开发者比较理解的多
- 做网站很少涉及到版本的概念,网站目的就是快
each和forEach解析
- jquery中each使用,一般用于遍历jQuery选择器选择到的伪数组实例对象
- $.each(数组,function(index,element){}),该方法一个参数为要操作的数组,另一个为具体执行函数
- $(selector).each(function(index,element){}),该方法为选取元素执行函数
- jQuery的function中的参数与原生的forEach方法刚好相反
- each方法的作用
- 方便的遍历jquery元素的
- 可以在不兼容forEach的低版本浏览器中使用jQuery的each方法
- forEach(function(item,index){})为原生js中的方法,可以遍历任何可以被遍历的成员
- forEach只能够遍历数组,each可以遍历jquery获取到的伪数组
- jQuery的each方法支持低版本的IE浏览器,ECMAScript5中的forEach方法不支持IE8版本以及以下的浏览器
- $(‘div’)的jQuery获取元素的方法,返回的是一个伪数组,伪数组是对象不是数组,不能够使用forEach方法,forEach()是Array.prototype原型链中的方法
伪数组转化为数组
- 伪数组使用
[].slice.call(eles)
可以使用数组中的方法 - 伪数组是一个key为数字的对象
node和PHP
- php是文件型的
- node定制性更强
- node比较底层,很多功能需要自己实现。
- 在Node中开启的服务器,默认是黑盒子,所有资源都不允许用户来访问,用户可以访问哪些资源具体有开发人员编写设计的代码为准。可以处理url,php则会显示index.html的形式
1.Node中的模块系统
使用node编写应用程序主要就是在使用:
- ECMAScript语言
- 核心模块
- 文件操作的fs
- http服务的http
- url路径操作系统
- path路径处理模块
- os操作系统信息
- 第三方模块
- art-template
- 必须通过npm来下载可以使用
- 自己写 的模块
- 自己创建的模块
1.1 什么是模块化
- 具有文件作用域
- 通信规则
- 加载 require
- 导出
- 模块的好处:可以完全避免变量命名冲突污染的问题
1.2 CommonJs模块规范
在Node中的js还有一个重要的概念:模块系统
- 模块作用域
- 使用require方法用来加载模块
- 使用exports接口对象用来导出模块中的成员
如果一个模块需要直接导出某个成员,而非挂载的方式,需要使用下面的方式
module.exports = 'hello'//这样另一个模块加载这个模块就会返回'hello',而不是exports对象
1.2.1 加载 require
语法:
var 自定义变量名 = require('模块')
两个作用:
- 执行被加载模块中的代码
- 得到被加载模块中的
exports
导出接口对象
1.2.2 导出exports
- Node中是模块作用域,默认文件中所有的成员只在当前文件模块中有效
- 对于希望可以被其他模块访问的成员,我们就需要把这些公开的成员都挂载到
exports
接口对象中
导出多个成员(必须在对象中):
exports.a = 123
exports.b = {
foo : 123
}
导出单个成员(拿到的就是:函数、字符串):
module.exports = 'hello'
module.exports = function(){//后者会覆盖前者
}
因此,也可以如下方式导出多个成员:
module.exports = {
//加成员
}
1.2.3 原理解析
- 可以认为在node中,没一个模块都有一个自己的
module
对象 - module对象中,有一个成员叫:
exports
成员也是一个对象 - 也就是说需要对外导出成员,只需要把导出的成员挂载到
module.exports
对象中
var module = {
exports : {
}
}
//谁require这个模块,就会得到 module.exports
//为了简化操作,在模块中还有一句代码
var exports = module.exports //exports和module.exports挂载是一样的。这行代码应该是在第一行
console.log(exports === module.exports)//结果为true
//默认在代码的最后又一句:
return module.exports
//一定要记住return的是module.exports,不能通过直接修改exports影响返回的对象,因此导出单个成员需要修改module.exports对象
- exports是
module.exports
的一个引用
1.2.4 require方法加载规则
-
优先从缓存加载
-
不会重复加载相同的模块
-
可以拿到其中的接口对象,不会重复执行模块中的代码
-
这样做是为了避免重复加载模块,提高加载效率
-
require的参数为模块标识
-
加载时要判断模块标识
- 核心模块
- 第三方模块
- 凡是第三方模块都可以通过
npm
来下载 - 使用的时候可以同require(‘包名’)的方式进行加载才可以使用(非路径形式)
- 不可能有一个第三方名字与核心模块名字相同
- 查找规则(以art-template模块为例)
- 先找到当前文件所处目录中的node_modules目录(这个目录就是用来存放第三方模块的)
- 找node_modules/art-template
- 找node_modules/art-template/package.json 文件
- 找node_modules/art-template/package.json文件中的“main”属性
- mian属性中就记录了art-template的入口模块
- 然后加载使用这个第三方包,实际上最后加载的还是文件
- 如果package.json文件不存在或者main指定的入口模块也没有,则node会自动找该目录下的index.js作为默认备选项
- 若果以上所有任何一个条件都不成立,则会进入上一级目录中的node_modules目录查找,规则如上
- 如果上一级还没有,则继续往上上一级查找,知道磁盘根目录还找不到,最后报错:
can not find module xxx
,反正要找到node_modules
目录
- 凡是第三方模块都可以通过
- 自己写的模块
注意:
- 路径形式的模块采用
./
,当前目录不可省略,`…/``上一节目录不可省略 - 核心模块的加载按名字来加载,核心模块的本质也是文件。核心模块的文件已经被编译到二进制文件中了,我们只需要按照名字来加载就可以了
- 一个项目有且只有一个node_modules,不会出现多个node_modules。该目录放在项目同目录(项目根目录)中,这样的话项目中的代码都可以加载到第三方包。
1.3 npm
- node package manager,是一种命令行工具
- npm install art-template jquery bootstrap(可以一次性装几个包)
- install 也可以用
i
代替
1.3.1 npm网站
npmjs.com npm官方网站,可以查询包和发包
1.3.2 npm命令行工具
npm第二层含义就是一个命令行工具,只要你安装node就已经安装好了npm。
npm也有版本的概念(独立的软件)
- npm查看版本输入:
npm --version
npm -v
- npm升级
npm install --global npm//自己升级自己
- npm初始化
npm init
npm init -y//可以跳过向导,快速生成
- npm install
- 一次性把dependencies选项中的依赖项全部安装
- npm i install可以使用i简写代替
- npm install 包名
- 只下载
- npm i 包名
- npm安装指定的版本
- npm i bootstrap@版本号 (中间没有空格)
- npm install --save 包名
- 下载并保存依赖项(package.json文件中的dependencies选项)
- npm i -S 包名
- npm uninstall 包名
- 只删除,如果有依赖项会依然保存
- npm un 包名
- npm uninstall --save 包名
- 删除的同时也会把依赖信息也删除
- npm un -S 包名
- npm help
- 查看使用帮助
- npm 命令 --help
- 查看指定命令的帮助
- –global 为全局安装,安装到node的安装目录下,一般用于影响操作的软件更新或替换
- npm install 包名 --save-dev 这样安装的包和版本号就会存在 package.json 的 devDependencies 这个里面,–save 会会存在 dependencies 里面。简写为 -D
1.3.3 解决npm被墙问题
- npm速度很慢,http://npm.taobao.org/ 淘宝的开发团队吧npm在国内做了一个备份
- 安装淘宝的 cnpm:
# 在任意目录下执行都可以
# --global表示安装到全局,而非当前目录,因此在任意目录都可以执行
# --global不可以省略
npm install --global cnpm
接下来你安装包的时候吧之前的npm替换成 cnpm
举个例子:
# 这里走国外的npm服务器,速度较慢
npm install jquery
#使用淘宝的服务器下载:jquery
cnpm install jquery
如果不想安装cnpm
又想使用淘宝的服务器来下载:
npm install jquery --registry=https://registry.npm.taobao.org
但是每一次手动这样加参数很麻烦,所以我们可以吧这个选项加入到配置文件中:
npm config set registry https://registry.npm.taobao.org
# 查看 npm 配置信息
npm config list
只要经过了上面命令的配置,则你以后所有的npm install
都会默认通过淘宝的服务器来下载。
1.4 package.json
-
package.json,包描述文件,包的说明书,说明包引用了什么依赖
-
npm install art-template --save(放到包后面)或者npm install --save art-template (放到包前面,前后都可以),package.json文件中多了一个属性
"dependencies"
,该属性的值的对象中保存着项目的依赖(依赖什么插件、插件的版本) -
建议每一个项目都有一个package.json文件,就像说明书
-
package.json文件可以通过
npm init
的方式自动初始化出来,
npm init
会以向导的方式(问一句答一句),提问项如下(不填的直接回车):
- name:
- version
- description:(项目的描述)
- entry point:(index.js) (项目的入口一般使用
main.js
作为入口,与json文件同目录) - test command:(测试命令)
- git repository:(github地址)
- keywords:
- author:作者
- license: (ISC)(许可证)
- –save 第三方包会出现"dependencies"属性
-
目前最有用的是"dependencies"选项,包含第三方包的依赖信息
-
建议执行
npm install +第三方包名
都加上--save
这个选项,用来保存(项目依赖信息) -
如果node_modules删除了,只要"dependencies"选项中保存有依赖包,下次直接npm install来加载包即可
补充:
npm 5 以前是不会有package-lock.json
这个文件的
npm 5 之后才加入这个文件
当你安装包的时候,npm 都会生成或者更新package-lock.json
文件
2. Express
- experss : 表达,快速的
原生的http在某些方面表现不足以应对我们的开发需求,所以我们就需要使用框架来加快我们的开发效率,框架的目的就是提高效率,让我们的代码更高度统一。
-
注意 express 也可以使用原生的方法
-
Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。使用 Express 可以快速地搭建一个完整功能的网站。
-
在Node中,有很多的web开发框架,我们这里以学习
express
为主。 -
http://expressjs.com/
//先建一个app.js
// 安装依赖
// 初始化应用
// 引包开发
var express = require('express')
// 2.创建你的服务器应用程序
// 也就是原来的 http.createServer
var app = express() //相当于原来的server
//当服务器收到get请求/的时候,执行回调处理函数。必须为get请求
app.get('/', function (req, res) {
res.send('hello world')
})
//不需要一个一个再判断了
app.get('/about', function (req, res) {
res.send('你好') //此处的编码问题框架已经帮我们处理好了,不需要res.setHeader()
})
//相当于server.listen
app.listen(3000, function () {
console.log('app is running at port 3000.')
})
- express找不到的路径,会返回Cannot GET /a (比如说‘a’) 页面,同时返回状态码404
- express的get方法判断的路径为纯路径,不带传递的参数和锚等内容
- app.get()方法会返回app对象,可以链式编程,继续执行get方法
express的request对象
//req对象中直接包含了 原生 url 模块中返回的方法
req.query //返回参数对象
- request对象的其他属性和方法可以查看文档 http://www.runoob.com/nodejs/nodejs-express-framework.html
express公开指定的目录(处理静态资源)
// 公开指定目录
//只要这样做了,就可以直接通过 /public/xx 的方式访问 public 目录中的所有资源了
app.use('/public/', express.static('./public/')) //相当于拼接的'. + 路径'
- 不公开目录默认找不到路径处理。
- 上述代码公开的是public文件夹下的文件,因此次用
‘/public/’
的形式,也可以使用/public
,它只是在检测url是否以你定义的开头 - 浏览器的访问路径只有在端口号后没有’/'的时候补一个‘/’,浏览器在文件路径后面补一个‘/’,其他的路径都是在浏览器地址栏看到的路径,没有区别。
总结:
- get方法是用来判断访问路径,作出处理的
- use方法是用来开发静态资源的。
- 浏览器路径确认是文件,会在后面自动拼接一个
/
- 在Express中开放资源就是一个API的事儿;模板引擎在Express中也是一个API的事儿
伪数组
- 一般伪数组的形式:(如下的一种对象)
var fakeArr = {
0 : 'abc',
1 : 'efg',
2 : 'aaa',
length : 3
}