为什么需要class
在其他语言中class已经是一个早就被实现的功能,在JavaScript中一直到ES6被实现。在class没有实现之前我们是这样写的(如下代码)
function Person(name,sex){this.name = ''this.sex='
}
Person.prototype.say=function(){alert('hello')
}
有了class我们就这么写的,是不是看起来更简洁。甚至对于初学者来说都不需要了解什么是prototype
class Person {constructor (name,sex) {this.name = name;this.sex = sex;}say() {alert('hello')}
}
个人认为的是:在没有class这个声明之前,可以使用es5来模拟。但是在一定程度上并不是规范。如果新手或者通过其他语言学习者看到这个prototype什么的就比较懵。有了这个class关键字让js做面向对象的设计更完善了
class是什么
定义:类关键字Class 和 constructor 构造函数
类是用于创建对象的模板。 用 class 关键字来创建一个类,类体在一对大括号 {} 中,我们可以在大括号 {} 中定义类成员的位置,如方法或构造函数。 每个类中包含了一个特殊的方法 constructor(),它是类的构造函数,这种方法用于创建和初始化一个由 class 创建的对象。
class ClassName {constructor() { ... }
}
//定义好类后,我们就可以使用 new 关键字来创建对象:
let site = new ClassName();
创建对象时会自动调用构造函数方法 constructor()。还可以这样创建对象
// 未命名/匿名类
let Runoob = class {constructor(name, url) {this.name = name;this.url = url;}
};
console.log(Runoob.name);
// output: "Runoob"
// 命名类
let Runoob = class Runoob2 {constructor(name, url) {this.name = name;this.url = url;}
};
console.log(Runoob.name);
// 输出: "Runoob2"
// 自执行的类
let Runoob =new class {constructor(name, url) {this.name = name;this.url = url;}
}('name','111');
console.log(Runoob)
constructor 构造方法
构造方法是一种特殊的方法:
- 构造方法名为 constructor()。
- 构造方法在创建新对象时会自动执行。
- 构造方法用于初始化对象属性。
- 如果不定义构造方法,JavaScript 会自动添加一个空的构造方法。
static 静态方法
类(class)通过static
关键字定义静态方法。
静态方法调用直接在类上进行,不能在类的实例上调用。但是父类的静态属性和静态方法,会被子类继承。
静态方法通常用于创建实用程序函数。
class A {static foo = 100;static hello() {console.log('hello world');console.log(A.foo)}
}
A.hello()
const a=new A(); // typeError: a.hello is not a function
a.hello()
class B extends A {
}
B.hello()// hello world
注意,静态属性是通过软拷贝实现继承的。
class A { static foo = 100; }
class B extends A {constructor() {super();B.foo--;}
}
const b = new B();
B.foo // 99
A.foo // 100
上面示例中,foo
是 A 类的静态属性,B 类继承了 A 类,因此也继承了这个属性。但是,在 B 类内部操作B.foo
这个静态属性,影响不到A.foo
,原因就是 B 类继承静态属性时,会采用浅拷贝,拷贝父类静态属性的值,因此A.foo
和B.foo
是两个彼此独立的属性。
但是,由于这种拷贝是浅拷贝,如果父类的静态属性的值是一个对象,那么子类的静态属性也会指向这个对象,因为浅拷贝只会拷贝对象的内存地址。
class A {static foo = { n: 100 };
}
class B extends A {constructor() {super();B.foo.n--;}
}
const b = new B();
B.foo.n // 99
A.foo.n // 99
上面示例中,A.foo
的值是一个对象,浅拷贝导致B.foo
和A.foo
指向同一个对象。所以,子类B
修改这个对象的属性值,会影响到父类A
。
私有方法和属性
目前 class 的私有属性特性已经进入了 Stage3 实验阶段,通过 Babel 已经可以使用,并且 Node v12,chrome 中也增加了对私有属性的支持,但这并不妨碍我们用 JS 的现有功能实现一个私有属性特性,以加深对这一概念的理解。
class Person {_count = 100// 私有属性外部不可直接设置值,直接访问// 变量污染,不能设置同名属性#userName#user_Name; // 实例上的私有属性,不能直接修改值,不能遍历static #userName; // 类的静态私有属性,不可继承,无法直接修改,只能通过类内部方法修改static names = []get value() {return this._count}set value(num) {this._count = num}constructor(name) {this.name = namethis.#user_Name = namePerson.#userName = '1111'Person.names.push(name)}userName() {console.log(Person.#userName)console.log(this.#user_Name)}setUserName(name) {Person.#userName = namethis.#user_Name = namePerson.names.push(name)}sayHi() {console.log(`我是可以直接设置的名字${this.name}`)}}//const myPerson = new Person('用户1')// Object.setPrototypeOf(myPerson,null)myPerson.sayHi()console.log('Person', myPerson)const myPerson2 = new Person('用户2')// Object.setPrototypeOf(myPerson,null)myPerson2.sayHi()console.log('Person', myPerson2)
- 私有属性外部不可直接设置值,直接访问
- 变量污染,不能设置同名属性 #userName
- #user_Name; // 实例上的私有属性,不能直接修改值,不能遍历
- static #userName; // 类的静态私有属性,不可继承,无法直接修改,只能通过类内部方法修改
继承extends和super
- 关键字用于创建一个类,该类是另一个类的子类。
- 子类继承了另一个类的所有方法。
- 继承对于代码可重用性很有用:在创建新类时重用现有类的属性和方法。
- super() 方法引用父类的构造方法。
- 通过在构造方法中调用 super() 方法,我们调用了父类的构造方法,这样就可以访问父类的属性和方法。
class childClass extends parentClass
super 关键字用于访问和调用一个对象的父对象上的函数。。
在构造函数中使用时,super关键字将单独出现,并且必须在使用 this 关键字之前使用。super 关键字也可以用来调用父对象上的函数。
第一种情况,super
作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次super
函数。
class A {}
class B extends A {constructor() {super();}
}
第二种情况,super
作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。
class A {p() {return 2;}
}
class B extends A {constructor() {super();console.log(super.p()); // 2}
}
let b = new B();
使用的时候注意事项
1.只能new使用,不能作为方法直接调用会报错
2.this调用的是时指向
3.类方法不可枚举
和ES5的区别和相同点
1.与 ES5 不同,类不存在变量提升
2.类的调用必须要使用 new 命令,否则会报错
3.底层还是ES5原型链实现(可称作语法糖)
4.实例的__proto__ 指向 类的prototype
最后
最近找到一个VUE的文档,它将VUE的各个知识点进行了总结,整理成了《Vue 开发必须知道的36个技巧》。内容比较详实,对各个知识点的讲解也十分到位。
有需要的小伙伴,可以点击下方卡片领取,无偿分享