学习笔记整理-面向对象-03-构造函数

news2024/11/27 4:39:39

一、构造函数

1. 用new调用函数的四步走

 new 函数();
  • JS规定,使用new操作符调用函数会进行"四步走":

    • 函数体内会自动创建出一个空白对象
    • 函数的上下文(this)会指向这个对象
    • 函数体内的语句会执行
    • 函数会自动返回上下文对象,即使函数没有return语句
  • 四步走详解

      function fun() {
           this.a = 3;
           this.b = 5;
       }
       var obj = new fun();
       console.log(obj);  
    
    • 第1步:函数体内会自动创建出一个空白对象。
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xQz1dAoW-1692020300178)(https://raw.githubusercontent.com/yangdong520/drawing-bed-workspace/main/js/obj-1.png)]

    • 第2步:函数的上下文(this)会指向这个对象。
      obj-2.png

    • 第3步:执行函数体中的语句
      obj-3.png

    • 第4步:函数会自动返回上下文对象,即使函数没有return语句。
      obj-4.png

2. 构造函数

  • 用new调用一个函数,这个函数就被称为"构造函数",任何函数都可以是构造函数,只需要用new调用它。

  • 顾名思义,构造函数用来“构造新对象”,它内部的语句将 为新对象添加若干属性和方法,完成对象的初始化

  • 构造函数必须用new关键字调用,否则不能正常工作,正因 如此,开发者约定构造函数命名时首字母要大写

  • 一个函数是不是构造函数,要看它是否用new调用,而至于名称首字母大写,完全是开发者的习惯约定。

  • 如果不用new调用构造函数

      function People(name, age, sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
      } 
      People('小明', 12, '男');
      People('小红', 10, '女');
      People('小刚', 13, '男');
    
    • 结果:都会成为全局的变量,且变量的值会依次覆盖,就是小刚 13 男
  • 使用new构建

      function People(name, age, sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
      }
      var xiaoming = new People('小明', 12, '男');
      var xiaohong = new People('小红', 10, '女');
      var xiaogang = new People('小刚', 13, '男');
    
  • 为对象添加方法

      function People(name, age, sex) { 
          this.name = name;
          this.age = age;
          this.sex = sex;
          this.sayHello = function () {
              console.log('我是' + this.name + ',我' + this.age + '岁了');
          }; 
       }
      var xiaoming = new People('小明', 12, '男'); 
      var xiaohong = new People('小红', 10, '女'); 
      var xiaogang = new People('小刚', 13, '男'); 
      xiaoming.sayHello();
      xiaohong.sayHello();
      xiaogang.sayHello();    
    
  • 构造函数中的this不是函数本身

3. 类和实例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1cNSmlDn-1692020300179)(https://raw.githubusercontent.com/yangdong520/drawing-bed-workspace/main/js/obj-5.png)]

  • Java、C++等是"面向对象"(object-oriented)语言。
  • JavaScript是"基于对象"(object-based)语言。
  • JavaScript中的构造函数可以类比于OO语言中的"类", 写法的确类似,但和真正OO语言还是有本质不同
    JS和其他OO语言完全不同的、特有的原型特性。

4. prototype和原型链查找

  • 什么是prototype

    • 任何函数都有prototype属性,prototype是英语"原型"的意思。
    • prototype属性值是个对象,它默认拥有constructor属性指回函数
      obj-7
    • 普通函数来说的prototype属性没有任何用处,而构造函数的prototype属性非常有用。
    • 构造函数的prototype属性是它的实例的原型
  • 构造函数的prototype是实例的原型
    obj-8

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <script>
            function People(name, age, sex) {
                this.name = name;
                this.age = age;
                this.sex = sex;
            }
            // 实例化
            var xiaoming = new People('小明', 12, '男');
            // 测试三角关系是否存在
            console.log(xiaoming.__proto__ === People.prototype);
        </script>
    </body>
    </html>
    
  • 原型链查找

    • 每个对象都可以有一个原型_proto_,这个原型还可以有它自己的原型,以此类推,形成一个原型链。
      查找特定属性的时候,先去这个对象里去找,如果没有的话就去它的原型对象里面去,如果还是没有的话再去向原型对象的原型对象里去寻找…
      这个操作被委托在整个原型链上,这个就是我们说的原型链了。

    • JavaScript规定:实例可以打点访问它的原型的属性和方法,这被称为"原型链查找"。

          function People(name, age, sex) {
            this.name = name;
            this.age = age;
            this.sex = sex;
          }
          People.prototype.nationality = '中国';
          var xiaoming = new People('小明', 12, '男');
          console.log(xiaoming.nationality);
      
      • People.prototype.nationality在构造函数的prototype上添加nationality属性。
      • xiaoming.nationality实例可以打点访问原型的属性和方法。
        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-19GzAMjt-1692020300180)(https://raw.githubusercontent.com/yangdong520/drawing-bed-workspace/main/js/obj-9.png)]
    • 原型的遮蔽效应

          function People(name, age, sex) {
          this.name = name;
          this.age = age;
          this.sex = sex;
      }
      // 往原型上添加nationality属性
      People.prototype.nationality = '中国';
      
      // 实例化
      var xiaoming = new People('小明', 12, '男');
      var tom = new People('汤姆', 10, '男');
      tom.nationality = '美国';
      
      console.log(xiaoming.nationality);      // 中国
      console.log(xiaoming);
      
      console.log(tom.nationality);           // 美国
      //tom本身有nationality时,就不找原型上的nationality属性了,原型链的遮蔽效应
      //跟局部变量全局变量差不多
      

      obj-10

    • hasOwnProperty方法可以检查对象是否真正"自己拥有"某属性或者方法。

          xiaoming.hasOwnProperty('name'); // true
          xiaoming.hasOwnProperty('age');  // true
          xiaoming.hasOwnProperty('sex');  // true
          xiaoming.hasOwnProperty('nationality'); // false
      
    • in运算符只能检查某个属性或方法是否可以被对象访问,不能检查是否是自己的属性或方法。

          'name' in xiaoming  // true
          'age' in xiaoming   // true
          'sex' in xiaoming   // true
          'nationality' in xiaoming  // true
      
      

5. 在prototype上添加方法

  • 把方法直接添加到实例身上的缺点:每个实例和每个实例的方法函数都是内存中不同的函数,造成了内存的浪费
  • 解决方法:将方法写到prototype上
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KfgSpKFg-1692020300180)(https://raw.githubusercontent.com/yangdong520/drawing-bed-workspace/main/js/obj-11.png)]

6. 原型链的终点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YC2Sl5h4-1692020300180)(https://raw.githubusercontent.com/yangdong520/drawing-bed-workspace/main/js/obj-12.png)]

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        function People(name, age) {
            this.name = name;
            this.age = age;
        }
        var xiaoming = new People('小明', 12);

        console.log(xiaoming.__proto__.__proto__ === Object.prototype);     // true
        console.log(Object.prototype.__proto__);                            // null

        console.log(Object.prototype.hasOwnProperty('hasOwnProperty'));     // true
        console.log(Object.prototype.hasOwnProperty('toString'));           // true
    </script>
</body>
</html>

  • 关于数组的原型链
    array

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <script>
            var arr = [344, 45, 34, 23];
    
            console.log(arr.__proto__ === Array.prototype);                 // true
            console.log(arr.__proto__.__proto__ === Object.prototype);      // true
            console.log(Array.prototype.hasOwnProperty('push'));            // true
            console.log(Array.prototype.hasOwnProperty('splice'));          // true
        </script>
    </body>
    </html>
    

6. 继承

  • JavaScript中如何实现继承?

    • 实现继承的关键在于:子类必须拥有父类的全部属性和方法,同时子类还应该能定义自己特有的属性和方法。
    • 使用JavaScript特有的原型链特性来实现继承,是普遍的做法
  • 通过原型链实现继承
    array
    array

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    
    <body>
        <script>
            // 父类,人类
            function People(name, age, sex) {
                this.name = name;
                this.age = age;
                this.sex = sex;
            }
            People.prototype.sayHello = function () {
                console.log('你好,我是' + this.name + '我今年' + this.age + '岁了');
            };
            People.prototype.sleep = function () {
                console.log(this.name + '开始睡觉,zzzzz');
            };
    
            // 子类,学生类
            function Student(name, age, sex, scholl, studentNumber) {
                this.name = name;
                this.age = age;
                this.sex = sex;
                this.scholl = scholl;
                this.studentNumber = studentNumber;
            }
            // 关键语句,实现继承
            Student.prototype = new People();
    
            Student.prototype.study = function () {
                console.log(this.name + '正在学习');
            }
            Student.prototype.exam = function () {
                console.log(this.name + '正在考试,加油!');
            }
            // 重写、复写(override)父类的sayHello
            Student.prototype.sayHello = function () {
                console.log('敬礼!我是' + this.name + '我今年' + this.age + '岁了');
            }
    
            // 实例化
            var hanmeimei = new Student('韩梅梅', 9, '女', '慕课小学', 100556);
    
            hanmeimei.study();
            hanmeimei.sayHello();
            hanmeimei.sleep();
    
            var laozhang = new People('老张', 66, '男');
            laozhang.sayHello();
        </script>
    </body>
    
    </html>
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/877561.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

事件过滤器(eventfilter)的说明与使用

事件过滤器可以在不定义一个新的类的情况下&#xff0c;对界面组件的事件进行处理。事件过滤器通过将一个对象的事件委托给另一个对象来监视并进行处理&#xff1b;如一个窗口可以作为其界面上的QLabel组件的事件过滤器&#xff0c;派发给QLabel组建的事件由窗口去处理&#xf…

Blender 混合现实3D模型制作指南【XR】

本教程分步展示如何&#xff1a; 减少 3D 模型的多边形数量&#xff0c;使其满足 Microsoft Dynamics 365 Guides 和使用 Microsoft Power Apps 创建的应用程序中包含的混合现实组件的特定性能目标的性能需求。将 3D 模型的多种材质&#xff08;颜色&#xff09;组合成可应用于…

matplotlib绘制位置-时序甘特图

文章目录 1 前言2 知识点2.1 matplotlib.pyplot.barh2.2 matplotlib.legend的handles参数 3 代码实现4 绘制效果5 总结参考 1 前言 这篇文章的目的是&#xff0c;总结记录一次使用matplotlib绘制时序甘特图的经历。之所以要绘制这个时序甘特图&#xff0c;是因为22年数模研赛C…

关于consul的下载方法

linux下 sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo sudo yum -y install consulwindow下 https://developer.hashicorp.com/consul/downloads 然后把里面的exe文件放在gopath下就行了 验证…

手机照片误删怎么办,电脑照片误删怎么办怎么才能找回,EasyRecovery来帮您

手机照片误删怎么办&#xff0c;电脑照片误删怎么办怎么才能找回&#xff0c;EasyRecovery 2023来帮您&#xff01;&#xff01;&#xff01; EasyRecovery 2023是一款操作安全、价格便宜、用户自主操作的 数据恢复 方案&#xff0c;它支持从各种各样的 存储介质 恢复删除 或者…

12 注册登录

12 注册登录 整体概述 使用数据库连接池实现服务器访问数据库的功能&#xff0c;使用POST请求完成注册和登录的校验工作。 本文内容 介绍同步实现注册登录功能&#xff0c;具体涉及到流程图、载入数据库表、提取用户名和密码、注册登录流程与页面跳转的代码实现。 流程图&a…

加了ComponentScan,但是feign接口无法注入的原因

正文 正确的注入 如果发现无法注入&#xff1a;看看启动类Application是否有加入注解&#xff1a;EnableFeignClients(AppConstant.BASE_PACKAGES) 注意&#xff1a;EnableFeignClients和ComponentScan是两个独立的扫描&#xff0c;所以&#xff0c;如果只配置了ComponentSca…

FPGA控制RGB灯WS2812B

文章目录 FPGA控制RGB灯WS2812B1、简介1.1水一水1.2程序完成目标1.3项目工程结构 2、代码3、仿真代码4、结果展示 FPGA控制RGB灯WS2812B 1、简介 1.1水一水 最近在学习WS2812B手册&#xff0c;是一个简单的协议编写&#xff0c;做的时间也算是比较久&#xff0c;相对做出了一…

00-认识C++

2、认识C 2.1、例子 一个简单的C例子 #include <iostream>int main() {using namespace std; //使用名称空间cout << "Com up and C me some time.";cout << endl; //换行符&#xff0c;还可以cout<<"\n";cout <…

【JAVA】集合(Collection、Map)

集合和数组都是容器 数组&#xff1a;类型确定&#xff0c;长度固定&#xff0c;可以存储基本类型和引用类型的数据 集合&#xff1a;类型可以不固定&#xff0c;大小可变&#xff0c;只能存储引用数据类型的数据 Collection单列单列集合&#xff0c;每个元素只包含一个值Ma…

伴随矩阵的特征值跟原矩阵特征值居然有关系!!!附证明

文章目录 论点&#xff1a;A与其伴随矩阵的特征值相乘等于|A|证明证明证明中涉及的相关定理&#xff1a;1.逆矩阵与伴随矩阵的关系2.A可逆时&#xff0c;A的逆矩阵的特征值是原矩阵特征值的倒数 论点&#xff1a;A与其伴随矩阵的特征值相乘等于|A| 证明 证明 证明中涉及的相关…

html css实现爱心

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><style>/* 爱心 */.lo…

基于Matlab实现小偷体貌识别仿真(附上源码+数据集)

小偷体貌识别是一种应用于安全领域的重要技术&#xff0c;它利用计算机视觉和机器学习的方法&#xff0c;通过对监控视频中的人体特征进行提取和分析&#xff0c;来识别出可能的小偷。在本文中&#xff0c;我们将介绍如何使用Matlab实现小偷体貌识别的仿真。 文章目录 介绍部分…

测牛学堂:软件测试工程师都要懂的软件开发模型总结

软件开发模型之快速原型 之前跟大家介绍了最早期的瀑布模型。今天聊一下快速原型模型。 快速原型&#xff0c;在初步确定用户需求之后&#xff0c;快速构造出一个原型项目&#xff0c;可以跟用户展示软件的功能&#xff0c;用户根据原型进行评审&#xff0c;提出更进一步的细…

JavaWeb-Servlet服务连接器(终)

上一篇文章JavaWeb-Servlet服务连接器&#xff08;三&#xff09;_Alphamilk的博客-CSDN博客 目录 1.ServletContext通信 会话技术Cookie与Session 1.Cookie 2.Session 1.ServletContext通信 概念&#xff1a;代表了整个web应用&#xff0c;用于与服务器实现通信 可以通…

6.2 口令破解攻击

数据参考&#xff1a;CISP官方 目录 口令安全问题口令破解攻击口令破解安全防护口令使用安全管理 一、口令安全问题 什么是口令 身份验证的机制&#xff0c;俗称 “密码"&#xff0c;对应英文单词为 password成本较低&#xff0c;得到广泛应用信息安全中的 “密码”…

基于 Nginx All In One 的 Outline Wiki 部署方法

1. Outline 简介 官网&#xff1a;https://www.getoutline.com/ Outline 是一个开源的知识库和团队协作工具&#x1f9e0;&#xff0c;旨在帮助团队共享、组织和协作文档&#x1f4dd;。它提供了一个简洁的界面&#xff0c;使用户能够轻松创建、编辑和查看文档。 以下是 Out…

sudo免密码设置以及设置失败解决方法

使用sudo visudo修改\etc\sudoers文件 打开后有很多已有的设置大致格式username ALL(ALL:ALL) ALL&#xff0c;都不要动&#xff01; 在文件结尾加上一句话&#xff1a; username ALL(ALL:ALL) NOPASSWD: ALLusername就是目前你这个账户的名字&#xff0c;开机时会输密码登录…

Nginx访问日志及巡检统计

一、前言 二、词汇解释 2.1、pv和uv的区别 PV&#xff08;Page View访问量/也卖弄浏览数&#xff09;&#xff1a;指在一定统计周期内&#xff0c;用户每次刷新网页一次即计算一次。PV高不一定代表来访者多:PV与来访者的数量成正比&#xff0c;但是PV并不直接决定页面的真实来…

同样的字符串,有一些事长度为3,有一些长度为2,导致Convert.ToByte(macStringArray[i], 16);出错

同样的字符串&#xff0c;有一些事长度为3&#xff0c;有一些长度为2,导致Convert.ToByte(macStringArray[i], 16);出错。 最后&#xff0c;把长度为2的复制过去&#xff0c;就好了。 要复制“1C- 只复制1C不行 { “pc101”:“1C-69-7A-BD-05-C4”, “pc102”:“1C-69-7A-BD…