//1. class声明会提升,但不会初始化赋值,类似与let、const进入暂时性死区
const bar = new Bar(); //it's ok
function Bar() {
this.bar = 42;
}
const foo = new Foo(); //ReferenceError: Cannot access 'Foo' before initialization
class Foo {
constructor() {
this.foo = 42;
}
}
//2. class 声明内部会启用严格模式
function Bar() {
baz = 42;
}
const bar = new Bar(); //it's ok
class Foo {
constructor() {
fol = 42;
}
}
const foo = new Foo(); //ReferenceError: fol is not defined
//3. class的所有方法(静态方法和实例方法)都是不可枚举的
function Bar() {
this.bar = 42;
}
Bar.answer = function () {
return 42;
};
Bar.prototype.print = function () {
console.log(this.bar);
};
const barKeys = Object.keys(Bar);
console.log(barKeys); //[ 'answer' ]
const barProtoKeys = Object.keys(Bar.prototype);
console.log(barProtoKeys); //[ 'print' ]
class Foo {
constructor() {
this.foo = 42;
}
static answer() {
return 42;
}
print() {
console.log(this.foo);
}
}
const fooKeys = Object.keys(Foo);
console.log(fooKeys); //[]
const fooProtoKeys = Object.keys(Foo.prototype);
console.log(fooProtoKeys); //[]
//4. class的所有方法(静态方法和实例方法)都没有原型对象prototype,也没有[[constructor]],不能使用new来调用
function Bar() {
this.bar = 42;
}
Bar.prototype.print = function () {
console.log(this.bar);
};
const bar = new Bar();
const barPrint = new bar.print(); //it's ok
class Foo {
constructor() {
this.foo = 42;
}
print() {
console.log(this.foo);
}
}
const foo = new Foo();
const fooPrint = new foo.print(); //TypeError: foo.print is not a constructor
//5. 必须使用new调用class
function Bar() {
this.bar = 42;
}
const bar = Bar(); //it's ok
class Foo {
constructor() {
this.foo = 42;
}
}
const foo = Foo(); //TypeError: Class constructor Foo cannot be invoked without 'new'
//6. class内部无法重写类名
function Bar() {
Bar = "Baz";
this.bar = 42;
}
const bar = new Bar(); //Bar = 'baz' bar = {bar:42}
class Foo {
constructor() {
this.foo = 42;
Foo = "Fol";
}
}
const foo = new Foo(); //TypeError: Assignment to constant variable.
//7. class子类可以通过__proto__寻到父类
class Super {}
class Sub extends Super {}
const sub = new Sub();
Sub.__proto__ === Super; //true
function Super() {}
function Sub() {}
Sub.prototype = new Super();
Sub.prototype.constructor = Sub;
let sub = new Sub();
Sub.__proto__ === Function.prototype; //true
/*
8. this生成的顺序不同。
es5的继承先生成子类实例,再调用父类的构造函数修饰子类实例。
es6的继承先生成父类实例,再调用子类的构造函数修饰父类实例。
所以es6可以继承内置对象
*/
function MyEs5Array() {
Array.call(this, arguments);
}
const arrayEs5 = new MyEs5Array(); //先创建子类实例{} 所以arrayEs5为{}
class MyEs6Array extends Array {}
const arrayEs6 = new MyEs6Array(); //先创建父类实例[] 所以为arrayEs6
网友评论