ES6學習筆記(七)【class】
class
關鍵字是小寫,大括號中的方法不用逗號分隔。
ES5與ES6實現類的區別
ES5函式實現建構函式
function Student(name) {
this.name = name;
}
Student.prototype.hello = function () {
console.log(('Hello, ' + this.name + '!'));
}
var xiaoming = new Student('小明');
xiaoming.hello();
console.log(xiaoming);
ES6 class
關鍵字實現建構函式
class Student {
constructor(name) { //建構函式
this.name = name;
}
hello() { //原型物件上的函式
console.log(('Hello, ' + this.name + '!'));
}
}
var xiaoming = new Student('小明');
xiaoming.hello();
console.log(xiaoming);
class
表示式
下邊這個類的名字是MyClass
,不是Me
,Me
只在Class
內部代表當前類。
const MyClass = class Me {
getClassName() {
return Me.name;
}
}
let inst = new MyClass();
inst.getClassName() // Me
Me.name // ReferenceError: Me is not defined
類內部沒有用到Me
的話可以省略掉:
const MyClass = class {
//...
};
如果不需要多次構造,可以寫成立即執行的class
:
//沒有類名,只有一個例項
let person = new class {
constructor(name) {
this.name = name;
}
sayName() {
console.log(this.name);
}
}('張三');
person.sayName();
不存在變數提升
類class
不存在變數提升,必須先定義後使用,是因為繼承的存在,防止出現繼承時類未定義。
class
的私有屬性和私有方法
class
的Generator
方法
如果某個方法之前加上星號(*
),就表示該方法是一個 Generator
函式。
下面這個例子是定義一個遍歷器介面:
class Foo {
constructor(...args) {
this.args = args;
}
* [Symbol.iterator]() {
for (let arg of this.args) {
yield arg;
}
}
}
for (let x of new Foo('hello', 'world')) {
console.log(x);
}
// hello
// world
Class的靜態方法
表示是類的屬性,不是例項的屬性:
class Foo {
static classMethod() {
return 'hello';
}
}
Foo.classMethod() // 'hello'
var foo = new Foo();
foo.classMethod() //例項訪問不到
// TypeError: foo.classMethod is not a function
靜態方法中的this
指的是這個類而不是例項。
靜態方法可以被子類繼承,也可以在子類中通過super
物件呼叫。
class Foo {
static classMethod() {
return 'hello';
}
}
class Bar extends Foo {
}
Bar.classMethod() // 'hello'
//或者像下邊這樣
class Foo {
static classMethod() {
return 'hello';
}
}
class Bar extends Foo {
static classMethod() {
return super.classMethod() + ', too';
}
}
Bar.classMethod() // "hello, too"
class
的靜態屬性和例項屬性
new.target
屬性
可以判斷類是通過new
呼叫還是通過繼承呼叫。
需要注意的是,子類繼承父類時,new.target
會返回子類。
不是通過new
呼叫的話返回undefined
。
class A {
constructor() {
console.log(new.target);
}
}
new A(); //返回A的引用
class B extends A {
}
new B(); //返回B的引用
class
繼承
子類必須在constructor
方法中呼叫super
方法,否則新建例項時會報錯。這是因為子類沒有自己的this
物件,而是繼承父類的this
物件,然後對其進行加工。如果不呼叫super
方法,子類就得不到this
物件。
正因為如此,在子類的建構函式中,只有呼叫super
之後,才可以使用this
關鍵字,否則會報錯。
class PrimaryStudent extends Student { //用extends實現繼承
constructor(name, grade) {
super(name); // 記得用super呼叫父類的構造方法!
this.grade = grade;
}
myGrade() {
console.log('I am at grade ' + this.grade);
}
}
var xiaoming = new PrimaryStudent("小明", "三年級");
xiaoming.myGrade();
console.log(xiaoming);
super
關鍵字
super
這個關鍵字,既可以當作函式使用,也可以當作物件使用。使用super
的時候,必須顯式指定是作為函式、還是作為物件使用,否則會報錯。
作為函式時,super()
只能用在子類的建構函式之中,代表父類的建構函式,用在其他地方就會報錯。
super
作為物件時,在普通方法中,指向父類的原型物件;在靜態方法中,指向父類。
作為父類建構函式
子類建構函式必須呼叫父類建構函式後才能使用this
。
作為父類原型物件
super
指向父類的原型物件,所以定義在父類例項上的方法或屬性,是無法通過super
呼叫的。
class A {
constructor() {
this.a = 1;
}
p() {
return 2;
}
}
class B extends A {
constructor() {
super();
console.log(super.p); // 2
console.log(super.a); // undefined
}
}
let b = new B();
super 與 this
通過super
呼叫父類的方法時,方法內部的this
指向子類。
就是說通過super
呼叫父類原型屬性的方法,方法中如果有使用this
,它是指向子類例項的。
class A {
constructor() {
this.x = 1;
}
print() {
console.log(this.x);
}
}
class B extends A {
constructor() {
super();
this.x = 2;
}
m() {
super.print();
}
}
let b = new B();
b.m() // 2
上邊通過super
呼叫的方法返回了子類例項的屬性。
類似的,如果使用super
對某個屬性賦值,則會賦值到子類例項的屬性上。因為寫屬性的時候相當於this.PropertyName = ""
。
class A {
constructor() {
this.x = 1;
}
}
class B extends A {
constructor() {
super();
this.x = 2;
super.x = 3;
//super指向父類原型物件,x屬性不存在
console.log(super.x); // undefined
console.log(this.x); // 3
}
}
let b = new B();
作為父類
super
作為物件,用在靜態方法之中,這時super
將指向父類,而不是父類的原型物件。
類的原型鏈
Class
作為建構函式的語法糖,同時有prototype
屬性和__proto__
屬性,因此同時存在兩條繼承鏈。
- 一條是自己作為物件對類的靜態屬性的繼承,指向父類。
- 另一條是子類的原型物件,對方法的繼承,指向父類的
prototype
屬性。
class A {
}
class B extends A {
}
B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true
extends的繼承目標
只要是一個有prototype
屬性的函式,就能被繼承。由於函式都有prototype
屬性,所以任意函式都能被繼承。
繼承原生建構函式
Mixin 模式實現
多繼承
相關文章
- ES6學習筆記(八)【class】筆記
- ES6學習筆記(九)【class】筆記
- ES6 學習筆記筆記
- ES6 學習筆記筆記
- es6學習筆記筆記
- 深入學習 es6 class
- ES6 學習筆記四筆記
- ES6 學習筆記一筆記
- ES6 學習筆記二筆記
- ES6 學習筆記三筆記
- ES6的學習筆記筆記
- HexMap學習筆記(七)——道路筆記
- Redis阻塞(學習筆記七)Redis筆記
- andeoid學習筆記七筆記
- Spss 學習筆記(七)SPSS筆記
- TypeScript學習筆記之五類(Class)TypeScript筆記
- ES6學習筆記--es6簡介筆記
- Object C學習筆記18-SEL,@ selector,Class,@classObject筆記
- ES6學習筆記之Function筆記Function
- 前端學習筆記之ES6~~~前端筆記
- webpack學習筆記七:配置babelWeb筆記Babel
- angular學習筆記(七)-迭代1Angular筆記
- angular學習筆記(七)-迭代2Angular筆記
- angular學習筆記(七)-迭代3Angular筆記
- C++/C學習筆記(七)C++筆記
- Java學習筆記——陣列練習(七)Java筆記陣列
- ES6學習筆記(六)【promise,Generator】筆記Promise
- ES6學習筆記3---Symbol筆記Symbol
- Redis學習筆記(七) 資料庫Redis筆記資料庫
- Laravel學習筆記七-建立部落格Laravel筆記
- Activiti 學習筆記七:連線(SequenceFlow)筆記
- OS學習筆記七:IO系統筆記
- 工作學習筆記(七)Java的介面筆記Java
- JVM學習筆記——Class類檔案解讀JVM筆記
- ES6學習筆記(一)【變數,字串】筆記變數字串
- ES6學習筆記(三)【函式,物件】筆記函式物件
- ES6學習筆記(四)【正則,集合】筆記
- ES6語法學習筆記之promise筆記Promise