You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
class Person {
constructor (name) {
this.name = name;
return 1;
}
}
let zhang = new Person('zhang');
console.log(zhang instanceof Person) // true
因为返回的不是对象,所以还是返回实例对象。
let obj = {};
class Person {
constructor (name) {
this.name = name;
return obj;
}
}
let zhang = new Person('zhang');
console.log(zhang instanceof Person) // false
console.log(zhang === obj); // true
constructor 方法返回的是对象,所以 new Person 对象就是返回对象 obj。
Class 表达式
Class 表达式和函数表达式相似。
let ClassExpression = class Person {
getClassName () {
return Person.name;
}
};
let res = new ClassExpression();
console.log(res.getClassName()); // "Person"
和函数表达式一样,Person 只能在类内部使用。
Class 表达式还是有匿名形式。
let ClassExpression = class {
constructor (name) {
this.name = name;
}
};
let res = new ClassExpression('li');
console.log(res.name); // "li"
Class 方法
Class 方法是不可枚举的。
class Person {
constructor (name, age) {
this.name = name;
this.age = age;
}
getName () {
return this.name;
}
getAge () {
return this.age;
}
}
for (let key in Person.prototype) {
console.log(key); // 没值
}
可以通过 Object.assign一次性向类的 prototype 添加多个方法。
class Person {
constructor (name, age) {
this.name = name;
this.age = age;
}
}
Object.assign(Person.prototype, {
getName: function () {
return this.name;
},
getAge: function () {
return this.age;
}
});
let zhang = new Person('zhang', 25);
console.log(zhang.getName()); // "zhang"
console.log(zhang.getAge()); // 25
静态方法和静态属性
类的静态方法时在方法前加上 static。
class Person {
constructor (name) {
this.name = name;
}
getName () {
return this.name;
}
static classMethod () {
return 10;
}
}
let zhang = new Person('zhang');
console.log(Person.classMethod()); // 10
console.log(zhang.classMethod()); // TypeError: zhang.classMethod is not a function
class Person {
get height() {
console.log('175cm');
}
set height(value) {
console.log(`The height is ${value}cm`);
}
}
let zhang = new Person();
zhang.height; // "175cm"
zhang.height = 185; // "The height is 185cm"
如果有继承关系,子类必须在 constructor 调用 super 函数,此时 super 代表父类的构造函数。在调用 super 函数之后才能使用 this 关键字。
super 作为对象使用时,指向父类的原型对象
class Person {
getResult() {
return 1;
}
}
class Athletes extends Person {
constructor() {
super();
console.log(super.getResult());
}
}
let zhang = new Athletes(); // 1
new.target
如果是 new 调用构造函数,那么 new.target 指向构造函数
function Foo(name) {
if (new.target === Foo) {
this.name = name;
} else {
throw new Error('必须使用 new 调用');
}
}
在 Class 中,new.target 指向当前 Class
class Person {
constructor(name) {
console.log(new.target === Person);
this.name = name;
}
}
let zhang = new Person('zhang'); // true
但是在继承时,会返回子类
class Person {
constructor(name) {
console.log(new.target === Person);
console.log(new.target === Athletes);
this.name = name;
}
}
class Athletes extends Person {
constructor() {
super('zhang');
}
}
let zhang = new Athletes('zhang');
// false
// true
所以根据这个特性,写出不能实例化的 Class
class Person {
constructor(name) {
if (new.target === Person) {
throw new Error('Person 不能被实例');
}
}
}
let zhang = new Person('zhang'); // Error: Person 不能被实例
Class
介绍过原型,在 ES6 中为了规范,提出了 Class ,不过还是利用的原型的机制。
Class 基本语法
ES6 提供的 Class 更像传统语言的写法
我们使用 prototype 也能实现
实际上 Class 利用的还是 prototype 机制:constructor 就是构造函数,类的方法定义在类的 prototype 对象上面。如果我们修改了 prototype 对象,Class 实例也会改变。
但是 Class 的 prototype 对象是不可修改的(不可变绑定)。
constructor
constructor 是类的默认方法,也是原型继承的构造函数。类必须有 constructor 方法,如果没有显示定义,会被默认添加一个空的 constructor。
constructor 默认返回实例对象(this),但是也可以返回另外对象,这个特性和构造函数一样。
因为返回的不是对象,所以还是返回实例对象。
constructor 方法返回的是对象,所以 new Person 对象就是返回对象 obj。
Class 表达式
Class 表达式和函数表达式相似。
和函数表达式一样,Person 只能在类内部使用。
Class 表达式还是有匿名形式。
Class 方法
Class 方法是不可枚举的。
可以通过 Object.assign一次性向类的 prototype 添加多个方法。
静态方法和静态属性
类的静态方法时在方法前加上 static。
静态方法只能类自身访问,实例对象不能访问。
ES6 规定类中只有静态方法,没有静态属性。可以通过 Person.staticPro 这样添加。在 ES7 中有静态属性的提案:直接写在类中的属性就是静态属性。
getter 和 setter 方法
在类中也有 getter 和 setter 方法。
Class 继承
Class 继承是通过关键字 extends 完成的。
需要注意的是 super。super 可以当函数使用,也可以作为对象使用。
如果有继承关系,子类必须在 constructor 调用 super 函数,此时 super 代表父类的构造函数。在调用 super 函数之后才能使用 this 关键字。
super 作为对象使用时,指向父类的原型对象
new.target
如果是 new 调用构造函数,那么 new.target 指向构造函数
在 Class 中,new.target 指向当前 Class
但是在继承时,会返回子类
所以根据这个特性,写出不能实例化的 Class
参考资料
MDN 类
new.target
super
ES6 class
The text was updated successfully, but these errors were encountered: