美文网首页
ES6中Class类(面向对象编程)

ES6中Class类(面向对象编程)

作者: 扶得一人醉如苏沐晨 | 来源:发表于2023-03-26 10:07 被阅读0次

一、有两大编程思想:面向过程和面向对象;

2.1、面向过程编程POP(Process-oriented programming)

  • 面向过程即分析出解决问题所需要的步骤,然后用函数将这些步骤一步步实现,使用的时候再一个个的一次调用就可以了;

  • 即将大象装进冰箱,从面向过程来看,需要打开冰箱门、装进去大象、关上冰箱门

2.2、面向对象编程OOP(Object Oriented Programming)

  • 面向对象即把事务分解成为一个个对象,然后由对象之间分工与合作;是以对象功能来划分问题,而不是步骤;在面向对象程序开发思想中,每一个对象都是功能中心,具有明确分工;

  • 面向对象编程具有灵活、代码可复用、容易维护和开发的优点,更适合多人合作的大型软件项目;

  • 具有封装性、继承性、多态性等特性;

  • 即将大象装进冰箱,从面向对象来看,要先找出对象,并写出 这些对象的功能;如大象对象,冰箱对象;

二、面向过程与面向对象编程思想两种方式对比:

image.png

三、面向对象的思维特点:

1、抽取(抽象)对象共用的属性和行为组织(封装)成一个类(模板)

2、对类进行实例化,获取类的对象

面向对象编程我们考虑的是有哪些对象,按照面向对象的思维特点,不断的创建对象,使用对象,指挥对象做事情;

四、ES6中的类和对象

4.1、对象

JavaScript中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,如字符串、数值、数组、函数等;

对象是由属性和方法组成的:

属性:事物的特征,在对象中用属性来表示(名词);

方法:事物的行为,在对象中用方法来表示(动词);

4.2、类(class):

在ES6中新增了类的概念,可用class关键字声明一个类,之后用该类实例化对象;

4.3、类和对象关系:

类抽象了对象的公共部分,它泛指某一大类(class);

对象特指某一个,通过类实例化一个具体的对象

五、类的创建和使用(class)

5.1、创建类

class 类名 { // 此处类名不要加括号

// 类中的函数体

}

5.2、创建实例:

var xx = new 类名(); // 类必须使用new实例化对象

5.3、类constructor构造函数

constructor()方法是类的构造函数(默认方法),用于传递参数,返回实例对象,通过new命令生成对象实例,自动调用该方法。若没有显示定义,类内部会自动给我们创建一个constructor()。'

<script>
        // 创建类
        class Person {
            constructor(uname, sex, age) {
                this.uname = uname;
                this.sex = sex;
                this.age = age;
            }
        }
        // 创建实例对象
        var xm = new Person('小明', 'female', 19);
        var xs = new Person('小衫', 'male', 18);
        console.log(xm, xs);
 </script>

类中所有函数均不需要写function,且多个函数方法之间不需要添加符号分隔;

 <script>
        // 创建类
        class Person {
            //静态属性(只能通过类去访问)
            static tset = '测试'
           //静态方法(只能通过类去访问)
            static test(){
                console.log('hello')
            }
            constructor(uname, sex, age) {
                    this.uname = uname;
                    this.sex = sex;
                    this.age = age;
            }
           // 方法必须使用该语法, 不能使用 ES5 的对象完整形式
            Say() {
                console.log('我叫' + this.uname, '性别' + this.sex, '今年' + this.age);
            }
        }
        // 创建实例对象
        var xm = new Person('小明', '女', 19);
        var xs = new Person('小衫', '男', 18);
        console.log(xm, xs);
        // 通过实例调用方法
        xm.Say(); // 我叫小明 性别女 今年19
        xs.Say(); // 我叫小衫 性别男 今年18
    </script>

5.4、继承

继承是指子类可以继承父类的一些属性和方法,语法如下;

class Father {
  // 父类
}
class Son extends Father {
  // 子类继承父类
}

看下面一个错误示例:

<script>
        class Father {
            constructor(x, y) {
                this.x = x;
                this.y = y;
            }
            sum() {
                console.log(this.x + this.y);
            }
        }
        class Son extends Father {
            constructor(x, y) {
                this.x = x;
                this.y = y;
            }
        }
        var son = new Son(1, 2);
        son.sum();
</script>

运行该代码,会报如下错误:

Uncaught ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
    at new Son (ObjTsting.html:24:17)

这是因为子类中无法使用父类的sum方法,在父类方法中this.x和this.y中的this指代的是父类,而子类中传过来的参数中,this.x和this.y指代的是子类,所有会报错;
那要如何继承父类中的参数和方法呢?此时则需要super关键字~

