Node.js从4.0开始,支持ES6的大多数新特性,例如:classes、typed arrays、generators、Promises、Symbols、collections、arrowfunctions、block scoping、template strings等。 javascript
(1)原始类型(Primitive Type):
string、number、bollean、null、undefined,原始类型数据直接赋值便可。html
(2)引用类型(Reference Type):
包含ES原生对象、Node.js对象、用户自定义对象三类;引用类型数据通常须要使用new关键字进行建立。 前端
ES6标准中,可使用"模板"方式定义字符串:java
var info=` 用户名:tom 密码:123456 `;
复制代码
模板字符串中可使用${}拼接变量,并执行运算:编程
var price=3.5,count=3;
var info=` 单价:${price} 数里:${count} 小计:${price*count} `
console.log(info);
复制代码
(1)声明常量数组
var empName1='tom';//局部变量
empName2='Mary';//全局变量
复制代码
注意:省略var的全局变量在严格模式下是非法的闭包
(2)声明常量—ES6新特性框架
const fs=require('fs');
复制代码
ES6中,变量的做用域分为三种:
(1)局部做用域:只能在当前函数内使用
(2)全局做用域:能够在任意函数内使用—是全局对象的成员
(3)块级做用域:只能在当前块内使用—ES6新特性编程语言
"use strict";
for(let i=0;i<10;i++){
console.log(i)//正常执行
}
console.log(i)//执行错误
复制代码
(1)算术运算 | + - * / % ++ -- |
---|---|
(2)比较运算 | > < >= <= == ==== != !== |
(3)逻辑运算 | && |
(4)位运算 | & |
(5)赋值运算 | += -= *= /= %= |
(6)三目运算 | ? : |
(7)特殊运算 | typeof (判断变量类型) instanceof(判断一个对象是否从属于某种类型) viod(对任何值返回undefined) , . [ ](取下标运算符) => |
(1)循环结构函数
for | |
---|---|
for...in... | 经常使用于遍历对象 |
for...of... | 只能遍历数组,不能遍历对象(ES6新特性) |
while | |
do...while |
(2)选择结构
if...else... | |
---|---|
switch...case... |
(1) for...in循环能够遍历数组的下标或对象成员名
var arr=[90,80,70]
for(var i in arr){
console.log(i);//将输出0 1 2
}
复制代码
(2)ES6新增的for...of循环能够遍历数组的元素值
var arr=[90,80,70];
for(var v of arr){
console.log(v);//将输出90 80 70
}
复制代码
函数:就是一系列语句的集合,为了实现某种能够重复使用的特定功能。
(1)命名函数:指定了名称的函数对象
function add(num1,num2){
return num1+num2;
}
add(10,20);
复制代码
(2)匿名函数:未指定名称的函数对象
function(num){
arguments.calle(num-1);//递归调用匿名函数
}
复制代码
JS中,全局变量会变成全局对象的成员,形成全局对象的污染;不少JS工具和框架都在设计时,为了不此问题,经常使用匿名函数的自调:
(function(g){
var ns="myNamespace";
})(global);
复制代码
+function(g){
var ns="myNamespace";
}(global)
复制代码
匿名函数在使用时必须使用function关键字,在大型的WEB应用中匿名函数会使用的不少不少,因此ES6中为了简化这种匿名函数的用法,引入了箭头函数的概念。
ES6中,为了简化匿名函数的编写,引入了监听函数语法:
setInterval(()=>{
console.log('timer...');
},1000);
复制代码
箭头函数()是形参列表,function关键字被省略,小括号和大括号中间使用箭头指示符链接;大括号中仍是普通函数同样编写函数体。从此在编写Node.js程序中会常用箭头函数,Node.js官方给出的例子也几乎都是使用的箭头函数。
fs.readFile('index.html',(err,data)=>{
if(err)throw err;
console.log(data);
});
复制代码
箭头函数与普通匿名函数的区别:
一、普通匿名函数中使用了this,this指当前函数对象;
二、在箭头函数中this指与箭头函数自己同一级的this;
三、在箭头函数中使用arguments.callee不在指向当前匿名函数。
闭包(Closure),是ECMAScript中特有的现象。一个闭包,能够看作一种特殊的对象,包含若干函数对象,以及这些函数对象执行时必须依赖的执行上下文对象。
function outer(){
var num=10;
function inner(){
console.log(num)
}
return inner;
}
var fn=outer();
fn();
复制代码
有一个function,外部函数叫outer,outer有一个形参叫num=10,咱们知道num实在outer函数体内,那么他的做用范围也是仅限于outer函数内,离开outer那么num也没有做用了。在outer函数内又定义了一个内部函数叫inner,inner函数须要输出num变量,因为inner内部函数内并无定义,因此会使用outer内定义的局部变量num。outer函数自身并无调用inner,而是将inner内部函数return返回了。outer函数被调用,就会有一个返回值指向了inner函数,也就说fn指向了inner函数,inner函数被外部调用。inner函数不能直接被调用,由于inner函数执行必须依赖一个外部函数执行时,他建立的上下文对象所遗留的num变量。每一次调用outer函数,都返回了一个函数对象,以及这个函数对象运行所必须依赖的一个外部函数提供的上下文。(每调用一次outer函数都会产生一个闭包对象)
不管是前端JS仍是Node.js,闭包使用不当,都有可能引发看似奇怪的错误:
//假设前端项目有三个button元素
var list=document.querySelectAll("button");
for(var i=0;i<list.length,i++){
list[i].onclick=function(){
console.log(i);
}
}
//点击每一个按钮,会分别输出什么?
复制代码
理想结果:三个按钮,点击第几个按钮就输出数字对应的下标
实际结果:点击每一个按钮都会输出数字3
缘由?:这段代码中给这三个按钮各自绑定了一个匿名的监听函数,至关于这段代码执行完成后给外界返回了三个函数对象,这三个函数运行都须要依赖于外部产生的执行上下文对象,他里边有且只有一个i(三个函数对象,外加一个执行上下文对象里的i,这是一个典型的闭包)。循环结束变量i停留在3上,最终任何一个按钮被点击时,他们再去查找变量i,变量i已经被固定在3了,因此不会拿到0、一、2这种结果。
使用Node.js,也能够产生相似前端中的闭包错误:
//目标:1s后,先输出0、一、2
for(var i=0;i<3;i++){
setTimeout(()=>{
console.log(i)
},1000)
}
//实际的运行结果呢?
3
3
3
复制代码
那么咱们怎么解决呢?
for (var i = 0; i < 3; i++) {
setTimeout(((num) => {
return () => {
console.log(num)
}
})(i), 1000);
}
复制代码
ECMAScript中提供了多种建立对象的语法:
(1)对象直接量方式(这种对象不具备反复使用性)
var e1={ename:'tom',work:function(){}}
复制代码
(2)构造函数方式
function Emp(ename){
this.ename=ename;
this.work=function(){}
}
var e2=new Emp('tom');
复制代码
这里边指定emp所须要的成员属性和成员方法,咱们在须要emp类型对象时,能够直接new一个emp对象。
(3)原型继承方法
var parent=new Object();
var child=Object.create(parent);
复制代码
先建立一个parent对象,再使用Object.creaet()方法建立一个parent对象的子对象。
(4)class方式—ES6新特性
ES6借鉴了其余编程语言声明对象的方式,正式启用了class关键字,有了"类"的概念。
class:类,是一组类似对象的属性和行为的抽象集合。
instance:实例,是从属于某个类的一个具体对象。
//class关键字必须用严格模式
"use strict"
//声明一个类
class Emp{
//构造方法
constructor(ename){
this.ename=ename;
}
//实例方法
work(){
console.log(`ENAME:${this.ename}`);
}
}
//建立类的实例
var e3=new Emp('tom');
e3.work();
复制代码
继承,是面向对象编程的一个重要概念,使子对象能够继承父对象中声明的成员,从而极大的提升代码的复用性。
ES6以前的继承都是经过对象的原型(prototype)来实现的:
var graphic={bgColor:'red',borderColor:'blank'}
var rect={width:500,height:300}
Object.setPrototypeOf(rect,graphic);//原型继承
console.log(rect.width);
console.log(rect.hight);
console.log(rect.bgColor);//继承来的成员
console.log(rect.borderColor);//继承来的成员
复制代码
ES6中的继承经过使用class配合extentds关键字来实现。
//声明父类
class Emp{
constructor(ename){
this.ename=ename;
}
work(){
return `ENAME:${this.ename}`;
}
}
//声明子类
class Programmer extends Emp{
constructor(ename,skills){
//调用父类构造方法
super(ename);
this.skills=skills;
}
work(){
return super.work()+`SKILLS:${this.skills}`;
}
}
var p1=new Programmer('tom','js');
console.log(p1.work());
复制代码
(1)ECMAScript预约义对象
String、Boolean、Number、Date、Array、Math、RegExp、function、Object、Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、UriError等16个对象;
(2)Node.js核心模块定义的对象
Bufefer、WriteStream、Socket、ChildProcess等数百个;
(3)等三方模块定义的对象
(4)用户自定义的对象注意:Node.js中不支持BOM和DOM对象,如:window、document等