首頁 > web前端 > 前端問答 > es6 class是函數嗎

es6 class是函數嗎

青灯夜游
發布: 2022-04-11 14:37:31
原創
1438 人瀏覽過

es6 class是函數。在es6中,class(類別)作為物件的模板被引入,可以透過class關鍵字定義類,語法為「class 類別名稱{...};class的本質就是function(函數),它是一個語法糖,其底層是透過「建構函數」去創建的。

es6 class是函數嗎

本教學操作環境:windows7系統、ECMAScript 6版、Dell G3電腦。

es6 class是函數。

在ES6中,class (類別)作為物件的模板被引入,可以透過class 關鍵字定義類別。

class 的本質是function。

它可以看作一個語法糖,其底層還是透過 建構函數 去創造的,讓物件原型的寫法更加清晰、更像物件導向程式設計的語法。

function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.sayName = function() {
    return this.name;
}

const xiaoming = new Person('小明', 18);
console.log(xiaoming);
登入後複製

上面程式碼用ES6的class實現,就是下面這樣

class Person {
    constructor(name, age) {
      this.name = name;
      this.age = age;
    }
  
    sayName() {
      return this.name;
    }
}
const xiaoming = new Person('小明', 18)
console.log(xiaoming);
// { name: '小明', age: 18 }

console.log((typeof Person));
// function
console.log(Person === Person.prototype.constructor);
// true
登入後複製

constructor方法,這就是建構方法,this關鍵字代表實例物件。類別的資料型別就是函數,類別本身就指向建構子。

定義類別的時候,前面不需要加function, 而且方法之間不需要逗號分隔,加了會報錯。

類別的所有方法都定義在類別的prototype屬性上面。

class A {
    constructor() {}
    toString() {}
    toValue() {}
}
// 等同于
function A () {
    // constructor
};
A.prototype.toString = function() {};
A.prototype.toValue = function() {};
登入後複製

在類別的實例上面呼叫方法,其實就是呼叫原型上的方法。

let a = new A();
a.constructor === A.prototype.constructor // true
登入後複製

類別的實例

實例的屬性除非明確定義在本身(即定義在this物件上),否則都是定義在原型上(即定義在class上) 。

注意:

1、class不存在變數提升

new A(); // ReferenceError
class A {}
登入後複製

因為ES6 不會把類別的宣告提升到程式碼頭部。這種規定的原因與繼承有關,必須保證子類別在父類別之後定義。

{
  let A = class {};
  class B extends A {}
}
登入後複製

上面的程式碼不會報錯,因為B繼承A的時候,A已經有了定義。但是,如果存在class提升,上面程式碼就會報錯,因為class 會被提升到程式碼頭部,而let指令是不提升的,所以導致B 繼承A 的時候,Foo還沒定義。

2、this的指向類別的方法內部如果含有this,它預設指向類別的實例。但是,必須非常小心,一旦單獨使用該方法,很可能報錯。

繼承

Class 可以透過extends關鍵字實作繼承

class Animal {}
class Cat extends Animal { };
登入後複製

上面程式碼中定義了一個Cat 類,該類別透過 extends關鍵字,繼承了Animal 類別中所有的屬性和方法。但是由於沒有部署任何程式碼,所以這兩個類別完全一樣,等於複製了一個Animal類別。下面,我們在Cat內部加上程式碼。

class Cat extends Animal {
    constructor(name, age, color) {
        // 调用父类的constructor(name, age)
        super(name, age);
        this.color = color;
    }
    toString() {
        return this.color + ' ' + super.toString(); // 调用父类的toString()
    }
}
登入後複製

constructor方法和toString方法之中,都出現了super關鍵字,它在這裡表示父類別的建構函數,用來新建父類別的this物件。

子類別必須在 constructor 方法中呼叫 super 方法,否則新實例就會報錯。 這是因為子類別自己的this對象,必須先透過 父類別的建構子完成塑造,得到與父類別相同的實例屬性和方法,然後再加工,加上子類別自己的實例屬性和方法。如果不呼叫super方法,子類別就得不到this物件。

class Animal { /* ... */ }

class Cat extends Animal {
  constructor() {
  }
}

let cp = new Cat();
// ReferenceError
登入後複製

Cat 繼承了父類別 Animal,但是它的建構子沒有呼叫super方法,導致新實例報錯。

如果子類別沒有定義constructor方法,這個方法會被預設添加,程式碼如下。也就是說,不管有沒有明確定義,任何一個子類別都有constructor方法。

class Cat extends Animal {

}
// 等同于

class Cat extends Animal {
    constructor(...args) {
        super(...args);
    }
}
登入後複製

另一個需要注意的地方是,es5 的建構子在呼叫父建構子前可以存取 this, 但 es6 的建構子在呼叫父建構子(即 super)前不能存取 this。

class A {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
}

class B extends A {
  constructor(x, y, name) {
    this.name = name; // ReferenceError
    super(x, y);
    this.name = name; // 正确
  }
}
登入後複製

上面程式碼中,子類別的constructor方法沒有呼叫super之前,就使用this關鍵字,結果報錯,而放在super方法之後就是正確的。

父類別的靜態方法,也會被子類別繼承。

class A {
  static hello() {
    console.log('hello world');
  }
}

class B extends A {
}

B.hello()  // hello world
登入後複製

【相關推薦:javascript影片教學web前端

以上是es6 class是函數嗎的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板