在ES6中,class (类)作为对象的模板被引入,可以通过 class 关键字定义类。
class 的本质是 function,是原型
class与new出来的对象之间只是连接的关系,当本对象没有某个属性或方法时,到原型上找,class就是要找的原型
真正的class类,本质是复制,class有的属性和方法,new出来的对象也有
它可以看作一个语法糖,让对象原型的写法更加清晰、更像面向对象编程的语法
代码:
// es5是这样的:
function Dog(name, age){
this.name = name;
this.age = age;
}
Dog.prototype.bark = function(){
console.log(`我叫${
this.name}`)
}
let lili = new Dog("lili",2);
let sandy = new Dog("sandy",1);
lili.bark();
sandy.bark();
// es6是这样的
class Dog {
constructor(name, age){
this.name = name;
this.age = age;
}
bark(){
console.log(`我叫${
this.name}`)
}
}
let lili = new Dog("lili",2);
let sandy = new Dog("sandy",1);
lili.bark();
sandy.bark();
1.类声明不会被提升
2.类声明中的代码都自动运行在严格模式下
3.调用类必须使用new
4.类中所有的方法都是不可枚举的
5.类中的方法是不能用new调用的
6.在类的方法中重写(修改)类名报错
1.关于“类中所有的方法都是不可枚举的”:
// es5的function下的属性和原型方法均可以被遍历
function Dog(name, age){
this.name = name;
this.age = age;
}
Dog.prototype.bark = function(){
console.log(`我叫${
this.name}`)
}
let lili = new Dog("lili",2);
for(var proto in lili){
console.log(proto); // 打印出name age bark
}
// es6的class下的方法不可遍历
class Dog {
constructor(name, age){
this.name = name;
this.age = age;
}
bark(){
console.log(`我叫${
this.name}`)
}
}
let lili = new Dog("lili",2);
for(var proto in lili){
console.log(proto); // 打印出name age
}
2.关于“类中的方法是不能用new调用的”:
// es5的function中
new lili.bark(); //输出:我叫undefined
// es6的class中
new lili.bark(); // 报错: lili.bark is not a constructor
// 用const防止重写类名和类声明提升
const Dog = (function () {
"use strict"; // 严格模式
const Dog = function (name, age) {
// 判断是否是new调用的Dog类
if (!(this instanceof Dog)) {
throw new Error("必须要用new来调用Dog类")
}
this.name = name;
this.age = age;
}
Object.defineProperty(Dog.prototype, "bark", {
// 设置不可new调用Dog的方法,不可枚举
value: function () {
if (this instanceof Dog.prototype.bark) {
throw new Error("不能用new来调用方法")
}
console.log(`我叫${
this.name}`)
},
enumerable: false
})
return Dog;
})();
let lili = new Dog("lili", 2);
Dog(); // 触发Error("必须要用new来调用Dog类")
new lili.bark(); // 触发Error("不能用new来调用方法")
1.基本类表达式
2.具名类表达式
// 基本类表达式
const Cat = class {
constructor(age) {
this.age = age
}
}
const xiaomao = new Cat(1);
// 具名类表达式
const Cat = class Cat{
constructor(age) {
this.age = age
}
}
const xiaomao = new Cat(1);
另外:
类可以作为参数传给函数;
能作为函数返回值;
能给变量赋值
设置静态方法,ES6 中规定,Class 内部只有静态方法,没有静态属性。
静态方法由类直接调用,对象不能使用
class Dog {
constructor(name, age){
this.name = name;
this.age = age;
}
bark(){
console.log(`我叫${
this.name}`)
}
static showInfo(){
console.log(`this is a dog`);
}
}
let lili = new Dog("lili",2);
class Dog {
constructor(name, age){
this.name = name;
this.age = age;
}
bark(){
console.log(`我叫${
this.name}`)
}
static showInfo(){
console.log(`this is a dog`);
}
get showAge(){
console.log(`我今年${
this.age}岁了`)
}
set nickName(value){
this.nick = value;
}
get nickName(){
return this.nick;
}
}
let lili = new Dog("lili",2);
lili.showAge; // 输出:我今年2岁了,注意,showAge不是一个函数,是作为一个属性使用的
lili.nickName = 'lili2'
console.log( lili.nickName ); // 输出:lili2