node基础
node.js是什么?
- Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine.
- node不是一门语言,不是库,不是框架
- nodejs是一个JavaScript运行时环境
- 简单点来讲就是nodejs可以解析和执行JavaScript代码
- 以前只有浏览器可以解析执行JavaScript代码
- nodejs可以使JavaScript完全脱离浏览器来运行
浏览器中的JavaScript
- ECMAscript
- 基本语法
- if var function object array
- BOM
- DOM
node.js中的JavaScript
- 没有BOM和DOM(window也没有,和浏览器的js不一样)
- ECMAscript
- 服务端不处理页面
- 在node这个js执行环境中为js提供一些服务器级别的操作
- 例如 文件的读取
- 网站服务的构建
- 网络的通信
- http 服务器
node.js是什么?(2)
- event-driven 事件驱动
- non-blocking i/o model 非阻塞 IO模型(异步)
- lightweight and efficient. 轻量和高效
node.js是什么?(3)
- npm 是世界上最大的开源生态系统
- npm 绝大数的js相关的第三方包都存放在npm上,这样方便开发人员去下载使用
注意:浏览器中的js没有文件操作的能力的,不能读取文件,但是node中的js具有文件操作的能力
Node.js REPL(Read Eval Print Loop:交互式解释器)
表示一个电脑的环境,类似 Window 系统的终端或 Unix/Linux shell,我们可以在终端中输入命令,并接收系统的响应。
REPL 的交互式的编程环境可以实时的验证你所编写的代码,非常适合于验证 Node.js 和 JavaScript 的相关 API。
Node 自带了交互式解释器,可以执行以下任务:
- 读取 - 读取用户输入,解析输入了Javascript 数据结构并存储在内存中。
- 执行 - 执行输入的数据结构
- 打印 - 输出结果
- 循环 - 循环操作以上步骤直到用户两次按下 ctrl-c 按钮退出。
Node 的交互式解释器可以很好的调试 Javascript 代码。
nodemon
用来监视node.js应用程序中的任何更改并自动重启服务,非常适合用在开发环境中。
nodemon将监视启动目录中的文件,如果有任何文件更改,nodemon将自动重新启动node应用程序。
nodemon不需要对代码或开发方式进行任何更改。
nodemon只是简单的包装你的node应用程序,并监控任何已经改变的文件。nodemon只是node的替换包,只是在运行脚本时将其替换命令行上的node。nodemon使用教程
- 全局安装npm install -g nodemon
- 本地安装npm install --save-dev nodemon
- 启动应用nodemon [your node app](这里要输入是你要开服务器的文件名)
- 使用帮助nodemon -h 或者 nodemon --help
- 如果没有在应用中指定主机和端口,可以在命令中指定:nodemon ./server.js localhost 8080
- 开启debug模式nodemon --debug ./server.js 80
注:
nodemon 01-http.js
然后这个文件就会自动更新node,也就不用每次更新文件就关闭一次服务器
require 是一个方法:它的作用是用来加载模块的,注意是:同步
在node中 模块有三种: 1、具名的核心模块 例如 fs http 2、用户自己编写的文件模块 例如b.js
相对路径必须加 ./ 且 ./ 不能省略 否则会报错 (可以省略后缀名)
在node中没有全局作用域,只有模块作用域
外部访问不到内部
内部访问不到外部
既然是模块作用域,那如何让模块与模块之间进行通信?
有时候,加载文件模块目的不是为了简单的执行里面的代码,更重要的是使用里面的方法 3、第三方的模块
node在命令行使用
在cmd中:
1、输入node回车即可进入Node.js运行环境。
2、退出只需要连续按两次Ctrl+C或者输入“.exit”回车即可。
3、cls 清除之前终端命令
1、http模块
// 表示引入http模块
const http = require('http');
/*
request 获取URL传给来的信息
response 给浏览器响应信息
*/
http.createServer(function(req,res) {
console.log(req.url);//获取URL
//200表示成功,设置http 响应头 文件类型为HTML 字符集为utf-8
res.writeHead(200,{"Content-type":"text/html;charset='utf-8'"});
// 给页面上面写一句话
res.write('this is nodejs');
// 结束响应,必须写(当然也可以传入一些字符串表示给页面上输入一些东西)
res.end();
}).listen(3001);//端口号
- 第一行请求(require)Node.js自带的 http 模块,并且把它赋值给http变量。
- 接下来我们调用http模块提供的函数:createServer 。这个函数会返回 一个对象,这个对象有一个叫做listen的方法,这个方法有一个数值参数,指定这个HTTP服务器监听的端口号。
如何获取URL的值?
node里面有个URL模块的使用
2、读取文件- fs模块
/*
fs是file-system的简写,就是文件系统的意思
在node中如果想要进行文件的操作,就必须引入fs这个模块
在fs模块中,就提供了所有文件操作的相关的API接口
例如:fs。readFile 就是用来读取文件的
*/
// 1、使用require 方法加载fs 模块
const fs = require('fs')
// 2、读取文件
// 第一个参数就是要读取的文件路径
// 第二个参数是一个回调函数
/*
成功
data :数据 error :null
失败
data:null error :错误对象
*/
fs.readFile('./data/hello.txt', function(error,data){
// <Buffer 68 65 6c 6c 6f 20 6e 6f 64 65 6a 73>
// 文件中存储的其实都是二进制数据 0 1
// 这里为什么不是0和1呢?原因是二进制转为16进制了
// 但是无论是16进制还是二进制,人类都不认识,可以用tostring方法转为认识的字符
console.log(data.toString());
})
3、写入文件- fs模块
const fs=require('fs')
// 第一个参数是文件路径,
// 第二个参数是文件内容
// 第三个参数是回调函数
// error
// 成功:文件写入成功 error:是null
// 失败:文件写入失败 error:就是错误对象
fs.writeFile('./data/你好.txt','我是文件内容',function(error) {
console.log('文件写入成功');
})
var http = require('http');
// 1、创建server
var server = http.createServer()
// 2、监听request请求事件,设置请求处理函数
server.on('request',function(req, res) {
// console.log('收到请求了,请求路径是:' + req.url);
// res.write('hello');
// res.write('world');
// res.end();
// 上面的方式比较麻烦,推荐使用更简单的方式,直接end的同时发送响应数据(用的较多)
res.end('hello nodejs')
})
// 3、绑定端口号 ,启动服务
server.listen(80,function() {
console.log('服务器已启动,可以访问');
})
node中的模块系统
使用node编写应用程序主要就是在使用:
- 1、EcmaScript语言
- 和浏览器不一样,在浏览器中没有DOM和BOM
- 2、核心模块
- 文件操作的fs
- http服务的http
- url路径操作模块
- path路径操作模块
- OS操作系统信息
- 3、第三方模块
- art-template
- 必须通过npm来下载才可以使用
- 4、自己写模块
- 自己创建的文件
什么是模块化?
- 文件作用域
- 通信规则
- 加载 require
- 导出 exports
commonJS模块规范
- JavaScript本身是不支持模块化
在node中的JavaScript还有一个重要的概念:模块系统
- 模块作用域
- 使用require加载模块
- 使用 exports 接口对象用来导出模块中的成员
加载 require
语法:
var 自定义模块名 = require (‘模块名’)
两个作用:
- 执行被加载模块中的代码
- 得到被加载模块中的
exports
导出接口对象
导出 exports
- node中模块作用域,默认文件中所有的成员只在当前文件模块有效
- 对于希望可以被其他模块访问的成员,就需要把这些公开的成员都挂载到exports接口对象中就可以
导出多个成员(必须在对象中):
expoorts.a = 123
exports.b = 'hello'
exports.c = function(){
console.log('ccc')
}
exports.d = {
foo:'bar'
}
导出单个成员(拿到的就是:函数、字符串):
module.exports = 'hello'
以下情况会覆盖;
module.exports = 'hello'
//以这个为准,后者会覆盖前者
moule.exports = function(x, y){
return x + y
}
也可以这样导出多个成员:
module.exports = {
add: function () {
},
str: 'hello'
}
原理分析
exports和module.exports
的一个引用,
console.log(exports === module.exports); //true
exports.foo = 'bar'
//等价于
module.exports.foo = 'bar'
注意下面一点(引用):
// 举例1:
// exports.a = 123
// exports ={}
// exports.foo = 'bar'
// module.exports.b = 345
// 给exports 赋值会断开和module.exports之间的引用
// 同理:给module.exports 重新赋值也会断开
// module.exports = 'hello'
// exports.foo = 'world'
// 举例2:
exports.foo = 'bar'
// {foo: bar}
module.exports.b = 123
// {foo: bar,b: 123}
exports = {
a: 345
}
// 此处exports重新赋值,两者不等于了,就是 exports !== module.exports
// 最终return 的是 module.exports
// 所以无论exports 中的成员是什么都没用
module.exports.foo = 'hhh'
// {foo: hhh,b: 123}
exports.c = 456
// 没关系,混淆你
exports = module.exports
// 重新建立了和module.exports 之间的引用
exports.a = 678
// 由于上面建立了引用关系,这里是生效的
// {foo: hhh,b: 123,a: 678}
//如果再加下面这句的话
// 前面全部推翻了,重新赋值,最后得到的是函数
module.exports = function () {
console.loe('hello')
}
当真正去使用的时候:
1、导出多个成员 :exports.xxx = xxx
2、导出多个成员也可以 :module.exprts = {}
3、导出单个成员 :module.exports
后续继续跟进 nodejs