5.5、super关键字

它用于访问和调用对象父类上的函数,可以调用父类的构造函数,也可以调用父类的普通函数,上述例子就可以改造成:

<script>
        class Father {
            constructor(x, y) {
                this.x = x;
                this.y = y;
            }
            sum() {
                console.log(this.x + this.y);
            }
        }
        class Son extends Father {
            constructor(x, y) {
                super(x, y); // 调用父类的构造函数
            }
        }
        var son = new Son(1, 2);
        son.sum(); // 3
</script>

继承是指若子类有属性和方法,则用子类的属性和方法,若无,则继承父类方法;

子类在构造函数中使用super,必须放到this前面(即必须先调用父类的构造方法,再使用子类的构造方法);

<script>
        class Father {
            constructor(uname, sex) {
                this.uname = uname;
                this.sex = sex;
            }
        }
        class Son extends Father {
            constructor(uname, age) {
                super(uname); // 调用父类的构造函数(uname)
                this.age = age; // 定义子类独有的属性
            }
        }
</script>

类里面共有的属性和方法一定要加this使用;构造函数中的this 指向的是创建的实例对象;谁调用类中的方法,this就指向谁;

在ES6中类没有变量提升,所以必须要先定义类,才能通过类实例化对象;

5.6、示例、手机类的继承

class Phone{
            //构造方法
            constructor(brand, price){
                this.brand = brand;
                this.price = price;
            }
            //父类的成员属性
            call(){
                console.log("我可以打电话!!");
            }
        }

        class SmartPhone extends Phone {
            //构造方法
            constructor(brand, price, color, size){
                super(brand, price);// Phone.call(this, brand, price)
                this.color = color;
                this.size = size;
            }

            photo(){
                console.log("拍照");
            }

            playGame(){
                console.log("玩游戏");
            }

            call(){
                console.log('我可以进行视频通话');
            }
        }

        const xiaomi = new SmartPhone('小米',799,'黑色','4.7inch');
        // console.log(xiaomi);
        xiaomi.call();
        xiaomi.photo();
        xiaomi.playGame();

5.7、class内部getter和setter

 // get 和 set  
        class Phone{
            get price(){
                console.log("价格属性被读取了");
                return 'iloveyou';
            }

            set price(newVal){
                console.log('价格属性被修改了');
            }
        }

        //实例化对象
        let s = new Phone();

        // console.log(s.price);
        s.price = 'free';

getter使用场景,,当返回值依赖于多个数值进行计算
setter使用场景,,对newval赋值之前进行判断

