键盘敲烂,月薪过万作业不做,等于没学
当前系列: ES进阶 修改讲义

复习:类和对象

但是,之前我们只能生成一个匿名对象,或者使用JavaScript内置对象,我们好像不能自己定义一个类。



class关键字

ES6终于提供了class关键字和其他面向对象的支持。我们可以这样声明一个Student类:

        class Student {
            constructor(sname) {
                this.sname = sname;    //this就是实例化之后的对象
            }
            hello() {
                alert('Hello, ' + this.sname + '!');  //复习:用模板字符串改造
            }
        }

class后面直接跟自定义(开发人员自己命名的)类名,花括号({})中的内容包括:


constructor

构造函数。构造函数可以有一个或多个参数,在对象生成时时调用:

    var atai = new Student('atai');

演示:当用 new 来调用这个函数时,它就进入构造函数constructor,默认返回this。

实例方法

hello()是实例方法,可以使用当前对象的属性(所以,一定要带上this,不信就试一试?)

演示:atai.name和atai.hello()

注意

  • hello()方法前面不要加 function
  • 总有一个无参构造函数,即:可以没有constructor()函数
    @猜一猜@:有没有构造函数重载(复习)
  • 返回this(对象自己),也可以返回其他对象?!excuse me……
        constructor(name) {
            this._name = name;
            return this;    //默认省略
            //可以new出一个匿名对象
            //return {
            //    age: 38
            //};
            ////这又是不行的,唉~~
            //return '我就不是Student对象';
        }

ES6的class本质上就是function。


ES5的构造函数(constructor)

function Student(name){
    this.name=name;
    this.hello=function(){
        alert('Hello, '+this.name+'!');}
}

这不就是一个普通函数吗?

函数是普通函数,但当你用 new 来调用这个函数时,它就变成了一个构造函数,默认返回this

所以,一定要带上this不信就试一试?

  • 和函数参数同名
  • 和函数参数不同名

但是,不建议在函数中添加:

    return this;    //会是window对象

因为这样的话,new Student()没有问题,但Student()的时候,返回的就是window对象了……(详见:this总结

演示:ES5的写法和ES6的class声明具有完全相同的效果


静态(static)方法

在方法面前加上关键字static

    static hello() {
        //注意这个this,代表的是当前类,不是当前实例哟
        alert('Hello, ' + this.name + '!');
    }
该方法就只能用类而是类的实例(instance)调用:
Student.hello();


演示:this.Name变成了Student(类名)


相互调用

类中的方法可以互相调用。但是,在一个类中:

  • 实例可以调用实例
  • 静态可以调用静态
  • 实例可以调用静态
  • 静态可以调用实例

static方法体内不能调用实例方法(注意理解)

和C#不同:

  • (哪怕是同一个)实例方法体内调用静态方法时,要使用类名调用
  • static方法体类,可以使用this。此时this指代当前类(而不是实例)


getter和setter

            get Name(){
                return this.name.toUpperCase();
            }
            set Name(value) {
                this.name = value;
            }

可以:

  • 在构造函数以外改变对象的状态(属性)
  • 实现“只读/写”的封装(但因为没有private的封装,用处不大……)

实现私有的hack方法:

  • 变量名加_前缀(友情提示)
  • 利用函数作用域
            function Student(name) {
                var _greet = "Hello, "
                return {
                    name: name,
                    hello: function () {
                        alert(_greet + this.name + '!');
                    }
                }
            }


  1. 模拟真正面向对象的封装(属性)
            function LuckyStack() {
                var fee = 986, unit = '周';
                return {
                    cost: function () {
                        console.log(`源栈收费:每${unit}${fee}元`);
                    }
                }
            }
            
            var ls = LuckyStack();
            console.log(ls.fee);    //undefined,ls.fee不会被暴露
            ls.cost();              //ls.cost()像一个public方法一样使用




Class表达式

把一个类赋值给一个变量

        const Student = class DFG {
            constructor(name) {
                this.name = name;
            }
            hello() {
                alert(DFG.name + ' Hello, ' + this.name + '!');
            }
        }
        var yf = new Student('yf');

类名(DFG)仅在class内部可用。如果内部没有使用,可以省略,而且可以写出立即执行的 Class


其他


  • 没有变量提升(先声明后使用)
  • 属性名可以使用表达式:get [propertyName]{...}  (ES6 新特性)
  • 实例属性可以写在方法最顶部(点赞!)



此前学习JavaScript面向对象的难点:你不知道JavaScript绕来绕去是为了什么……其实,她就是在模拟真正的“面向对象”语言。

说到底,还是没有class……有的是什么?

JavaScript只有一个class(对象模板):Object。

试试看:

console.log(typeof Student);

为什么呢?(原来是个“语法糖”)





作业

  1. 用class声明一个课程(Course),包含属性:name,startDate,endDate,students,以及方法:begin()和end()
  2. 生成两个课程对象:JavaScript和SQL
  3. 调用对象的begin()和end()方法,可以在控制台输出开课信息,如:JavaScript于2019年5月5日开课,共有5名同学(两开花、王枫、王平、采铃、老程)报名。
  4. 不修改class,动态的改变begin()方法,使其能影响所有Course对象
  5. 让end()方法为各自对象“自有”,其他对象无法修改
  6. 在Course中使用getter和setter包装endDate,保证endDate不会小于startDate,也不会比startDate多出365天
  7. 判断并证明以下说法:
    • ES里的class其实就是一个function
    • constructor总是返回class的实例
    • 当new了一个class之后,class里声明的方法就会被copy到新生成的实例对象上
    • JavaScript里面,类就是对象,对象也是类
    • 只有Function才有prototype
    • Javascript是动态类型语言,所以对象的类型是可以随意更改的


作业点评

  • 含参构造函数
  • ;=> 区分函数声明和函数表达式
  • 尽量按照需求完成作业
  • 代码一行不能太长
学习笔记
源栈学历
大多数人,都低估了编程学习的难度,而高估了自己的学习能力和毅力。

作业

觉得很 ,不要忘记分享哟!

任何问题,都可以直接加 QQ群:273534701

在当前系列 ES进阶 中继续学习:

多快好省!前端后端,线上线下,名师精讲

  • 先学习,后付费;
  • 不满意,不要钱。
  • 编程培训班,我就选源栈

更多了解 加:

QQ群:273534701

答疑解惑,远程debug……

B站 源栈-小九 的直播间

写代码要保持微笑 (๑•̀ㅂ•́)و✧

公众号:源栈一起帮

二维码