目录
1、基本概念
2、基本用法
3、class与构造函数的区别
4、constructor的使用
5、自定义方法
6、extends和super
(1)问题一:我们想要在点击按钮二的时候改变字体大小,如何写呢?
(2)问题二:有的人又说,那直接再写一遍好了,把原来父类的construtor方法内容全部照搬过来,只是多了一个fontSize属性而已,请问这样可以吗?
(3)super如何使用呢?
(4)除了属性可以改写,方法也可以改写
7、static关键字
8、setter和getter方法
(1)setter
(2)getter
全代码粘贴
让你彻底学会class类~
我们通过一个例子来说明这个class类的原理以及如何使用,,,
我们想要实现的功能就是:根据用户输入的内容点击不同的按钮生成两种不同的语句,并输出显示
先写一个功能html。然后开启我们的class学习之路
<input type="text">
<button class="btn1">自动生成语句一</button>
<button class="btn2">自动生成语句二</button>
<p></p>
接着我们先用原生js获取到每个标签
<script>
const input = document.querySelector('input'),
btn1 = document.querySelector('.btn1'),
btn2 = document.querySelector('.btn2'),
p = document.querySelector('p')
</script>
1、基本概念
类可以看做是对象的模板,用一个类可以创建出许多不同的对象
2、基本用法
calss 类名 {} 没有分号,类名首字母大写,内容写在花括号里面。实例化执行构造方法,所以必须有构造方法constructor ,但可以不写出来。在构造方法constructor 中定义属性,在构造方法constructor外面定义方法。
3、class与构造函数的区别
大家一听类名首字母大写?就会想起来构造函数,构造函数也是首字母大写,其他class和构造函数都是自家人,Class在语法上更加贴合面向对象的写法,实现继承更加易读、易理解,更易于写java等后端语言的程序员使用,本质上还是语法糖,使用prototype;用typeof检测都是function类型。 那是不是也可以用new生成实例呢?答:正确
接下来我们来定义一个类,然后再生成一个实例。
注意:这个实例要写在定义类的后面,因为class是没有什么声明提升这样的功能的。
我们可以看到上面创建的实例,明显是个空实例,因为构造函数的同门师兄弟class里面没有内容,我们要想把他丰富起来,例如添加属性或者方法,这些属性或方法是每次生成实例都会各自添加的,也就是说我们要让每个实例都有自己特有的属性,但是都享用同一套代码,这么一想,好像挺方便的,如何写呢?
我们这时就要用到constructor了,constructor是class里面的一个方法,每次new的时候就会触发这个constructor,我们可以通过constructor定义2个参数
4、constructor的使用
这里创建实例的时候传入的2个参数,此时this.text就被赋值了‘我输入了’,也就是实例的属性text这时就被赋值了‘我输入了’这个字符串。
定义完了属性,如何定义方法?
5、自定义方法
方法直接写就行,在class里面创建方法也不需要写function关键字,也不需要用this。
这个方法就代表,当触发该方法的时候,p标签里面的内容就会变成Generatestate实例的text属性+用户输入的内容,p标签的字体颜色就会变成实例的color属性。这两个属性都是根据传入的参数来动态变化的。
此时我们来给按钮添加点击事件,来触发实例里面的showWord函数
点击按钮一看下效果,可以看到输出正确。
分析一下这个过程:当我们点击按钮一的时候就会生成一个Generatestate实例,实例紧接着执行自己的showWord方法,去改变字体颜色和内容
按钮一方法写好之后,按钮二我们想实现同样的功能,但并不想复制同一份代码,如何实现呢?
6、extends和super
class里面有个叫extends的关键词可以用于继承
那我们现在就来创建一个按钮二的子类来继承刚刚的Generatestate父类。
注意:我们并不需要在子类里面写任何内容,只需要在父类前面加上extends即可。
并给按钮二添加上点击事件、
此时实现的功能是一样的,点击按钮二输出 ‘你输入了’+‘哈哈哈’
(1)问题一:我们想要在点击按钮二的时候改变字体大小,如何写呢?
有人说了,简单啊,在子类里面的constructor里面定义字体大小属性就好了呀。
答:以上写法完全不可行
虽然我们用extends进行了继承,但并不代表我们不能改变子类,所以其实我们在子类写construtor方法的时候,实际上就是在覆盖原来父类的construtor方法。既然覆盖掉了,那我们在new实例的时候给construtor传入了三个参数,其实覆盖之后我们只有一个参数fontSize,所以此时点击按钮的时候,控制台是会报错的
(2)问题二:有的人又说,那直接再写一遍好了,把原来父类的construtor方法内容全部照搬过来,只是多了一个fontSize属性而已,请问这样可以吗?
答:不可以
原因是:如果在子类中写了construtor就必须要调用super ,主要原因是子类的this出现了问题,子类和父类的this都是指向各自的实例,因此在子类里面的this不会指向父类,此时就需要用super来初始化this,具体原因如下:
ES6在继承中强制要求,必须在子类调用super,因为子类的this是由父类得来的。
- super即可以做为函数调用,又可以做为对象使用。做为函数时,只能在constructor内部调用。做为对象则可以在别的方法内调用。
- class B extends A {} super如果在静态方法内调用,super是父类(A),如果方法里有this,则指向该类(B),如果在原型方法内调用。super指向父类的原型(A),如果方法里有this,则指向该实例的原型(B)
- 给super添加属性或者修改,修改的是子类的属性,因为this是子类
注意:在子类construtor里面写this之前一定要写super。总结:先super,后this
(3)super如何使用呢?
子类不需要重复写父类的代码,直接用super来进行调用,如果属性有几十个时更加体现出了方便。
(4)除了属性可以改写,方法也可以改写
看下效果:
先点击按钮一,再点击按钮二,看到子类方法的调用完全正确
7、static关键字
类class通过 static 关键字定义静态方法。不能在类的实例上调用静态方法,而应该通过类本身调用。不需要实例化类,即可直接通过该类来调用的方法,即称之为“静态方法”。将类中的方法设为静态方法也很简单,在方法前加上static关键字即可。这样该方法就不会被实例继承!
当我们不需要也不想要创建新的实例,就可以用static关键字来创建一个方法
我们先定义一个静态方法,返回一段文字
我们想把这个函数里面的内容输出到p标签里面,如何实现呢?
这样写是否正确?
这里的this用法是正确的,因为在一个静态方法里面调用另一个静态方法是可以用this的,这里的this并不是绑定实例的,是绑定类本身的,因为静态方法是需要用类调用,而不是用实例去调用。这样疑惑就解开了。
此时我们给p标签添加点击事件,在点击事件里面只用 类去调用静态方法tips_to_p,可前段不要用实例去调用静态方法,不然会报错
看下效果,点击p标签,就会出现温馨提示:
8、setter和getter方法
ES6中,可以通过get方法获取属性值,通过set方法对属性值进行更改值。不自定义时,初始化时会自动调用set方法,读取时调用get方法,get方法只能读。
(1)setter
只看概念可能还是不太理解,我们用例子看一下,首先明确的是set和get针对的目标都是属性。
我们用set定义一个属性。就是在类里面进行编写,set+属性名称。
看到提示说一个set属性必须有一个参数。我们加上、
在setter里面我们把参数赋值给实例的value属性,并且把value属性值加在原来的p标签内容里面
然后在按钮一点击事件里面进行属性设置即可。
注意:我们在调用set属性的时候不能加(),是因为它本身是一个属性不是一个方法,虽然定义的方式像是一个方法。但它是一个特殊的访问器属性
此时我们点击按钮,功能就实现了
(2)getter
get和set是一对的,,get可以获取值,set可以修改值
可以看到提示,get是没有参数的
给按钮一进行了get值的打印
看下效果,点击按钮一,set和get的作用均起到了效果
总结:因此我们可以发现,当一个属性word被定义了set和get之后,同一个名字既可以赋值,也可以输出内容,这就很方便了。
全代码粘贴
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text">
<button class="btn1">自动生成语句一</button>
<button class="btn2">自动生成语句二</button>
<p></p>
<script>
const input = document.querySelector('input'),
btn1 = document.querySelector('.btn1'),
btn2 = document.querySelector('.btn2'),
p = document.querySelector('p')
// 定义一个类
class Generatestate {
// 用static创建一个静态方法
static getTips() {
return '温馨提示:点击按钮即可生成语句'
}
static tips_to_p() {
p.innerHTML = this.getTips()
}
// 通过constructor定义属性
constructor(text, color) {
this.text = text
this.color = color
}
showWord() {
p.innerHTML = this.text + input.value
p.style.color = this.color
}
// 用set设置一个属性
set word(value){
this.value = value
p.innerHTML += this.value
}
get word(){
return `我是get获取的值:${this.value}`
}
}
// 创建子类
class son_Generatestate extends Generatestate {
constructor(text, color, fontSize) {
super(text, color)
this.fontSize = fontSize
}
showWord() {
p.innerHTML = this.text + p.innerHTML
p.style.color = this.color
p.style.fontSize = this.fontSize
}
}
// 创建一个类实例,并传入参数
btn1.addEventListener('click', () => {
const generatestate = new Generatestate('我输入了', '#0f0');
generatestate.showWord()
generatestate.word = '我是set新加的话'
console.log(generatestate.word)
})
btn2.addEventListener('click', () => {
const son_generatestate = new son_Generatestate('你输入了', '#0f0', '30px');
son_generatestate.showWord()
})
p.addEventListener('click', () => {
Generatestate.tips_to_p()
})
</script>
</body>
<style>
.btn1 {
background: green;
color: #fff;
}
.btn2 {
background: #F9BD12;
color: #fff;
}
button {
border: 1px solid transparent;
padding: 5px 10px;
border-radius: 5px;
cursor: pointer;
}
p {
border: 1px solid green;
width: 430px;
height: 200px;
border-radius: 5px;
}
input {
border: 1.5px solid green;
padding: 5px 10px;
border-radius: 5px;
outline-style: none;
}
</style>
</html>
那么class的核心知识点就讲完啦~