Node.js概述及编程基础
目录
- Node.js概述
- 什么是Node.js
- Node的特点
- Node程序的运行方式
- Node.js编程基础
- JavaScript语句与注释
- 变量
- 变量的提升和泄露
- 变量提升
- 变量泄露
- 全局作用域和函数作用域
- 常量
- 数据类型
- 数组或集合的遍历
- 函数
- 类
- 代码规范
Node.js概述
什么是Node.js
Node.js简称Node,是一个可以使JavaScript运行在服务器端的平台,是JavaScript的运行时环境,Node.js可以解析和执行JavaScript代码。
JavaScript本是一种Web前端语言,Node.js让JavaScript成为服务器端脚本语言,现在的JavaScript可以完全脱离浏览器来运行。
Node.js将V8引擎封装起来,作为服务器运行平台,以执行JavaScript编写的后端脚本程序。
Node.js进一步提升JavaScript的能力,在Node执行环境中提供了一些服务器级别的操作API,使JavaScript可以访问文件、读取数据库、访问进程,从而胜任后端任务。
Node.js是跨平台的。
Node.js除了自己的标准类库之外,还可使用大量的第三方模块系统来实现代码的分享和重用。
与其他后端脚本语言不同的是,Node.js内置了处理网络请求和响应的函数库,也就是自备了HTTP服务器,所以不需要额外部署HTTP服务器。
npm是世界上最大的开源库生态系统,绝大多数JavaScript相关的包都存放在了npm上,可以方便的下载使用。
Node的特点
- 非阻塞I/O
非阻塞I/O又称为异步式I/O。
是指当线程遇到I/O操作时,不会以阻塞方式等待I/O操作完成或数据返回,而只是将I/O请求转发给操作系统,继续执行下一条指令。
阻塞I/O是指在执行过程中遇到I/O操作时,操作系统会撤销该线程的CPU控制权,使其暂停执行,处于等待状态,同时将资源转让给其他线程
- 事件驱动
非阻塞I/O是一种异步方式的I/O,与事件驱动密不可分。
事件驱动以事件为中心,Node.js将每一个任务都当成事件处理。Node.js在执行过程中会维护一个事件队列,需执行的每个任务都会加入事件队列并提供一个包含处理结果的回调函数。
在事件驱动模型中,会生成一个事件循环线程来监听事件,不断地检查是否有未处理的事件。
Node.js的异步机制是基于事件的,所有磁盘I/O、网络通信、数据库查询事件都以非阻塞的方式请求,返回的结果由事件循环线程来处理。
JavaScript是一门单线程的语言,它的异步和多线程的实现是通过事件循环机制实现的
- 单线程
Node.js的应用程序是单线程的,但是通过事件和回调支持并发,性能变得非常高。
在阻塞模式下,一个线程只能处理一项任务,要想提高吞吐量必须使用多线程。
在非阻塞模式下,线程不会被I/O操作阻塞,该线程所使用的CPU核心利用率永远是100%,I/O操作以事件的方式通知操作系统。
Node.js在主线程中维护一个事件队列,当接受请求后,就将该请求作为一个事件放入该队列,然后继续接收其他请求。
Node.js内部通过线程池来完成非阻塞I/O,Node.js的单线程是指对JavaScript层面的任务处理是单线程的,而Node.js本身是一个多线程平台。
Node程序的运行方式
- 使用npm包管理器
//在package.json文件中配置启动(start):
"scripts": {"start": "node ./src/server.js","test": "echo \"Error: no test specified\" && exit 1"
}//用npm启动startnpm start
- Node程序文件名
Node.js编程基础
Node.js自6.0版本开始全面支持ES6。
JavaScript语句与注释
- 每条语句都以“ ; ”结束
- 一行可以有多条语句(若一行有多条语句,每条语句都要以“ ; ”结束,建议一行只有一条语句)
- 若一行语句太长可以用“ \ ”进行续行
- 语句块:由多条语句组成,这些语句都在“ { } ”中
- 注释:单行注释:“ // ” ;多行注释:“ /* … */ ”
在WebStorm中,单行注释的快捷键:Ctrl + ’ / ‘;多行注释的快捷键:Ctrl+Shift+’ / ’
变量
- 可以是任意的数据类型
- 变量名是由字母、数字、下划线“ _ ”、“ $ ”组成的字符序列,但是首字符不能是数字
- JavaScript是弱类型语言,在定义变量时不需要指定变量的类型,都可以使用关键字var声明
- 可以在声明变量的同时赋值,也可以先声明变量然后再赋值
- 变量可以反复的赋值
变量的提升和泄露
变量提升
在ES5中变量可以在声明之前使用,它的值是undefined。
在ES6中使用let关键字声明变量来改变这种行为,变量不能在声明之前使用。
console.log(test); //变量提升 结果为undefined
var test = 'hi';
变量泄露
在语句块中使用var关键字声明的变量,会被提升为全局变量,这样就会造成局部变量值的泄漏。
防止变量值的泄漏方法是使用let关键字声明局部变量。
var temp = 'Hello';
for(var i=0;i<temp.length;i++)
{console.log(temp[i]);
}
console.log(i); //用var声明i 提升为全局变量 i=6 变量泄露
全局作用域和函数作用域
ES5中作用域只有两个:
- 全局作用域:从声明的位置开始到源程序的结束均有效
- 函数作用域:只在函数范围内有效
ES6中增加的块级作用域:在ES6中使用let关键字声明的变量只在它所在的块级作用域中有效。
常量
ES6中使用const关键字定义只读常量。
数据类型
Number(数值类型)
- 不区分整数和浮点数
- 二进制以0b开头,八进制数以0o开头,十六进制以0x开头
- 若不能计算出结果显示为NaN(Not a Number),Infinity表示无限大
String(字符串)
- 使用单引号或双引号括起来的文本(字符序列)
- ES6提供模板字符串:反引号将模板字符串括起来,用 ${ } 将 变量括起来
var host = `http://localhost`;
var port = 8080;
var url = `API接口为:${host}:${port}` //模板字符串
console.log(url) //输出: API接口为:http://localhost:8080
- 模板字符串中可以不嵌入任何变量,按实际格式输出
Boolean(布尔类型)
- 值只有true、false两种,常用于条件判断
在比较等于时,建议使用 === 而不是 ==
null 和 undefined
- null:表示空值,即什么也没有
- undefined:表示’未定义’,通常用于判断函数的参数是否正常传递
Array(数组)
- 数组用[ ]表示,元素之间用逗号分隔
- 数组元素可以是任意类型
- 通过数组名带索引访问数组元素,索引的范围是 0~数组长度减1
Object(对象)
- 用’ { } '表示,是由键值对组成的无序集合,键值对之间用逗号分隔,'键’就是对象的属性
- 键的类型必须是字符串类型,值可以是任意类型
- 通过’对象名.属性名(键名)'来访问对象的属性
- 在ES6中允许将表达式作为键名,但表达式必须放在’[ ]'中
Symbol(符号)
是ES6引入的新类型,用来表示一个独一无二的值,其值通过Symbol( )函数自动生成。
Symbol值可以作为对象的属性名。
有三种表示方式:
let k = Symbol();
let obj = {}//第一种
obj[k] = "hi"
console.log(obj)//第二种
let myobj = {[k]:"hi"
}
console.log(myobj)//第三种
let obj2 = {}
Object.defineProperty(obj2,k,{value:'hello'})
console.log(obj2[k])
Set(集合)
集合是无重复的、无序的数据结构,类似于数组,集合中的成员不重复,都是唯一的。
集合是一个构造函数,用于生成Set数据结构。
- Set函数可以接收一个数组作为参数
var arr = [5,2,7,5,2,5,8];
const s1 = new Set(arr);
console.log(s1); //输出: Set{5,2,7,8}
- 属性:
constructor:表示构造函数
size:表示集合的元素个数
var arr = [5,2,7,5,2,5,8];
const s1 = new Set(arr);
console.log(Set.prototype.constructor); //输出:[Function:Set]
console.log(s1.size); //输出:4
- 方法(函数):
add(x):将x添加到集合中
delete(x):删除集合中的x,返回的是布尔值
has(x):返回布尔值,表示x是否是集合的成员
clear():清除所有成员,没有返回值
var s1 = new Set([45,23,78,44,56])
console.log(s1)
console.log(s1.keys()) //通过迭代器(遍历器)来遍历集合中的元素
console.log(s1.values()) //Set集合没有键只有值 keys遍历和values遍历结果是一样的
console.log(s1.entries()) //遍历键值对
遍历的使用:
- […集合名]
var s2 = new Set(['red','blue','green'])
let arr = [...s2] //遍历集合 将集合元素赋给一个数组 ...不定参数
console.log(arr)
- map遍历
set = new Set([...set].map(x => x*2)) //通过map遍历集合中的元素,让每个元素乘以2
- filter过滤集合元素
let set = new Set([1,2,3,4,5,6,7,8,9]);
set = new Set([...set].filter(x => (x%2)==0)); //遍历set集合,并将集合中的偶数全部过滤出来
//输出:2,4,6,8
Map(映射)
ES6引入Map数据结构,与对象类似,但各种类型的数据都可以作为键。
Map本身是一个构造函数,用于生成Map数据结构。
//set方法给map设置一个键值对
let map2 = new Map()
map2.set('school','11')
console.log(map2)
//get 获取键对应的值
console.log(map2.get('school'))
console.log(map2.keys()) //获取键
console.log(map2.values())
- 可以使用Map结构的set方法添加成员
- 使用Map结构的get方法读取键(成员)
WeakSet集合
集合中的元素只能是对象,不能是其他类型。
Node的垃圾回收机制,不考虑WeakSet中元素的回收。
let ws = new WeakSet({"name":"张三"})
数组或集合的遍历
ES5:
- ES5中使用的方式
for(var i=0;i<array.length;i++){console.log(array[i])}
- forEach循环
array.forEach(x => console.log(x))
- for( 变量 of 数组名或集合名)
for(let k of array){console.log(k)
}
函数
函数的声明
function 函数名([参数]){函数体语句;
}//ES6支持默认参数的函数
function testFun(x=21,y=19){return x+y
}
函数的调用
//事件名 = 函数名([参数])testFun(45,78)
默认参数的函数
//默认参数的函数
function testArgs(x=21,y=19) {//x,y参数带有默认值return x+y;
}//调用函数
let s1 = testArgs();
console.log(s1);
//40//传参
let s2 = testArgs(78,56);
console.log(s2);
//134//传一个参数
let s3 = testArgs(20);
console.log(s3);
//39
ES6中的rest参数
JacaScript的函数默认带有arguments对象,利用该对象可以获得调用者传入的所有参数。
//我们在定义函数时 函数默认自带一个argument对象 对象中存放函数的所有参数
function testSum() {let sum = 0;for(let i=0;i<arguments.length;i++){sum = sum + arguments[i];}return sum;
}//无参的调用
console.log(testSum())
//有参调用
console.log(testSum(1,2,3))
ES6中的rest参数(…变量名),用于获取函数的多于参数,可以替代ES5中的arguments对象。
//es6中rest参数
function test(...values) {let sum = 0;for(let k of values){sum += k;}return sum;
}
console.log(test(2,4,6))
匿名函数
在声明函数时省略函数名。
//匿名函数
var test = function (x,y) {return x+y;
}
let s = test(78,89)
console.log(s)
箭头函数
使用箭头符号(=>)声明的函数。
var 变量名 = ([参数])=> {函数体语句;
}
- 若函数体语句只有一条,可以省略’{ }’
高阶函数
把函数作为参数的函数。
//高阶函数:把abs函数作为参数function diffAvg(m,n,fn){return fn(m-n);
}//高阶函数的调用:
let k = diffAvg(45,78,Math.abs)console.log("高阶函数:"+k);
- fn:函数指针,指向的实参函数的入口地址(函数名代表了函数的入口地址)
闭包
当函数作为返回值或参数传递时,该函数就被称为闭包。
闭包是能够读取其他函数内部变量的函数,可以使用函数之外定义的变量。
//闭包:将函数作为返回值或参数 能够读取其他函数内部的变量
var basePrice = 10.00; //起步价
var baseMiles = 3.00; //起步里程
function taxiPrice(unitPrice,Mileage) {function totalPrice() { //计算总费用if(Mileage > baseMiles){return Mileage*unitPrice;}else{return basePrice;}}return totalPrice(); //返回函数
}console.log(taxiPrice(2,6));
类
ES5中通过函数来创建实例对象。
//ES5通过函数创建实例对象
function Visitor(vname,sex) { //是一个类名 也是一个函数名(构造函数)this.vname = vname;this.sex = sex;
}
Visitor.prototype.getInfo = function () { //通过原型对象添加函数return this.vname + this.sex;
}
//创建实例对象
var visitor = new Visitor('邓瑛','男');
console.log(visitor.getInfo())
ES6中引入类模板,使用class关键字定义类。
//ES6中类的定义
class Visitor {constructor(vname,sex) { //构造函数 初始化对象的属性this.vname = vname;this.sex = sex;}getInfo() {return this.vname + this.sex;}
}
var visitor = new Visitor('遥岑','女'); //通过类名调用了构造函数
console.log(visitor.getInfo());
代码规范
编码格式:
- 每条JavaScript语句都以分号结束。建议每行只有一条语句
- 缩进使用2个半角空格或4个半角空格, 而不使用Tab键
- 每行仅声明一个变量,而不要声明多个变量
- 字符串尽量使用单引号
- 符号“{”应在行末,表示代码块的开始,符号“}”应在行首,表示代码块的结束
命名规范:
- 变量名采用小驼峰命名法(除第一个单词之外,其他单词首字母大写)
- 常量全部采用大写
- 函数名也采用小驼峰命名法,第一个单词采用动词
- 类和构造函数名采用大驼峰命名法(每个单词的首字母都是大写),第一个单词使用名词
- 文件名采用下划线分割单词
Node.js概述及编程基础相关推荐
- Node.js(window)基础(1)——用cmd命令行访问某一文件夹下的js文件
一.安装,从官网上下载安装,安装基本一直点击下一步就行.注意:node.js基于Python的,安装node.js之前电脑上要安装Python,最好是Python2.7或2.6. 二.cmd进入命令行 ...
- Node.js快速入门之基础模块及常用api
目录 Node特点 模块化 文件 文件读取 文件写入 文件删除 Buffer(缓存数据) 读取/删除目录 输入输出 文件流 写入流 读取流 先流入后流出的整个流程 管道流 Node事件 Os模块和pa ...
- 最新Node.JS入门视频教程20集 Node.JS快速入门编程教材 Node.JS视频(偏重基础)
本套NodeJS教程共20集,同时包含源码.教程内容有点偏重基础,非常适合零基础的朋友学习! 下载地址:百度网盘
- Java 概述和编程基础
First of all,Java概述: 类是Java程序设计的基石和基本单元: main()方法是程序的入口,它是共有的.静态的,参数String[] args表示一个字符串数组可以传入该程序,用来 ...
- Node.js零基础自学(持续更新中)
1. Node.js时基于Chrome V8 引擎的JavaScript运行环境.官网:Node.jsNode.js® is a JavaScript runtime built on Chrome' ...
- node.js异步编程
目录 1.同步API 2.异步API 回调地狱 用promise解决回调地狱 异步函数 Node服务器端编程 1.同步API 只有在当前的API执行完成后,才执行下一个API.代码的执行方式是按照代码 ...
- PHP和Node.js开发之间有什么区别
在很长一段时间内,决定在Node.js和PHP之间进行选择是一件很麻烦的事情,但对于后端程序员来说,这一直很麻烦,但它从未影响过开发人员.但是事情很快就发生了变化,现在开发人员必须选择其中之一.Nod ...
- 《Node.js开发实战》代码下载、简介与前言
请下载代码评估:https://pan.baidu.com/s/1qYC3cVa (密码: bba3). 内容简介 本书以实战开发为原则,以Node.js原生知识和框架实战为主线,详细介绍Node ...
- php和nodejs和java的区别_讨论PHP和Node.js开发之间有什么区别
在很长一段时刻内,决定在Node.js和PHP之间进行挑选是一件很费事的工作,但关于后端程序员来说,这一直很费事,但它从未影响过开发人员.可是工作很快就发生了改变,现在开发人员有必要挑选其中之一.No ...
最新文章
- Generator + Promises, the best of all worlds in ES6
- Py之pyttsx:pyttsx/pyttsx3​​​​​​​的简介、安装、使用方法之详细攻略
- 初玩树莓派所遇见的坑
- 777后无效 执行chmod_厉害了!南航777机队和南航空姐在人民大会堂接受表彰!
- [CentOS Python系列] 四.阿里云服务器CentOS连接远程MySQL数据库及pymsql
- tplink 跨路由器 共享打印机_焦作联通案例分享:跨网段通过防火墙共享打印机设置...
- 20145240 《Java程序设计》第四次实验报告
- kotlin函数式编程_我最喜欢的Kotlin函数式编程示例
- linux安装pgsql源码包解压,在Linux(centos)中使用源码安装pgRouting
- Cisco ftp linux 权限,在Cisco设备上利用FTP传IOS文件
- LeetCode(59):螺旋矩阵 II
- 信道编码-RS-CRC-交织(一)
- spyder下载python3.5_ubuntu14.04 anaconda tensorflow spyder(python3.5) + opencv3
- Java获取名字首字母拼音及用户按名字拼音分组工具
- 中国指定银行支行数据及省市数据获取
- 2022小旋风万能蜘蛛池9.02开心版/站长必备SEO+带教程
- Git问题Everything up-to-date正确解决方法
- Type string trivially inferred from a string literal, remove type annotation
- 关于微信小程序通讯录人名分组的实现
- 保研导师联系邮件模板
热门文章
- Git 进阶 —— 时光穿梭机
- Git基础之(三)——时光穿梭机
- IDEA 解决import类飘红
- OpenCV学习十:blur、GaussianBlur、medianBlur 、bilateralFilter 图片的模糊、高斯模糊、中值模糊、二值滤波(课程里将模糊与滤波认定为一样) 以及 锐化算子
- 利用二次导数对函数凹凸性的证明
- 基于java的简单英雄联盟胜率计算
- 新手做数据分析的5大误区,一定要避开!
- STC用PCA测量脉宽_示波器在进行频率测量时如何减少误差
- 玩自动阅读,100部手机去操作,一天可以赚1200?揭秘背后的故事
- linux nand 驱动,Linux NAND FLASH驱动分析(一)