class可以看做就是一個語法糖,完全可以理解成es5中構造函數的另一種寫法。
每個class都會有一個constructor函數,不寫的話,js默認會加上一個空的constructor函數。
class與es5構造函數的區別
1.class內部是嚴格模式,其實es6推崇的都是嚴格模式,什麼是嚴格模式呢,大致理解就是寫法更加的規範,
eg: 不能使用未聲明的變量,不能使用關鍵字和保留字,不允許對只讀屬性賦值,等等。。。
// es5中
x=5
console.log(x) //5
function Per () {
"use strict"
y = 3.14 //報錯
}
2. 變量提升
es5中function 和var都會進行提升, es6中class不會進行提升
new Foo(); //報錯
class Foo {}
3.this指向
es5中誰調用該方法,改方法的this指向誰
es6中class中如果含有this,其默認指向類的實例
4.靜態方法寫法區別
es5中靜態方法和靜態屬性
function A(){
a = 1
}
A.sayMeS=function(){
console.log("Hello World S!");
}
es6中靜態方法和靜態屬性
class B {
static sayMes = function () {
console.log('456')
}
}
B.Foo = 'foo'
class中屬性和方法不可枚舉
class Point {
constructor(x, y) {
// ...
}
toString() {}
}
Object.keys(Point.prototype, 'Point')
console.log(Object.keys(Point.prototype),'Point') // []
function Pe () {
}
Pe.prototype.toString = function() {
}
console.log(Object.keys(Pe.prototype), 'Pe') // ["toString"]
繼承
es5中實現繼承就是修改原型鏈
es6中class利用extends關鍵字實現繼承,class中實現繼承要調用super方法,super方法只能在constructor中調用,在其他地方調用會報錯,在子類class中super相當於父類的構造函數,調用super相當於調用父類的constructor函數。所以調用super方法後才能實現繼承,這種繼承相當於把父類copy了一份給子類。
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
static haha () {
console.log('haha')
}
}
class ColorPoint extends Point {
constructor(x, y, color) {
this.color = color; // 報錯,constructor中使用this要在super調用之後,因爲子類不存在this,要super調用後繼承父類子類纔會存在this
super(x, y);
console.log(this.x, y)
this.color = color; // 正確
}
sayHello () {
this.sayword ()
}
sayword () {
console.log('hello,word', this.x)
}
}
var b = new ColorPoint('x', 'y')
b.sayHello()
b.haha() //報錯,haha是靜態方法,實例中無法訪問
ColorPoint.haha() // 打印haha,ColorPoint繼承父類,相當於copy一份父類,所以ColorPoint中存在靜態方法haha
class中super用兩種使用形式,第一種是當函數使用,代表父類的構造函數 ,第二種是當做對象使用,super
作爲對象時,在普通方法中,指向父類的原型對象(partent.prototype);在靜態方法中,指向父類(partent)。
class A {
constructor() {
this.p = 2;
}
}
class B extends A {
get m() {
return super.p;
}
}
let b = new B();
b.m //undefined
// super在普通方法中指向父類原型,而父類A中的p在實例上,不是在原型中,所以子類B中super.p (相當於A.prototype.p)打印出undefined