• JavaScript基础之八JavaScript面向对象


    1. JavaScript面向对象

    1.0 认识对象类型

    • 在数据类型中我们提到还有一种特别的类型:对象类型
      • 对象类型涉及到JavaScript的各个方面,所以掌握对象类型非常重要
      • 对象类型是一种存储键值对(key-value)的更复杂的数据类型;
    • 为什么需要对象类型呢?
      • 基本数据类型可以存储一些简单的值,但是现实世界的事物抽象成程序时,往往比较复杂;
      • 比如一个人,有自己的特性(比如姓名、年龄、身高),有一些行为(比如跑步、学习、工作);
      • 比如一辆车,有自己的特性(比如颜色、重量、速度),有一些行为(比如行驶);
    • 这个时候,我们需要一种新的类型将这些特性和行为组织在一起,这种类型就是对象类型
      • 对象类型可以 使用{…} 来创建的复杂类型,里面包含的是键值对(“key: value”);
      • 键值对可以是属性和方法(在对象中的函数称之为方法);
      • 其中key是字符串,但是在定义对象的属性名时,大部分情况下引号都是可以省略的(也叫做属性名property name ,ES6之后也可以是Symbol类型,后续学习);
      • 其中value可以是任意类型,包括基本数据类型、函数类型、对象类型等;
      <script>
        /*
          两个术语: 函数/方法
             函数(function): 如果在JavaScript代码中通过function默认定义一个结构, 称之为是函数.
             方法(method): 如果将一个函数放到对象中, 作为对象的一个属性, 那么将这个函数称之为方法.
        */
        function foo() {
        }
        // key: 字符串类型, 但是在定义对象的属性名时, 大部分情况下引号都是可以省略的
        var person = {
          // key: value
          name: "why",
          age: 18,
          height: 1.88,
          "my friend": {
            name: "kobe",
            age: 30
          },
          run: function() {
            console.log("running")
          },
          eat: function() {
            console.log("eat foods")
          },
          study: function() {
            console.log("studying")
          }
        }
        person.run();
      </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    1.1 创建对象和使用对象

    • 对象的创建方法有很多,包括三种:

      • 对象字面量(Object Literal):通过{}
      • new Object+动态添加属性;
      • new 其他类;
    • 目前我们主要掌握对象字面量的方式,后续我们学习其他两种方式。

      • 属性之间是以逗号( comma )分割的;
    • 对象的使用过程包括如下操作:

      • 访问对象的属性;
      • 修改对象的属性;
      • 添加对象的属性;
      • 删除对象的属性;
      <script>
        // 1.对象字面量
        var obj1 = {
          name: "why"
        }
        // 2.new Object()
        // // Object构造函数
        // var obj2 = new Object()
        // obj2.name = "kobe"
        // // 3.new 其他类()
        // function Person() {}
        // var obj3 = new Person()
      </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    1.2 对象的常见操作

    • 访问对象的属性
    • 修改对象的属性
    • 添加对象的属性
    • **删除对象的属性:delete操作符
      <script>
        // 1.定义了一个对象
        var info = {
          name: "why",
          age: 18,
          friend: {
            name: "kobe",
            age: 30
          },
          running: function() {
            console.log("running~")
          }
        }
        // 2.访问对象中的属性
        // console.log(info.name)
        // console.log(info.friend.name)
        // info.running()
        // 3.修改对象中的属性
        // info.age = 25
        // info.running = function() {
        //   alert("I am running~")
        // }
        // console.log(info.age)
        // info.running()
        // 4.添加对象中的属性
        info.height = 1.88
        info.studying = function() {
          console.log("I am studying~")
        }
        console.log(info)
        // 5.删除对象中的属性
        // delete关键字(操作符)
        delete info.age
        delete info.height
        console.log(info)
      </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    1.3 方括号和引用的使用

    • 为什么需要使用方括号呢

      • 对于多次属性来说,js是无法理解的image
    • 这是因为点符号要求key是有效的变量标识符

      • 不包含空格,不以数字开头,也不包含特殊字符允许使用($_)
    • 这时候我们就可以使用方括号

      • 方括运用我们在定义或者操作属性时更加灵活image1

    1.4 对象的练习

    • 练习一:商品对象
    • 练习二:手机对象
    • 练习三:用户对象
    
     <script>
        // 定义商品对象
        var product = {
          name: "鞋子",
          desc: "鞋子非常棒!!!",
          price: 99,
          brand: "nike"
        }
       
        // 定义手机对象
        var phone = {
          name: "iPhone 13 Pro Max",
          desc: "对iPhone的描述信息",
          price: 888,
          callPhone: function(phoneNum) {
            console.log("打电话给某人:", phoneNum)
          },
          playGame: function(gameName) {
            console.log("玩游戏:", gameName)
          }
        }
        // 定义用户对象
        var user = {
          id: 1111111,
          account: "coderwhy",
          nickname: "coderwhy",
          password: "xxx123",
          avatarURL: "图片地址",
          role: {
            id: 110,
            name: "管理员",
            createTime: "2033-03-03"
          }
        }
      </script>
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    1.5 对象的遍历

    • 对象的遍历:获取对象中所有的属性和方法
      • object.keys()方法返回一个给定对象的属性数组
    • 遍历方式一:普通for循环
    • 遍历方式二:for in 遍历方法
    • for of 默认不能遍历对象
    
      <script>
        var info = {
          name: "why",
          age: 18,
          height: 1.88
        }
        // console.log(Object.keys(info))
        // 对对象进行遍历
        // 1.普通for循环
        var infoKeys = Object.keys(info)
        for (var i = 0; i < infoKeys.length; i++) {
          var key = infoKeys[i]
          var value = info[key]
          console.log(`key: ${key}, value: ${value}`)
        }
        // 2.for..in..: 遍历对象
        for (var key in info) {
          var value = info[key]
          console.log(`key: ${key}, value: ${value}`)
        }
        // 对象不支持:  for..of..: 默认是不能遍历对象
        // for (var foo of info) {
        // }
      </script>
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    1.6 栈内存和堆内存

    • 我们知道程序是需要加载到内存中来执行的,我们可以将内存划分为两个区域:栈内存(stack)和堆内存(heap)
      • 原始类型占据的空间是在栈内存中分配的
      • 对象类型占据的空间是在堆内存中分配的

    1.7 值类型和引用类型

    • 原始类型的保存方式:在变量总保存的是值本身

      • 所以原始类似也称为值类型
    • 对象类型的保存方式:在变量总保存的是对象的引用

      • 所以对象类型也被称为引用类型image2

    1.8 思考下面的现象

    • 现象一:两个对象的比较
    • 现象二:引用传递和值传递的内存区别

    1.9 为什么需要this

    • 在常见的编程语言中,几乎都有this这个关键字(Objective-C中使用的是self),但是JavaScript中的this和常见的面向对象
      语言中的this不太一样:
      • 常见面向对象的编程语言中,比如Java、C++、Swift、Dart等等一系列语言中,this通常只会出现在类的方法中。
      • 也就是你需要有一个类,类中的方法(特别是实例方法)中,this代表的是当前调用对象;
    • 但是JavaScript中的this更加灵活,无论是它出现的位置还是它代表的含义;
    • 我们来看一下编写一个obj的对象,有this和没有this的区别:image3

    1.10 this指向什么

    • 目前掌握两个this的判断方法:
      • 在全局环境下面,this指向window;
      • **通过对象调用,this指向调用的对象;image4
        **
    • 后续我们还会学习其他,也会给大家总结this的规律;

    1.11 类和对象的思维方式

    • 我们来思考一个问题:如果需要在开发中创建一系列的相似的对象,我们应该如何操作呢?

    • 比如下面的例子:

      • 游戏中创建一系列的英雄(英雄具备的特性是相似的,比如都有名字、技能、价格,但是具体的值又不相同)
      • 学生系统中创建一系列的学生(学生都有学号、姓名、年龄等,但是具体的值又不相同)
    • 当然,一种办法是我们创建一系列的对象:image5

    • 这种方式有一个很大的弊端:创建同样的对象时,需要编写重复的代码;

      • 我们是否有可以批量创建对象,但是又让它们的属性不一样呢?

    1.12 创建对象的方案-工厂函数

    • 我们可以想到的一种创建对象的方式:工厂函数
      • 我们可以封装一个函数,这个函数用于帮助我们创建一个对象,我们只需要重复调用这个函数即可;
      • 工厂模式其实是一种常见的设计模式;但是这种方式创建的对象类型都是object类型image6

    1.13 认识构造函数

    • 工厂方法创建对象有一个比较大的问题:我们在打印对象时,对象的类型都是Object类型
      • 但是从某些角度来说,这些对象应该有一个他们共同的类型;
      • 下面我们来看一下另外一种模式:构造函数的方式;
    • 我们先理解什么是构造函数?
      • 构造函数也称之为构造器(constructor),通常是我们在创建对象时会调用的函数;
      • 在其他面向的编程语言里面,构造函数是存在于类中的一个方法,称之为构造方法;
      • 但是JavaScript中的构造函数有点不太一样,构造函数扮演了其他语言中类的角色;
    • 也就是在JavaScript中,构造函数其实就是类的扮演者:
      • 比如系统默认给我们提供的Date就是一个构造函数,也可以看成是一个类;
      • 在ES5之前,我们都是通过function来声明一个构造函数(类)的,之后通过new关键字来对其进行调用;
      • 在ES6之后,JavaScript可以像别的语言一样,通过class来声明一个类;

    1.14 类和对象的关系

    • 那么什么是类(构造函数)呢?
      • 现实生活中往往是根据一份描述/一个模板来创建一个实体对象的.
      • 编程语言也是一样, 也必须先有一份描述, 在这份描述中说明将来创建出来的对象有哪些属性(成员变量)和行为(成员方法)
    • 比如现实生活中,我们会如此来描述一些事物:
      • 比如水果fruits是一类事物的统称,苹果、橘子、葡萄等是具体的对象;
      • 比如人person是一类事物的统称,而Jim、Lucy、Lily、李雷、韩梅梅是具体的对象;

    1.15 JavaScript中的类

    • 我们前面说过,在JavaScript中类的表示形式就是构造函数。
    • JavaScript中的构造函数是怎么样的?
      • 构造函数也是一个普通的函数,从表现形式来说,和千千万万个普通的函数没有任何区别;
      • 那么如果这么一个普通的函数被使用new操作符来调用了,那么这个函数就称之为是一个构造函数;
    • 如果一个函数被使用new操作符调用了,那么它会执行如下操作:
      1. 在内存中创建一个新的对象(空对象);
      2. 这个对象内部的[[prototype]]属性会被赋值为该构造函数的prototype属性;(后面详细讲);
      3. 构造函数内部的this,会指向创建出来的新对象;
      4. 执行函数的内部代码(函数体代码);
      5. 如果构造函数没有返回非空对象,则返回创建出来的新对象;

    1.16 创建对象的方案-构造函数

    • 我们公共构造函数实现一些image7

    • 这个构造函数可以确保我们的对象都是Person的类型,一般构造函数第一个字母大写进行区别,当然不是必须的,只是为了区别于普通函数

  • 相关阅读:
    Linux——MySQL安装的几种方式
    CVE-2023-32315:Openfire管理控制台身份验证绕过到RCE的复现
    学生毕业设计选题管理系统(JSP+MySQL+Eclipse)
    从零带你底层实现unordered_map (1)
    JVM笔记
    封装适用于CentOS7的MySQL离线包
    day2_C++
    IP6510 为“快充”而生 支持PD及各种快充协议芯片多口快充解决方案
    Java单表实现评论回复功能
    主数据管理理论与实践
  • 原文地址:https://blog.csdn.net/LUFANZHENG/article/details/127407162