重点突出:
1:了解类的概念,由来
2:constructor方法
3:类的实例,继承
4:super 和this关键字
5:静态属性和方法
es6中引入了 class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。 我所理解的类指的就是 有相同属性和行为的一类群体
1.首先是写法不同。es6中使用关键词class
2.当new一个实例时,默认有一个constructor构造方法,默认返回实例对象(this)
3.类的调用必须通过new 一个实例
4.不存在变量提升,必须先声明,再调用
5.class 的静态方法,使用关键字static,不需new,直接通过类来调用
6.类的继承可以继承原生的构造函数,es5不可以
7.类的继承使用关键字extends,继承机制与es5完全不同
8.es6中继承的原理是:先创造父类的实例对象this,所以要构造函数constructor()访问父类的属性使用this,必须先调用super()方法;再通过子类的constructor()来修改this
//es5中的写法 先创建一个构造函数
function Point(x, y) {
this.x = x;
this.y = y;
}
//通过函数找到原型对象
Point.prototype.toString = function () {
return '(' + this.x + ', ' + this.y + ')';
};
//实例化
var p = new Point(1, 2);
//es6中的写法
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
//上面代码定义了一个“类”,可以看到里面有一个`constructor`方法,这就是构造方法,
//而`this`关键字则代表实例对象。也就是说,ES5 的构造函数`Point`,对应 ES6 的`Point`类的构造方法。
`//Point`类除了构造方法,还定义了一个`toString`方法。
//注意,定义“类”的方法的时候,前面不需要加上`function`这个关键字,直接把函数定义放进去了就可以了。
//另外,方法之间不需要逗号分隔,加了会报错
//class表达式
class Teacher{
// 构造方法
constructor(name,age,sex){
this.name=name;
this.age=age;
this.sex=sex
console.log("构造函数被调用了")
}
//自己添加的一个方法
teach(){
console.log("哈哈哈")
// alert("今天有一天点点丧")
}
}
// 实例化对象
let obj=new Teacher('panda',22,'男');
let obj2=new Teacher('monkey',18,'女');
// 调用它里面的teach方法
obj.teach();
console.log(obj.sex);
console.log(obj2.sex);
//而这时,后台会重复出现两个 构造函数被调用了 原因是我们实例了两个对象
//`constructor`方法是类的默认方法,通过`new`命令生成对象实例时,自动调用该方法。
class Point {
}
// 等同于
class Point {
constructor() {}
}
//es6中 class默认有一个构造方法 只需将其实例化然后调用里面的方法
class point{
.....
}
let obj=new point(1,2);
Class 可以通过
extends
关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。
ES5 的继承实质:先创造子类的实例对象this,再将父类的方法添加到this上面(Parent.apply(this))。
ES6 的继承实质:先将父类实例对象的属性和方法加到this上面(所以必须先调用super方法),再用子类的构造函数修改this。
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
static hello() {
console.log('hello world');
}
}
class ColorPoint extends Point {
//这里指的就是继承 但是子类继承父类时构造方法不能被执行 执行过程中 必须先执行父类的super
constructor(x, y, color) {
this.color = color; // ReferenceError
super(x, y);
this.color = color; // 正确
}
}
ColorPoint.hello();// hello world
let cp = new ColorPoint(25, 8, 'green');
super 作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次 super() 函数。注意:作为函数时,super() 只能用在子类的构造函数之中,用在其他地方就会报错。
//当做函数使用时
=
class A {
constructor() {
this.show();
}
}
class B extends A {
constructor() {
super();
}
show(){
console.log('实例');
}
static show(){
console.log('子类');
}
}
new B()
//输出 '实例' ,new B 时触发了 B 的构造函数,所以触发了 super 方法
//即触发了父类 A 的构造函数,此时的 this.show 的 this 指的是子类
super 作为对象使用
super 作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。
class A {
p() {
return 2;
}
}
class B extends A {
constructor() {
super();
console.log(super.p()); // 2
}
}
let b = new B();
静态属性指的是 Class 本身的属性,即
Class.propName
,而不是定义在实例对象(this
)上的属性。
class Foo {
}
Foo.prop = 1;
Foo.prop // 1
// 上面的写法为`Foo`类定义了一个静态属性`prop`。
//,因为 ES6 明确规定,Class 内部只有静态方法,没有静态属性。
现在有一个提案提供了类的静态属性,
/写法是在实例属性的前面,加上static
关键字。
class MyClass {
static myStaticProp = 42;
constructor() {
console.log(MyClass.myStaticProp); // 42
}
}
//这个新写法大大方便了静态属性的表达。
类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上
static
关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
class Foo {
static classMethod() {
return 'hello';
}
}
Foo.classMethod() // 'hello'
var foo = new Foo();
foo.classMethod()
ES6中的class类其实只是个语法糖,皆可以用ES5来实现。由构造函数Cat创建的实例cat是一个对象。在初始化cat实例的时候,在constructor中就会把this上的属性挂载到实例对象上面。另外牢记,this的指向与作用域无关,与调用执行函数时的上下文相关
class Cat {
constructor(name, age) {
this.name = name
}
run() {
console.log('run',this)
}
}
let cat = new Cat('米粒', '5个月')
cat.name // '米粒'
cat.run() // run Cat {name: "米粒"}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h1>猜数字小游戏</h1>
<hr>
<button onclick="startGuess()">开始游戏</button>
<h4>请输入0-100以内的任意整数:</h4>
<input type="text" name="" id="inp">
<button onclick="onGuessClick()">猜一下</button>
<div>结果:<span id='mess'></span></div>
//
</body>
<script>
var value = 0;//答案变量
class A{
constructor(num){
this.v = value;//生成答案
console.log(this.v);
this.num = num;
}
//计算大小
guess(){
var str = '';
if(this.v > this.num){// 猜小了
str = '猜小了';
}else if(this.v < this.num){//猜大了
str = '猜大了';
}else{//猜对了
str = '猜对了';
}
return str;
}
}
//猜一下事件
function onGuessClick(){
var v = document.getElementById('inp').value;
var a = new A(v);
var result = a.guess();
document.getElementById('mess').innerText = result;
}
//开始游戏事件
function startGuess(){
value = Math.ceil(Math.random()*100);
console.log(value);
}
</script>
</html>