1.class的定義函數
ECMAScript 2015 中引入的 JavaScript 類實質上是 JavaScript 現有的基於原型的繼承的語法糖。類語法不會爲JavaScript引入新的面向對象的繼承模型。this
2.定義類
用class定義類有兩種方法:類表達式和類聲明prototype
1.類聲明code
class Person{ constructor(x,y){ this.x=x; this.y=y; } tostring(){ return this.x+this.y } }
2.類表達式對象
// 匿名類 var Person=class { constructor(x,y){ this.x=x; this.y=y; } tostring(){ return this.x+this.y } } // 命名類 var Person = class Person { constructor(x, y) { this.x = x; this.y = y; } tostring() { return this.x + this.y } }
以上須要說明的點:
1.類聲明/類表達式不會向函數聲明/函數表達式同樣提高。你要訪問一個類,就必須先聲明。
2.ES6類的constructor函數至關於ES5的構造函數。
3.類中定義方法時,前面不用加function,後面不得加 ,。繼承
2、繼承
extends 關鍵字在類聲明或類表達式中用於建立一個類做爲另外一個類的一個子類。ip
//父類 class Animal{ constructor(name,age){ this.name=name; this.age=age; } tostring() { return (this.name + "的年齡是:" + this.age) } } //子類 class Dogs extends Animal { constructor(name,age,code) { super(name, age); // 調用父類的 constructor(name,age) this.code = code; } toString() { return this.color + ' 的' + super.toString(); // 調用父類的 toString() } }
也能夠擴展傳統的基於函數的「類」(構造函數)get
function Animal (name) { this.name = name; } Animal.prototype.speak = function () { console.log(this.name + ' makes a noise.'); } class Dog extends Animal { speak() { super.speak(); console.log(this.name + ' barks.'); } } var d = new Dog('Mitzie'); d.speak();//Mitzie makes a noise. Mitzie barks.
請注意,類不能繼承常規(非可構造)對象。若是要繼承常規對象,能夠改用原型
var Animal = { speak() { console.log(this.name + ' makes a noise.'); } }; class Dog { constructor(name) { this.name = name; } } Object.setPrototypeOf(Dog.prototype, Animal);// If you do not do this you will get a TypeError when you invoke speak var d = new Dog('Mitzie'); d.speak(); // Mitzie makes a noise.
以上須要說明的點:
1.類必須使用new調用,不然會報錯。
2.子類必須在constructor方法中調用super方法, 不然新建實例時會報錯。 這是由於子類沒有本身的this對象, 而是繼承父類的this對象, 而後對其進行加工。 若是不調用super方法, 子類就得不到this對象。string
constructor 是一種用於建立和初始化class建立的對象的特殊方法。若是不指定一個構造函數(constructor)方法, 則使用一個默認的構造函數(constructor)。
class Animal { } // 等同於 class Animal { constructor() {} }
以上須要說明的點:
1.constructor方法默認返回實例對象(即this)。
2.在一個類中只能有一個名爲 「constructor」 的特殊方法。 一個類中出現屢次構造函數 (constructor)方法將會拋出一個 SyntaxError 錯誤。
1.super做爲函數時,指向父類的構造函數。super()只能用在子類的構造函數之中,用在其餘地方就會報錯。
class Animal{ constructor(){ console.log(new.target.name); } } class Dogs extends Animal { constructor() { super(); } } new Animal() // Animal new Dogs() // Dogs
class A { p() { return 2; } } class B extends A { constructor() { super(); console.log(super.p()); // 2 } }super指向父類的原型對象,此時super.p()就至關於A.prototype.p()。
以上須要說明的點:
1.因爲super指向父類的原型對象,因此定義在父類實例上的方法或屬性,是沒法經過super調用的。
Class 做爲構造函數的語法糖, 同時有prototype 屬性和__proto__屬性, 所以同時存在兩條繼承鏈。
1.子類與父類
1.子類的__proto__屬性, 表示構造函數的繼承, 老是指向父類。
2.子類prototype屬性的__proto__屬性, 表示方法的繼承, 老是指向父類的prototype屬性。
class A {} class B extends A {} B.__proto__ === A // true B.prototype.__proto__ === A.prototype // true
2.實例的 proto 屬性
子類實例的 proto 屬性的 proto 屬性, 指向父類實例的 proto 屬性。 也就是說, 子類的原型的原型, 是父類的原型。
class A{} class B extends A{} let a = new A(); let b = new B(); console.log(b.__proto__ === a.__proto__);//false console.log(b.__proto__.__proto__ === a.__proto__);//true