Node.js入门(四) : Node.js与ES6

2018-05-31  本文已影响893人  Tenloy

ES6

为什么前端不用,node要用?

严格模式: 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

  1. 在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变量"
    
  2. 在使用let命令声明变量时,一个变量名只能声明一次,不存在命名冲突。不能再像var 一样,同一个作用域内定义两次相同的变量名
  3. 对全局对象的属性影响
    //浏览器中
    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

注意,使用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);
  };

只是简单介绍了一些比较常接触的语法,后续感觉经常遇到的,再补充说明吧

上一篇下一篇

猜你喜欢

热点阅读