在指南中,我將嘗試解析以面向對象規範聚焦的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'