开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第16天,点击查看活动详情
🎈大家好,我是
李乐一,新人初来乍到,请多多关照~
📝小小的前端一枚,分享一些日常的学习和项目实战总结~
😜如果本文对你有帮助的话,帮忙点点赞呀!ღ( ´・ᴗ・` )比心~
写在前面
在es5中主要是通过构造函数方式和原型方式来定义一个类,在es6中引入了class类的概念,通过关键字定义类。
一、class类必须new调用,不能直接执行。
📝举个栗子
Class Info {// 定义一个名为Info的类
// 构造函数,用来接收参数
constructor(name) {
this.name = name
}
info() {// 类的方法,不用加function,有多个方法不必用逗号隔开
console.log(`my name is${this.name}`)
}
}
export default Info;
class类执行会报错,而es5中的类和普通函数没有本质区别
二、class类不存在变量提升
let info = new Info();
function Info(name) {
this.name = name;
}
Info.prototype.name = function() {
console.log(`my name is${this.name}`)
}
三、class类无法遍历它实例原型链上的属性和方法
function Foo (color) {
this.color = color
}
Foo.prototype.like = function () {
console.log(`like${this.color}`)
}
let foo = new Foo()
for (let key in foo) {
// 原型上的like也被打印出来了
console.log(key) // color、like
}
class Foo {
constructor (color) {
this.color = color
}
like () {
console.log(`like${this.color}`)
}
}
let foo = new Foo('red')
for (let key in foo) {
// 只打印一个color,没有打印原型链上的like
console.log(key) // color
}
四、new.target属性
es6为new命令引入了一个new.target属性,它会返回new命令作用于的那个构造函数。如果不是通过new调用或Reflect.construct()调用的,new.target会返回undefined
function Person(name) {
if (new.target === Person) {
this.name = name;
} else {
throw new Error('必须使用 new 命令生成实例');
}
}
let obj = {}
Person.call(obj, 'red') // 此时使用非new的调用方式就会报错
五、class类有static静态属性和方法
静态属性不能被子类继承,子类不能调用 静态属性只能通过类名调用,不能通过类的实例调用
static prop = 1 ; // 静态属性
static静态方法只能通过类调用,不会出现在实例上;另外如果静态方法包含 this 关键字,这个 this 指的是类,而不是实例。static声明的静态属性和方法都可以被子类继承。
class Foo {
static bar() {
this.baz(); // 此处的this指向类
}
static baz() {
console.log('hello'); // 不会出现在实例中
}
baz() {
console.log('world');
}
}
六:class继承extends
- class通过extends关键字来继承
- ES6继承,子类构造函数中必须使用super()。因为ES6继承是先将父类实例对象的属性和方法,加到this上面,然后再调用子类的构造函数修改这个this
- 如果子类没有定义constructor方法,super()会默认添加上
- 子类会继承父类的方法和属性,但是静态方法和属性必须通过子类的类名来调用
七:class的取值函数getter和存值函数setter
getter、setter就是给class的属性读值、传值用的。
取值函数getter和存值函数setter可自定义赋值和取值行为,当一个属性只有getter没有setter的时候,这个属性就是只读属性,不能赋值,第一次初始化也不行。
如果变量定义为私有的(定义在类的花括号外面),就可以只使用getter不使用setter。
let data = [1,2,3,4]; // 放在类外面,属于私有变量,可以只读取
class Person{
// 构造函数
constructor(x,y){
this.x = x;
this.y = y;
}
get x(){
console.log('获得name');
return this._name; // get读取属性
}
set x(x){
console.log("设置name");
this._name=x; // set给属性赋值
}
get data(){
return data; // 只读属性,属性返回的值只能是私有变量
}
todoSome(){
console.log(this.x + "的年龄是" +this.y+"岁");
}
static dayin(){
console.log("dayin");
}
}
export default Person;
使用
var test= new this.$myutils.classtest('haha','18');
test.x="haha3"; // 改变了实例化时候的x的值
test.todoSome(); // 输出:haha3的年龄是18岁。这里就已经不是实例化时候的haha了
console.log(test.data); // 结果:打印[1,2,3,4]