5.8、Es11类的私有属性

 <script>
      class Person {
        //公有属性
        name;
        //私有属性
        #age;
        #weight;
        //构造方法
        constructor(name, age, weight) {
          this.name = name;
          this.#age = age;
          this.#weight = weight;
        }

        intro() {
          console.log(this.name);
          console.log(this.#age);
          console.log(this.#weight);
        }
      }

      //实例化
      const girl = new Person("晓红", 18, "45kg");

      // console.log(girl.name);
      // console.log(girl.#age);  //报错
      // console.log(girl.#weight); //报错

      girl.intro();
    </script>

七、构造函数和原型

构造函数和原型是在ES6出来之前存在的,后被类取代;在ES6之前,对象不是基于类创建的,而是用一种成为构造函数的特殊函数来定义对象和它们的特征。

创建对象可通过如下三种方式:

1、对象字面量

2、new Object()

3、自定义构造函数

<script>
        var obj1 = {}; // 通过字面量创建对象
        var obj2 = new Object(); // 利用new创建对象
        function Obj3(uname, age) { // 利用构造函数创建对象
            this.uname = uname;
            this.age = age;
            this.sing = function() {
                console.log('这是构造函数中包含的方法');
            }
        }
        var dog = new Obj3('小狗', 1);
        var cat = new Obj3('小猫', 1.5);
</script>

构造函数是一种特殊的函数,主要用于初始化对象,即为对象成员变量赋初始值,它总与new一起使用,他们可把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面

7.1、在JS中,使用构造函数时要注意以下两点:

  • 1、构造函数用于创建某一类对象,其首字母要大写;

  • 2、构造函数要和new一起使用才有意义

new 在执行时会做四件事情:

image

7.2、实例成员与静态成员

  • 实例成员就是构造函数内部通过this添加的成员;实例成员只能通过实例化的对象来访问;不可以通过构造函数来访问实例成员;
  • 静态成员及在构造函数本身上添加的成员;静态成员只能通过构造函数来访问
<script>
        function Obj3(uname, age) { // 利用构造函数创建对象
            this.uname = uname;
            this.age = age;
            this.sing = function() {
                console.log('这是构造函数中包含的方法');
            }
        }
        var dog = new Obj3('小狗', 1);
        console.log(dog.uname); // 小狗 // 只能通过实例化的对象来访问实例成员
        console.log(Obj3.uname); // undefined 不可以通过构造函数访问实例成员
        // 静态成员是指在构造函数本身上添加的成员,静态成员只能通过构造函数来访问
        Obj3.sex = 'male';
        console.log(Obj3.sex); // male
</script>

7.3、构造函数的问题

构造函数方法很好用,但是存在浪费内存的问题;

  • 不同实例对象会开辟多个空间用于存放同一个函数,这样就会造成内存浪费;

  • 既然使用同一个函数构建出来的实例对象,那么该函数和属性应该是所有对象所共享的,
    JavaScript规定,每一个构造函数都有一个prototype属性,指向另一个对象。注意,这个prototype就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有。因此可以将那些不变的方法,直接定义在prototype上,这样所有对象的实例就可以共享这些方法

7.4、对象原型proto

对象都会有一个属性proto指向构造函数的prototype原型对象,之所以我们对象可使用构造函数prototype原型对象的属性和方法,就是因为对象有proto原型的存在。

  • proto对象原型和原型对象prototype是等价的
  • proto对象原型的意义就在于为对象的查找机制提供一个方向,或者说一条路线,但是它是一个非标准属性,因此实际开发中,不可以使用这个属性,它只是内部指向原型对象prototype

7.5、constructor构造函数

对象原型(proto)和构造函数(prototype)原型对象里面都有一个属性constructor属性,constructor我们称为构造函数,因为它指回构造函数本身。

他主要用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数

<script>
        function Obj3(uname, age) { // 利用构造函数创建对象
            this.uname = uname;
            this.age = age;
        }
        Obj3.prototype = {
            sing: function() {
                console.log('wangwang');
            }
        }
        var dog = new Obj3('小狗', 1);
        console.log(Obj3.prototype); 
        console.log(dog.__proto__);
        console.log(Obj3.prototype === dog.__proto__); // true
</script>

7.6、构造函数、实例、原型对象三者之间的关系

只要是对象,就有原型对;

  • 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性;

  • 若没有则查找它的原型(即proto指向的prototype对象);

  • 如果还没有就查找原型对象的原型,以此类推一直找到Object为止;

  • proto对象原型的意义就在于为对象成员查找机制提供一个方向,或者说是一条路线

7.7、扩展内置对象

可以通过原型对象,对原来的内置对象进行扩展自定义的方法,比如给数组增加自定义求偶数和的功能;

<script>
        console.log(Array.prototype);
        Array.prototype.sum = function() {
            var sum = 0;
            for (var i = 0; i < this.length; i++) {
                sum += this[i];
            }
            return sum;
        }
        var arr = [1, 2, 3, 4];
        console.log(arr.sum()); // 10
</script>

注意:数组和字符串内置对象不能给原型对象覆盖操作Array.prototype = {},只能是Array.prototype.xxx = function() {}的方法

相关文章

  • JavaScript之面向对象编程

    五、面向对象编程 目录:面向对象原型继承、面向对象class继承(ES6引入的) 1.面向对象原型继承 类:模板 ...

  • Pytorch搭建网络

    面向对象编程 类 面向对象编程——类class和对象object class是一种类型(Type),object是...

  • 【ES6】class的基本使用与继承

    生成实例对象的传统方法是通过构造函数 定义类 ES6 引入了class(类),让javascript的面向对象编程...

  • ES6时代的JavaScript面向对象编程

    ES6时代的JavaScript面向对象编程 ES6带来的类语法糖 类的定义 ES6支持了class,extend...

  • 【python】面向对象

    面向对象编程面向对象的设计思想是抽象出Class,根据Class(类)创建Instance(实例)。面向对象的程序...

  • 23

    编程方法大致有三种: ——面向对象 ——面向过程 ——函数式编程 面向对象——类——class 面向过程——过程—...

  • ES6面向对象

    1、ES6面向对象: class(类) 构造函数 对象 实例对象 ES5面向对象是模拟面向对象。 2、继...

  • ES6 class类

    在ES6以前,没有类的概念,所有的面向对象都是基于原型实现的。ES6中可以通过class定义类,但是class的本...

  • typescript之类

    类 类就是面向对象编程,javascript基于原型的方法来实现类,es6之后引入class关键字,本质上虽然还是...

  • class创建组件与state关键字

    es6中class关键字,是实现面向对象编程的新形式class与function的区别在与: class有自己的生...

网友评论

      本文标题:ES6中Class类(面向对象编程)

      本文链接:https://www.haomeiwen.com/subject/bfawrdtx.html