• 【生日快乐】Node.js 实战 第1章 欢迎进入Node.js 的世界 1.2 ES2015、Node 和 V8


    Node.js 实战

    第1章 欢迎进入Node.js 的世界

    1.2 ES2015、Node 和 V8

    对于“以前的JavaScript” ,Node解决了很多问题:

    • 创建类

    • const 和 let 代替了var 解决了作用域的问题

    • Node6 开始,可以使用:

      • 默认函数参数
      • 剩余参数
      • spread 操作符
      • for … of 循环
      • 模板字符串
      • 解构
      • 生成器

    https://node.green/ 上汇总了Node 支持的ES 2015特性

    在这里插入图片描述

    先说类。

    ES5 及以前的版本中,我们需要使用 prototype对象来创建类似于类的结构:

    function User(){
        //构造器
    }
    
    User.prototype.method = function(){
        //方法
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    有了Node 6 和 ES 2015,我们就可以写成下面这样了:

    class User {
        constructor() {
        }
    
        method() {
            
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    可以看到,代码量少了,也更容易理解了,Node也支持子类、超类和静态方法。

    const 和 let 是从 Node4 开始支持的。

    在ES5 中,所有变量都是用var 创建的,不管是在函数中还是全局作用域中,都是用var定义变量,所以我们没办法在if语句、for循环以及其他块中定义块级别的变量。

    这里一个问题:【到底应该用const 还是 let】

    在决定是用const 还是let 时,几乎都可以用const。因为你的大部分代码都是在用你自己的类实例、对象常量或不会变的值,所以大部分情况下都可以用const。即便是有可修改属性的对象,也是可以用const声明的,因为const的意思是引用是只读的,而不是值是不可变的。

    Node还有原生的promise 和 生成器。

    让开发者可以用流畅的接口风格编写异步代码,有很多库都支持promise。

    流畅的接口风格:

    [1,2,3]
    	.map(n => n * 2)
    	.filter(n => n > 3)
    
    • 1
    • 2
    • 3

    生成器可以把异步I/O 变成同步编程风格。

    Koa Web 应用库中用到了Generator,如果结合Koa 使用 promise和其他生成器,你就可以抛开层层嵌套的回调(“回调地狱”),在值上yield。

    ES2015中的模板字符串在Node 中也很好用。

    在ES5中,字符串常量不支持插值,也不能跨行。

    现在我们可以使用反引号(`) 定义模板字符串,这样不仅可以插值,还可以跨行。

    this.body = `
        

    Hello from Node

    Welcome, ${user.name}!

    > `
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    以前只能使用普通字符串进行拼接,不仅代码多,还容易出错。

    箭头函数。

    比起普通函数写法,箭头函数的语法非常精炼。

    有一个参数和一个返回值的回调函数:

    [1,2,3].map(v => v * 2)
    
    • 1

    在Node中,我们一般会需要两个参数,回调的第一个参数通常是错误对象

    const fs = require('fs');
    fs.readFile('package.json',(err, text) => {
        console.log('Length:',text.length)
    });
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    如果函数体的代码不止一行,则要用到大括号,箭头函数的价值不仅体现在其精炼的语法,还和JavaScript 的作用域有关。

    在ES5以及之前的版本的语言中,在函数中定义函数会把this的应用变成全局对象,像下面这样就很容易出错:

    function User(id){
        //构造器
        this.id = id;
    }
    
    User.prototype.load = function (){
        var self = this;
        var query = 'select * from user where id = ?';
        sql.query(query,this.id,function (err,users){
            self.name = users[0].name;
        })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    给self.name 赋值那行代码不能写成 this.name,因为这个函数的this 是个全局变量。

    常用的解决办法是在函数的入口处将this 赋值给一个变量。

    但是。

    箭头函数的绑定就没有这个问题,在ES2015中,上面的例子可以改写成更直观的形式:

    // function User(id){
    //     //构造器
    //     this.id = id;
    // }
    //
    // User.prototype.load = function (){
    //     var self = this;
    //     var query = 'select * from user where id = ?';
    //     sql.query(query,this.id,function (err,users){
    //         self.name = users[0].name;
    //     })
    // }
    
    class User {
        constructor(id) {
            this.id = id;
        }
    
        load() {
            const query = 'select * from users where id = ?';
            sql.query(query, this.id, (err, users) => {
                this.name = users[0].name;
            });
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    开发者不仅可以用const 更好地定义建模数据库查询,而且还去掉了麻烦的self 变量。

    1.2.1 Node 和 V8

    Node 的动力源自V8 JavaScript 引擎,它是由服务于Google Chrome 的 Chromium项目组开发的。

    V8的一个很棒的特性是它会把JavaScript 直接编译为机器码,另外它还有一些代码优化的特性,所以Node 才能这么快。

    之前我们说到Node 的另一个本地部件libuv,它负责处理I/O,而V8 负责JavaScript 代码的解释和执行,Node 用C++ 绑定层将libuv 和 V8结合。

    下图是Node.js 的软件栈:

    在这里插入图片描述

    因此,Node 中能用的JavaScript特性都可以追溯到V8对该特性的支持。

    这一支持是通过特性组来管理的。

    1.2.2 使用特性组

    Node包含了V8提供的ES2015特性。

    这些特性分为shipping.staged和 in progress三组。

    shipping组的特性是默认开启的,staged和 in progress组的特性则需要用命令行参数开启。

    如果你想用staged特性,可以在运行 Node时加上参数–harmony,V8团队将所有接近完成的特性都放在了这一组。

    然而,in progress特性稳定性较差,需要具体的特性参数来开启。

    Node的文档建议通过grep "in progress"来查询当前可用的 in progress特性:

    node --v8-options | grep "in progress"
    
    • 1

    在不同的 Node版本中执行这条命令后得到的结果也是不同的。Node自己也有个版本计划,定义了它要提供哪些API。

    1.2.3 了解Node 的发布计划

    Node的发行版分为长期支持版(LTS)、当前版和每日构建版三组。

    LTS版有18个月的支持服务﹐期满后还有12个月的维护性支持服务。版本号是按照语义版本(SemVer )编制的。SemVer给每个版本定义了一个主要、次要和补丁版本号。比如6.9.1的主要版本号是6,次要版本号是9,补丁版本号是1。

    只要看到主版本号发生变化,那就意味着有些API可能不兼容了,也就是说如果要用这个版本的Node,那么你的项目需要重新测试一下。

    另外,按Node的发布规则,主版本号增长意味着新的当前版也已经切下来了。每日构建版的构建是自动进行的,每隔.24小时一次,包含这24小时内的最新修改,但一般只用来测试Node的最新特性。

    用哪个版本取决于你的项目和组织。有些人可能喜欢更新不那么频繁的LTS,对于那些难以管理频繁更新的大公司来说,这个版本可能更好。但如果你想跟上性能和功能的改进,当前版更合适。

  • 相关阅读:
    python字典、列表排序,从简单到复杂
    Java堆(Java Heap)
    人大金仓分析型数据库JSON索引
    DVWA之SQL注入
    计算机视觉CV-目标检测OB
    golang读取键盘功能按键输入
    EMR 集群时钟同步问题及解决方案An error occurred (InvalidSignatureException)
    Dropout在Python中的应用及源代码解析
    【脑与认知科学】【n-back游戏】
    2019架构真题&2020案例(四十七)
  • 原文地址:https://blog.csdn.net/weixin_44226181/article/details/127700854