Node.js入门(四) : Node.js与ES6
ES6
- ECMAScript es标准的作用 定义js的发展方向的一套标准,新的语法,写起来更严谨更安全更简便。
- 是向下兼容ECMAScript 5.1的
- 2015年6月就已经发布了,但是由于浏览器的兼容性,在前端开发中,应用性并没有在Hybid APP、nodejs开发中那么高
- ES6对JavaScript的改变还是很大的,个人感觉如同jdk 1.5之于Java了,不过一系列的新增语法,也让一些js开发朋友褒贬不一,有人说限制了js的简洁性,也有人说是对开发性的一种提高(不过,刚开始上手的话,还是建议ES5开始,体验一下js作为脚本语言没有逐步进化时灵活的魅力)
- 目标:让JavaScript语言可以用来编写大型的复杂的应用程序,称为企业级开发语言。
为什么前端不用,node要用?
-
前端
- 太受浏览器的限制(IE Chrome Safari Firefox等等)
-
Node.js
- Node.js代码是只运行在Chrome v8平台上,其对ES6的兼容性还是不错的,并且只运行在服务器端,所以不用考虑其他兼容性
- ES6确实能给我们带来很多方便
- Node.js 覆盖了93%的ECMAScript 6
-
阮一峰es6入门 http://es6.ruanyifeng.com/#README 阮老师这本书很系统,本文中,只会简单讲一些nodejs比较常用的新增语法,有什么不足之处,欢迎指正
严格模式: strict mode
消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
- 消除代码运行的一些不安全之处,保证代码运行的安全;
- 提高编译器效率,增加运行速度;
- 为未来新版本的Javascript做好铺垫。
'use strict' 一旦使用这个,就表示必须要摒弃旧语法
保留字:
一旦出现Unexpected strict mode reserved word这样的错误说明你用保留字做了参数名了。
es6-->implements, interface, let, package, private, protected, public, static, yield
es5-->class, enum, export, extends, import, super
阮一峰 严格模式 http://www.ruanyifeng.com/blog/2013/01/javascript_strict_mode.html
块级作用域
凡是被{}包裹的代码属于一个代码块,自成一块作用域
ES6之前,JavaScript是: 词法作用域 + 函数作用域 + 变量提升规则。
ES6:
但凡是let、const定义的变量,都增加了块级作用域的限制(var的不受限制,大括号外还是能访问到)
但凡是let、const定义的变量都取消了变量提升规则,即先访问,再定义行不通了. "严格模式下,运行会报错"
ES6里面不建议使用var了,因为var定义的变量没有块级作用域,还会出现变量提升的情况,这样经常会导致你意想不到的错误
- 块级作用域对函数定义的影响
function foo () {
console.log('I am the outside one')
};
(function(){
//因为在ES5中是没有块级作用域的,if中的函数定义,会被提升到这
//function foo() { console.log('I am the inside one') }
if(false){
// 重复声明一次函数
function foo() {
console.log('I am the inside one')
}
}
foo(); // 在ES5中运行会得到“Iam inside”, 但是在ES6中运行,则会得到“Iam outside”
}());
这个特性很容易引起冲突,因为我们很难判断我们代码的运行环境究竟在哪里,是遵循ES5的法则还是遵循ES6的法则。所以当这段代码运行在nodejs环境中的时候,编译器会选择直接报错,而并不像理论上分析得到的结果那样。
我们应该尽量规避上面那种情况,使用严格模式。在严格模式下,函数必须定义在顶级作用域,定义在if,for语句中会直接报错。
- 块级作用域对变量定义的影响(死区)
let foo = 'foo';
if(true){
console.log(foo);
let foo = 'foo bar';
console.log(foo);
}
下面的代码在第一次输出foo的时候会报错,提示foo没有定义,这就是死区效应
。
只要块级作用域内存在let命令,它所声明的变量就绑定在这个区域,不再受外部影响。ES6明确规定,只要块级作用域中存在let命令,则这个块区对这些命令声明的变量从一开始就形成封闭的作用域。只要声明之前,使用这些变量,就会报错。只需要记住:在块级作用域内如果使用let声明了某个变量,那么这个变量名必须在声明它的语句后使用,即使块外部的变量有与之重名的也不行
。从块开头到声明变量的语句中间的部分,称为这个变量的“暂时性死区”
。
这样也意味着我们不再能使用typeof关键字检测某个变量是否被声明了:
typeof x; // 返回'undefined',即使x没有声明
typeof x // 与let x =10。一起使用则报错。
let x = 10;
ES6之所以如此设计,是为了减少运行时错误,防止变量在声明前使用。
为了避免死区,提供两种方法:
一、是像java那样在编写代码时里层和外层尽量不重名。
二、是像编写传统的js代码那样,把变量在块级作用域顶层进行声明,虽然let的产生实现了java中声明变量的效果,很多人推荐使用就近原则。
参考链接:https://blog.csdn.net/hukaihe/article/details/70142802
let、const
let
- 在for循环中,let命令每次定义的作用域都在本次循环的方法体内
let arr = []; for(var i = 0; i <6; i++){ arr.push(function () { console.log(i); i++; //注意这里 }); } arr[0](); arr[0](); arr[1](); //如果上面是var,那么打印的都是6,如果是let,那么打印结果是0 1 1 //"证明let是为每个function声明了一个单独的相互没影响的i变量"
- 在使用let命令声明变量时,一个变量名只能声明一次,不存在命名冲突。不能再像var 一样,同一个作用域内定义两次相同的变量名
- 对全局对象的属性影响
- 在ES5中,全局对象的属性和全局变量是等价的。ES6规定,使用var, function声明的全局变量依旧作为全局变量的属性存在,而使用let,const,class声明的全局变量则不属于全局变量的属性。
- nodejs中有所不同,var let定义的全局变量就是所属当前文件的,不使用let var const,直接定义的才是全局变量global的属性,详情见我 Node.js入门(二):包、模块化、Repl环境及全局对象Global
//浏览器中
var foo = 'foo';
let bar = 'bar';
console.log( foo === window.foo ); // =>true
console.log( bar === window.bar );// => false
//Nodejs中
var foo = 'foo';
let bar = 'bar';
string = 'str';
console.log( foo === global.foo ); // => false
console.log( bar === global.bar );// => false
console.log( string === global.string );// => true
const
- 定义常量,不会发生变化
如定义了常量,再去修改就会报错error Assignment to constant variable 不可以给常量赋值 - const定义的常量,作用域与let相同
- 应用场景const用来定义静态变量,加载模块的时候,定义个常量,把模块赋值给常量
注意,使用const声明对象的时候,只能保证对象的引用地址不被更改,并非此对象不被修改。
const foo = {nickname:'John Doe'}
foo.nickname = 'Jane'; //okay
foo.age = 25; // okay
foo = {nickname:'Kyle Hu'} // 报错,因为改变了引用关系
promise
https://cnodejs.org/topic/560dbc826a1ed28204a1e7de
异步流程控制的解决方案
回调地狱
异步流程--->回调函数的嵌套
异步流程控制---->用同步的方式去写异步的代码
箭头函数
箭头函数就是一种语法糖
语法糖是一种语法,用这种语法能尝到甜头,能是编程高效
当函数体有一个参数有返回值的时候
var foo=function(v){ return v;}
var foo=v=>v;
当函数体没有参数有返回值的时候
var foo=function(){ return v;}
var foo=()=>v;
当函数体有多个参数有返回值的时候
var foo=function(v1,v2){ return v1+v2;}
var foo=(v1,v2)=>v1+v2;
当函数体有多个参数没有返回值的时候
var foo=function(v1,v2){
console.log(v1); console.log(v2);
}
var foo=(v1,v2)=>{
console.log(v1); console.log(v2);
};
只是简单介绍了一些比较常接触的语法,后续感觉经常遇到的,再补充说明吧