首先我们来了解一下类定义
类
类是用来描述现实事物的,由属性和行为组成。可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该类事物。
constructor
一个类只能有一个constructor方法
在function定义的构造函数中,其prototype.constructor属性指向构造器自身
在class定义的类中,constructor其实也相当于定义在prototype属性上
class Pon{
constructor(a) {
// ...这了可以定义实例属性
this.a = a;
}
int(){ }
}
// 等同于
function Pon(){
this.a = a;
}
Pon.prototype.int= function (){ }
ES6 class与ES5 构造函数区别
声明区别
ES6 中的 class 是不可以重复定义的重复定义是会报错的
ES5中的function 声明构造函数会却覆盖之前定义的方法
class没有变量提升是没有变量提升的
function 声明构造函数会却变量提升(js预编译)
枚举区别
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
int() {
console.log(x,y)
}
}
Object.keys(Point.prototype)
Object.getOwnPropertyNames(Point.prototype)
function Point1 (x, y) {
this.x = x;
this.y = y;
};
Point1.prototype.int = function() {
console.log(x,y)
};
Object.keys(Point1.prototype)
Object.getOwnPropertyNames(Point1.prototype)
class中定义的方法不可用Object.keys(Point.prototype)枚举到
function构造器原型方法可被Object.keys(Point.prototype)枚举到
但是不管是class还是function,constructor属性默认不可枚举
ES6中的Object.getOwnPropertyNames()可以枚举到每个属性
调用区别
class必须使用new调用,不用new调用会报错。普通构造函数不用new也可以执行。
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
int() {
console.log(x,y)
}
}
const p = new Point()
console.log(p)
const p1 = Point()
console.log(p1)
function Point1(x, y) {
this.x = x;
this.y = y;
};
Point1.prototype.int = function() {
console.log(x,y)
};
const pf = new Point1()
console.log(pf)
const pf1 = Point1()
console.log(pf1)
new.target属性指向当前的构造函数,不能在构造函数外部调用会报错,
function Person(name) {
console.log(new.target);
if (new.target !== undefined) {
this.name = name;
} else {
throw new Error('必须使用new生成实例');
}
}
}
静态属性的区别
静态属性指的是 Class 本身的属性,即Class.propName,而不是定义在实例对象(this)上的属性。
class内部没有静态属性,只能在外面通过类名定义
class Foo {
}
Foo.x= 1;xx
Foo.x // 1
上面的写法为Foo类定义了一个静态属性x
ES6 明确规定,Class 内部只有静态方法,没有静态属性。
calss的关键字static 只能在class中使用 .定义的静态方法前加static关键字。
class Point {
static x = 1;
static y = 2;
static int() {
console.log(this.x)
}
}
class Point {
constructor(){
static x = 1;
static y = 2;
}
static int() {
console.log(this.x)
}
}
继承区别
clas使用 extends 继承,
extends 只能用于类中的定义 不能用与普通的构造函数中
super (ES6 中的要求 :子类的构造函数必须执行一次super函数。)
super有两种用法
1.直接当成函数调用,表示父类的构造
如果定义了constructor 并表示这个是子类,则必须在constructor的第一行手动调用父类的构造函数.
如果说子类不写constructor,则会有默认的构造器,自动去调用父类的构造器
class Animal{
constructor(type,name,age,sex){
this.type = type;
this.name = name;
this.age = age;
this.sex = sex;
}
print(){
console.log(`种类 : ${this.type}`)
console.log(`名字 : ${this.name}`)
console.log(`年龄 : ${this.age}`)
console.log(`性别 : ${this.sex}`)
}
}
class Dog extends Animal{
constructor(name,age,sex){
super("犬类",name,age,sex)
}
}
const d = new Dog("旺财",5,"公");
console.log(d);
d.print();
2.super如果说当成对象使用,则表示父类的原型
super.inti() 这表示调用父类的inti方法
class Dog extends Animal{
print(){ //
super.print();
}
}
const d = new Dog("旺财",5,"公");
console.log(d);
d.print();//和普通构造函数一样父类和自身都拥有相同的属性名优先使用自身的
语言模式区别
类总是使用严格模式的。这意味着类构造中的所有代码都自动处于严格模式