【JavaScript】原型链 prototype 和 this 关键字的练习(老虎机)

这个老虎机练习主要考察JavaScript中的原型链(prototype)和this关键字的使用。


主要思路

  1. 创建三个轮盘(reels)实例:我们需要创建3个独立的轮盘对象,它们都委托(delegate)到基础的reel对象。这可以通过Object.create(reel)来实现,创建新对象并将其原型指向reel

  2. 实现display()方法:这是最复杂的部分,需要显示3×3的网格:

    • 每个轮盘需要显示三个位置:当前位置、上方位置和下方位置
    • 行显示(水平方向):以"|"分隔的三个轮盘符号
    • 列显示(垂直方向):每个轮盘的三个位置(上中下)

实现代码

function randMax(max) {return Math.trunc(1E9 * Math.random()) % max;
}var reel = {symbols: ["♠", "♥", "♦", "♣", "☺", "★", "☾", "☀"],spin() {if (this.position == null) {this.position = randMax(this.symbols.length); }this.position = (this.position + 100 + randMax(100)) % this.symbols.length;},display() {if (this.position == null) {this.position = randMax(this.symbols.length);}return this.symbols[this.position];}
};var slotMachine = {reels: [Object.create(reel),Object.create(reel),Object.create(reel)],spin() {this.reels.forEach(reel => {reel.spin();});},display() {// 获取每个轮盘上方、当前和下方的符号var lines = [];// 创建三行(上、中、下)for (let linePos = -1; linePos <= 1; linePos++) {let line = this.reels.map(reel => {// 创建一个临时对象,委托到reel,但拥有自己的positionvar slot = Object.create(reel);// 调整position以显示上方/当前/下方的符号slot.position = ((reel.position + linePos) + reel.symbols.length) % reel.symbols.length;return slot.display();});lines.push(line.join(" | "));}// 打印结果console.log(lines.join("\n"));}
};slotMachine.spin();
slotMachine.display();slotMachine.spin();
slotMachine.display();

代码解析

  • 循环创建三行:使用-101作为偏移量,分别表示上、中、下行

  • 显示每个位置的符号

    • 为每个位置创建一个临时对象(使用Object.create(reel)
    • 调整临时对象的position属性,考虑到循环(使用模运算)
    • 调用临时对象的display()方法获取符号
  • 处理循环边界问题:当计算上方位置(特别是当前位置为0时),需要加上reel.symbols.length来确保结果为正,然后再取模

  • 格式化输出:组合所有符号,map生成的行数组用"|“分隔转换成字符串后加入lines数组,lines数组用换行符”\n"分隔转换成字符串。

  • spin()方法有两个主要作用:

    1. 初始化位置:如果轮盘的position属性为null(比如第一次使用时),它会为轮盘设置一个初始随机位置。

    2. 改变轮盘位置:每次调用spin()都会使轮盘旋转一定数量的位置(至少100个位置加上0-99的随机数),然后通过取模确保最终位置在有效范围内。

      在示例代码中:

      slotMachine.spin();
      slotMachine.display();
      // 显示第一组结果slotMachine.spin();
      slotMachine.display();
      // 显示第二组结果
      

      两次结果不同,正是因为中间调用了spin()方法,改变了每个轮盘的位置。如果删除第二个spin()调用,两次display()会显示完全相同的结果。

      所以spin()方法是整个老虎机机制的核心部分之一,它模拟了真实老虎机拉杆后轮盘旋转的过程,而这个旋转直接决定了最终显示的符号组合。

  • reel原型对象

    1. reels数组中的对象

      reels: [Object.create(reel),Object.create(reel),Object.create(reel)
      ]
      

      这里创建了三个独立的对象,每个都作为slotMachine的一个轮盘。这些对象在整个slotMachine的生命周期中持续存在,并且每个都维护自己的position属性状态。当我们调用slotMachine.spin()时,这三个对象的position属性会被更新。

    2. display()方法中的临时对象

      var slot = Object.create(reel); // 这个是个临时对象,不是reels中的元素
      

      这是在display()方法内部创建的临时对象,它在每次显示时创建,用完即丢弃。这个临时对象不是用来替代轮盘的,而是用来临时保存修改后的位置,以便显示上方或下方的符号,而不影响原始轮盘的position属性

      理解这一点很关键:slot是通过原型链委托到reel对象的,而reels数组中的每个元素是通过原型链委托到同一个reel对象的独立对象。

      因此,它们在内存中是完全不同的对象,只是共享相同的原型。这种结构让我们能够在不改变原始轮盘位置的情况下,显示每个轮盘的上方、当前和下方位置的符号。

  • 理解参数reel的来源:

    1. this.reels.map(function getSlot(reel){...}) 中的reel参数是map方法传入的,它代表的是this.reels数组中的每个元素,也就是我们在slotMachine初始化时创建的那三个轮盘对象。

    2. 然后,我们基于这个轮盘对象创建一个临时对象:var slot = Object.create(reel),这个临时对象的原型是当前遍历到的轮盘对象,而不是原始的reel对象。

    3. 这样,我们可以通过reel.position访问到当前轮盘的位置,并在临时对象中设置调整后的位置:slot.position = ...

    简单来说,这里存在三层委托关系:

    • slot对象委托到reels数组中的特定轮盘对象
    • 那个轮盘对象又委托到原始的reel对象
    • 当我们调用slot.display()时,会使用slot自己的position,但方法本身是从reel原型继承的

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

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

相关文章

vue项目data functions should return an object

在vue项目中提示错误&#xff0c;data functions should return an object Message.error(err)错了&#xff0c;Message.error()是element-ui的组件&#xff0c;只能接受字符串&#xff0c;不能接受对象。 改为Message.error(err.message)就好了 我的错误是 Message.error(er…

leetcode刷题 - 数组理论基础

数组是内存空间连续存储、相同类型数据的集合。遍历方式&#xff1a;下标索引 下标&#xff1a;从 0 开始 数组的元素不能删除&#xff0c;只能覆盖 定义一维数组&#xff1a; int arr0[10]; int arr1[10] { 100, 90,80,70,60,50,40,30,20,10 }; int arr2[ ] { 100,90,80,7…

状态机思想编程练习

状态机实现LED流水灯 本次实验&#xff0c;我们将利用状态机的思想来进行Verilog编程实现一个LED流水灯&#xff0c;并通过Modelsim来进行模拟仿真&#xff0c;再到DE2-115开发板上进行验证。 ​ 首先进行主要代码的编写。 module led (input sys_clk,input sys_…

数据结构|排序算法(一)快速排序

一、排序概念 排序是数据结构中的一个重要概念&#xff0c;它是指将一组数据元素按照特定的顺序进行排列的过程&#xff0c;默认是从小到大排序。 常见的八大排序算法&#xff1a; 插入排序、希尔排序、冒泡排序、快速排序、选择排序、堆排序、归并排序、基数排序 二、快速…

如何确保MQ消息队列不丢失:Java实现与流程分析

前言 在分布式系统中&#xff0c;消息队列&#xff08;Message Queue, MQ&#xff09;是核心组件之一&#xff0c;用于解耦系统、异步处理和削峰填谷。然而&#xff0c;消息的可靠性传递是使用MQ时需要重点考虑的问题。如果消息在传输过程中丢失&#xff0c;可能会导致数据不一…

关于termux运行pc交叉编译的aarch64 elf的问题

在Linux系统上交叉编译Nim程序到Android Termux环境需要特殊处理&#xff0c;以下是详细的解决方案&#xff1a; 问题根源分析 ​​ABI不兼容​​ Android使用bionic libc而非标准glibc&#xff0c;直接编译的Linux ARM二进制无法直接运行 ​​动态链接错误​​ 默认编译会链…

为PXIe控制器配置NI Linux实时操作系统安装软件

一、升级BIOS 使用NI Linux Real-Time操作系统的PXI硬件支持页面来确定NI Linux Real-Time是否支持您的PXIe控制器&#xff0c;以及是否需要更新控制器BIOS。 按照BIOS下载页面上的“安装说明”部分安装BIOS更新。 注意&#xff1a;NI在NI 2020软件版本中删除对cRIO的Phar Lap和…

《汽车噪声控制》课程作业

作业内容 在MATLAB绘制给出单个正弦波或余弦波的时域图和频域图 绘制实测数据的时域图和频域图 图1 单个正弦波的时频图 图1 单个正弦波的时频图 % 正弦波参数设置 f0 1000; % 信号频率 1kHz Fs 16384; % 采样频率 16kHz T 0.05; % 信号持续时间 0.05秒 A 0.8; % 信号幅度…

Baklib内容中台AI技术协同应用

内容中台与AI协同创新 在数字化转型进程中&#xff0c;内容中台通过人工智能技术的深度整合&#xff0c;正重塑企业信息管理范式。以Baklib内容中台为例&#xff0c;其通过智能语义分析引擎解析用户意图&#xff0c;结合知识图谱构建技术动态关联碎片化信息&#xff0c;实现从…

压测工具开发实战篇(二)——构建侧边栏以及设置图标字体

你好&#xff0c;我是安然无虞。 文章目录 构建侧边栏QtAwesome使用调整侧边栏宽度了解: sizePolicy属性伪状态 在阅读本文之前, 有需要的老铁可以先回顾一下上篇文章: 压测工具开发(一)——使用Qt Designer构建简单界面 构建侧边栏 我们要实现类似于下面这样的侧边栏功能: …

Axure RP9.0教程: 查询条件隐藏与显示(综合了动态面板状态切换及展开收缩效果实现)

文章目录 引言I 原型显示/隐藏搜索框思路步骤详细操作II 若依 ruoyi 显示/隐藏搜索框 & 显示隐藏列自定义设置显示隐藏列显示/隐藏搜索框引言 数据筛选有大量的查询条件时,可以选择查询隐藏效果。 I 原型显示/隐藏搜索框 综合了动态面板状态切换及展开收缩效果实现 思…

解锁工业通信:Profibus DP到ModbusTCP网关指南!

解锁工业通信&#xff1a;Profibus DP到ModbusTCP网关指南&#xff01; 在工业自动化领域&#xff0c;随着技术的不断进步和应用场景的日益复杂&#xff0c;不同设备和系统之间的通讯协议兼容性问题成为了工程师们面临的一大挑战。尤其是在Profibus DP和Modbus/TCP这两种广泛应…

3维格式转换(二)

基于python的三维模型演化可视化 本项目的主要内容为总结了3种不同的可视化方案( trimesh + matplotlib 库、 pyvista 库、 vedo 库),并通过案例对可视化效果进行展示,最终通过模型动态演化案例给出最佳效果的可视化方案 本期结构图为 本期博客结构图 0 环境搭建 项目开…

docker导出image再导入到其它docker中

导出image docker save -o gxc_tenant.tar vue_tenant:1.0 eitc_tenant:1.0 redis:latest docker.io/mysql:8.0 minio/minio导入image docker load -i gxc_tenant.tar

Spring-IOC部分

Spring-IOC部分 1.SpringBean的配置详解&#xff08;Bean标签&#xff09; &#xff08;1&#xff09;scope 默认情况下&#xff0c;单纯的Spring环境Bean的作用范围有两个&#xff1a;Singleton和Prototype singleton&#xff1a;单例&#xff0c;默认值&#xff0c;Spring…

人工智能爬虫导致维基共享资源带宽需求激增 50%

2025 年 4 月 1 日&#xff0c;维基媒体基金会在博文中表示&#xff0c;自 2024 年 1 月以来&#xff0c;维基共享资源下载多媒体的带宽消耗激增 50%&#xff0c;这一变化趋势主要由用于 AI 训练数据集的网络爬虫导致。以下是具体分析1&#xff1a; 爬虫流量特征与数据存储模式…

2007-2019年各省地方财政交通运输支出数据

2007-2019年各省地方财政交通运输支出数据 1、时间&#xff1a;2007-2019年 2、来源&#xff1a;国家统计局、统计年鉴 3、指标&#xff1a;行政区划代码、地区、年份、地方财政交通运输支出 4、范围&#xff1a;31省 5、指标说明&#xff1a;地方财政交通运输支出是指地方…

【爬虫开发】爬虫开发从0到1全知识教程第14篇:scrapy爬虫框架,介绍【附代码文档】

本教程的知识点为&#xff1a;爬虫概要 爬虫基础 爬虫概述 知识点&#xff1a; 1. 爬虫的概念 requests模块 requests模块 知识点&#xff1a; 1. requests模块介绍 1.1 requests模块的作用&#xff1a; 数据提取概要 数据提取概述 知识点 1. 响应内容的分类 知识点&#xff1a…

【CMake】《CMake构建实战:项目开发卷》笔记-Chapter8-生成器表达式

第8章 生成器表达式 生成器表达式&#xff08;generator expression&#xff09;是由CMake生成器进行解析的表达式&#xff0c;因此&#xff0c;这些表达式只有在CMake的生成阶段才被解析为具体的值。 CMake在生成阶段&#xff0c;能够根据具体选用的构建系统生成器生成特定…

Docker安装、配置Mysql5.7

1.创建必要的目录 # 创建目录 mkdir -p ~/docker/software/mysql/{conf,log,data} 2.如果没有docker-compose.yml文件的话&#xff0c;先创建docker-compose.yml 配置文件一般长这个样子 version: 3services:mysql:image: mysql:5.7.36container_name: mysqlports:- "…