在指南中,我将尝试解析以面向对象规范聚焦的es6的新特性。javascript
首先,java
范例是某个事务的例子或模型,在某种状况下,按照一种模式建立了计算机程序。es6
显然你意识到这是一种设计模式,像已经存在的这个模式,咱们还有许多其它的设计模式,好比函数式编程和反应式编程。编程
咱们在这个模式中所作的是以更接近实际的方式编程,咱们使用类,对象,方法,属性等进行编程,而且集成了抽象,封装,模块化,隐私,多态和继承等术语。设计模式
javascript的问题是,它不是一个很规范的语言,为何?由于javascript全部的都是对象,所以咱们可使用很著名的
prototype
来解决这个问题。模块化
在ES5中,咱们使用下面的例子实现工程模式:函数式编程
console.log('*** PERSON ***'); function Person (name) { this.name = name; } // 明确属性和方法 Person.prototype = { eyes: 2, mouth: 1, sleep: function () { return 'zzz'; } }; // 建立一个叫Nick的人 const p1 = new Person('Nick'); console.log( `name: ${p1.name}`, `eyes: ${p1.eyes}`, `mouth: ${p1.mouth}`, p1.sleep() ); console.log('*** EMPLOYEE ***') // 若是咱们有class属性,咱们能够继承person的属性 function Employee (name, salary) { this.name = name; this.salary = salary; } // Prototype 继承 Employee.prototype = Object.create(Person.prototype); Employee.prototype.constructor = Employee; // Set his own constructor // 如今能够作相同的事情了 // 建立一个employee const em1 = new Employee('John', 3000); console.log( `name: ${em1.name}`, `salary: ${em1.salary} USD`, `eyes: ${em1.eyes}`, `mouth: ${em1.mouth}`, em1.sleep() );
如今使用ES6,用一种简单的方式实现上面的操做,可是必定记住这仅仅是语法糖:函数
class Person { constructor (name) { this.name = name; this.eyes = 2; this.mouth = 1; } sleep () { return 'zzz'; } } class Employee extends Person { constructor (name, salary) { super(name); this.salary = salary; } } const p1 = new Person('Nick'); console.log( `name: ${p1.name}`, `eyes: ${p1.eyes}`, `mouth: ${p1.mouth}`, p1.sleep() ); const em1 = new Employee('John', 3000); console.log( `name: ${em1.name}`, `salary: ${em1.salary} USD`, `eyes: ${em1.eyes}`, `mouth: ${em1.mouth}`, em1.sleep() );
在这种状况下,经过extends
关键字咱们只需说:好吧,我想要继承Person
类的属性。但在背后,这与咱们在使用es5示例中的原型所作的相同。oop
class Dog { static whatIs() { return 'A dog is a beatiful animal'; } } // 所以,咱们经过静态方法,不用实例化一个新的对象就能够访问方法 console.log( Dog.whatIs() );
javascript并不像java和C#那样拥有私有属性。重要的是,在JavaScript中咱们有一个用于“私有”值的约定,该约定是在该单词以前使用下划线:this
class Person { constructor (name, phone) { this.name = name; this._phone = phone; } } const p1 = new Person('John', 544342212); // 实际上 'phone' 不是一个私有属性,由于咱们能够这样使用: console.log(p1._phone);
不过在ES6中,咱们有一个叫WeakMap的对象,它容许咱们建立私有属性。让咱们来看下:
// 由于它是保留字,因此不要使用private做为变量名称 const secret = new WeakMap(); class Person { constructor (name, phone) { this.name = name; secret.set(this, {_phonenumber: phone}); } } const p1 = new Person('John', 544342212); // 如今_phonenumber是一个私有属性 console.log(p1. _phonenumber); // Print's undefined
当咱们拥有私有方法时一般会建立一个返回私有值的公共方法,所以咱们必须返回一个值,并定义一个新的值。
const secret = new WeakMap(); class Person { constructor (name, phone) { this.name = name; secret.set(this, {_phonenumber: phone } get phoneNumber() { return secret.get(this)._phonenumber; } set phoneNumber(newNumber) { secret.get(this)._phonenumber = newNumber; } } const p1 = new Person('John', 544342212); const p2 = new Person('Tom', 111111); // 经过getter获取手机号 console.log(p1.phoneNumber); // Print's the number // 设置新的手机号 p1.phoneNumber = 432232323; p1.phoneNumber = 222222; console.log(p1.phoneNumber, p2.phoneNumber); // 得到新的手机号
在执行过程当中,一个对象引用它的类的事件或者任何子类的事件。子类可能会从新定义一种方法。
class Person { constructor(name) { this.name = name; } me() { return `My name is ${this.name}`; } } const axel = new Person('Axel'); console.log(axel.me()); // -> 'My name is Axel' class Employee extends Person { constructor (name, salary) { super(name); this.salary = salary; } me() { return `My name is ${this.name} and my salary is ${this.salary}`; } } const nick = new Employee('Nick', 3000); console.log(nick.me()); // -> 'My name is Nick and my salary is 3000'