Node.js笔记七:es6

Node.js笔记七:es6

es6是javascript的新一代语法规范,现在很多新的库都是基于新的es6语法规范编写。得益于类结构,方便了大型项目的编写。在webpack,babel等工具的帮助下,es6离我们并不遥远。说到es6不得不说es5,也想说说es7。

网上es6的教程很多,这里推荐的是阮一峰老师的ECMAScript 6 入门。

es5

我相信很多的前端工程师嘴上说的Javascript都是es5,因为es5可以直接在大部分浏览器当中运行,兼容性问题较少。由于es5当中所有数据类型都是对象,并不存在类的概念,只有原型。所有的原型链都指向Object。

这时,面试官问你,用原始es5写一个class类名为person,它具有公有属性name,和私有属性age,公有函数setAge()设置私有变量age,公有函数getAge()获取变量age。

function Person(props){
  if(props){
    this.name = props.name||"brandon";
    var age = props.age||26;
  }else{
    this.name = "brandon";
    var age = 26;
  }

  this.setAge = function(_age){
    age = _age;
  }
  this.getAge = function(){
    return age;
  }
}

其中,this指向的是自己的prototype。在进行new操作以后,该对象的属性可以被外部读取,便像是公有变量。而var定义的变量不能被外部读取,可以看作私有变量。

这里补充一点,new的过程其实并不是类的实例化。而是构造函数执行的过程,将this的属性赋予新的对象。

面试官再问你,写一个class类名为teacher继承于person,具有私有属性studentCount公有方法setStudentCount()设置私有变量studentCount,公有函数getStudentCount()获取变量studentCount。没有类怎么办?

function Teacher(props){
  Person.call(this, props);
  if(props){
    var studentCount = props.studentCount||55;
  }else{
    var studentCount = 55;
  }

  this.setStudentCount = function(_count){
    studentCount = _count;
  }
  this.getStudentCount = function(){
    return studentCount;
  }
}

这不过是个构造函数。原型链并没有建立。步骤如下:需要创建一个新的函数,原型指向父类。子类原型是它的实例。详细参考:原型继承-廖雪峰Javascript官网。源码参考。其实,es5面向对象的方法还有很多,想了解各自优劣,参看Javascript面向对象编程(二):构造函数的继承。

function inherits(Child,Parent){
  var F = function(){};
  F.prototype =Parent.prototype;
  Child.prototype = new F();
  Child.prototype.constructor = Child;
}

inherits(Teacher, Person);

这时候,面试官再问你,es5怎么实现多继承。

function Man(){
    var sex = 'male'

    this.setSex = function(_sex){
        sex = _sex
    }

    this.getSex = function(){
        return sex
    }
}

function Student(){
    Person.call(this)
    Man.call(this)
}

for(var i in Person.prototype){
    Student.prototype[i] = Person.prototype[i]
}
for(var i in Man.prototype){
    Student.prototype[i] = Man.prototype[i]
}

由于空方法继承法在多继承的情况下会出现被覆盖的情况。最终只能使用复制法。该方法将父类的prototype复制给子类,出现名字重复的话,直接被覆盖。

es6

如果你困扰于es5的面向对象,变量提升,函数提升和作用域的问题,那么es6则是你的救星。es6也就是es2015。它给你一个完整的编程语言。

数据类型

var是es5变量声明的一个标志。它出现的时候你要小心,因为变量提升。它没出现的时候,你更加需要小心,它有可能改变了上一层作用域的值。

es5只有全局作用域和函数作用域,没有块级作用域。
--30分钟掌握ES6/ES2015核心内容

es6的letconst则没有这个问题,他俩给你的是类似其他语言般正常的体验,使用的是块级作用域。

let是变量声明,并不会出现变量提升,而且可以在for循环中放心使用。const则为常量声明,已经定义不能可以被改变,很好地避免了变量的重复声明。

面向对象

es6提供完整的class和继承,但是很可惜的是并不具备私有变量。如下的定义_age并非正在的私有变量。_age还是可以被外界访问。上方的面向对象代码可以被重构。

class Person {
    constructor(){
        this.name = 'brandon'
        this._age = 26;
    }

    setAge(_a){
        this._age = _a;
    }

    getAge(){
        return this._age;
    }
}

继承用extends,super则是执行父类的构造函数。

class Teacher extends Person {
    constructor(){
        super()
        this._studentCount = 55
    }

    setStudentCount(_b){
        this._studentCount = _b
    }

    getStudentCount(){
        return this._studentCount
    }
}

如果真的需要私有变量,可以考虑用weakMap。详情参考如何在 ES6 中管理类的私有数据。这里不做详细说明。

箭头函数

箭头函数内部没有constructor方法,也没有prototype,所以不支持new操作。但是它对this的处理与一般的普通函数不一样。箭头函数的 this 始终指向函数定义时的 this,而非执行时。使用前要搞清楚this的指向。

其他特征

解构,默认参数和字符串格式化都非常实用,参考ECMAScript 6 入门。

es7

正因为es6还是有缺点,所以才要有进步。

展望es7,es7在es6的基础上,它增加了一些新的语言特性。可以说,es7是es2016发展的过程中,有好几个stage。

语法特性包括:

  • 指数运算符
  • SIMD.JS – SIMD APIs + polyfill
  • 异步函数
  • Object.values/Object.entries
  • 字符串填充
  • 函数参数列表与调用中的尾逗号

由于es7还在发展的过程中,很多“语法糖”特性并未稳定。暂时不推荐用于生产当中。题外话,著名的koa是基于es6开发的,而koa2结合es7的await和async的属性实现异步函数。

扩展阅读

【译】ECMAScript 2016 (ES7) 新特性一览

欢迎关注我的微信公众号:brandonxiang

Node.js笔记七:es6_第1张图片
微信公众号

你可能感兴趣的:(Node.js笔记七:es6)