Building JavaScript Games for Phones Tablets and Desktop(3)-创造一个游戏世界

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

创造一个游戏世界

这章教会你如何通过内存中储存的信息创造一个游戏世界。介绍了基本类型和变量并且这些变量是如何储存和改变信息的。接下来,你会看到如何用对象储存更复杂的信息,里面包含成员变量和方法。

基本类型和变量

先前的章节几次讨论到了内存。你已经看到了如何执行一个简单的指令譬如canvasContext.fillStyle = “blue”;为画布设置一个颜色。在这章例子里,你使用内存储存临时信息,是为了记住一些简单运算的结果。在这个例子里,你使用经过的时间来改变背景色。

类型

类型,或者数据类型,代表不同类型的信息。先前的例子使用了不同类型的信息,当做参数传递给了函数。例如,fillRect函数,需要4个整数,start函数需要一个文本标识引用自canvas,update和draw函数不需要任何信息。浏览器/解释器可以区分这些不同类型的信息并且很多情况下可以把一个类型的信息转换成另一个类型的信息。比如,在JavaScript里,你可以使用单引号或者双引号来标识文本。如下的两句指令是一样的:

canvas = document.getElementById("myCanvas");
canvas = document.getElementById('myCanvas');

浏览器可以自动的在不同类型的信息间进行转换。比如,下面的语句不会导致语法错误:

canvas = document.getElementById(12);

这个当做参数传递的整数会被转换成文本。在这种情况下,当然,这里没有ID叫做12的canvas,所以这个程序是不正确的。如果你像下面一样替换canvas的ID,程序就会正常运行:

<canvas id="12" width="800" height="480"></canvas>

浏览器自动的在文本和数字之间进行转换。

现代编程语言都比JavaScript严格的多。比如Java和C#,不同类型之间转换是有限制的。大多时候,你必须明确的告诉编译器这里有一个类型转换。

为什么对类型转换需要这么严格的限制呢?首先,一个函数或方法中明确的类型参数可以让程序员简单的使用函数。比如下面这样:

function playAudio (audioFileId)

简单的看一下,你并不确定audioFileId是一个数字还是文本。在C#里,这个函数会类似这样:

void playAudio(string audioFileId)

可以看出,不仅有参数名,而且还附有参数类型。类型是string,也就是字符串。此外,在函数名前面还有void这个单词,表示这个函数没有返回值。

声明和变量赋值

在JavaScript里面储存信息和使用信息都是很简单的。你需要做的只是为你要引用的信息提供一个名字。这个名字就叫做变量。当你想在程序里使用变量时,在使用之前声明它是一个好习惯。下面是如何声明一个变量:

var red;

在这里,red就是变量名。你可以在你随后的程序用它储存信息。

当你声明了一个变量,你不需要提供你需要储存信息的类型。变量仅仅是内存里有一个名字。有些编程语言要求在变量声明时确定变量的类型。比如在Java或者C++里。然而,很多的脚本语言(包括JavaScript)允许你声明一个变量而不需要指定其类型。当编程语言声明变量时不要指定类型,这个编程语言就有松散类型。在JavaScript里,你可以声明不止一个变量,比如:

var red, green, fridge, grandMa, applePie;

这里你声明了5个不同的变量。当你声明这些变量时,你没有赋值。在这种情况下,变量是未定义的。你可以用赋值指令为变量赋值。比如,给red赋值:

red = 3;

赋值指令包含下面这些:

  • 变量名
  • ”=“符号
  • 变量值
  • 一个分号

你可以发现赋值指令中间有个等号。然而,在JavaScript里,最好把”=“看成”变为“而不是”等于“。毕竟,变量还没有等于右边的值,它在指令执行之后才变成那个值。下面的语法图描述了赋值指令。(图3-1)

(省略图3-1)

现在知道如何声明一个变量和给变量赋值了。如果你在声明变量时就知道给变量赋什么值,你可以声明的同时进行赋值。比如:

var red = 3;

当执行这句后,内存中就会有3这个值,如图3-2所示。

(省略图3-2)

这里有更多关于数值变量的声明和赋值:

var age = 16;
var numberOfBananas;
numberOfBananas = 2;
var a, b;
a = 4;
var c = 4, d = 15, e = -3;
c = d;
numberOfBananas = age + 12;

在第四行,你可以发现一次可以声明多个变量。也可以像第六行一样有多个变量进行了声明赋值。在赋值的右边,你可以放置其它变量或者数学表达式,正如最后两行所示。指令 c = d;让储存在d中的值也储存在了c里面。因为d是15,所以执行这条指令后,c也是15.最后一条指令让age加上12,把结果储存在numberOfBananas里面。概括来说,执行这些指令后,这些内存值看起来就像图3-3所示:

(省略图3-3)

全局变量和严格模式

除了在使用变量之前进行声明,javascript也可以直接使用变量而不用声明它。比如下面这样:

var a = 3;
var b;
b = 4;
x = a + b;

如上所示,前两行指令通过var关键字声明了变量a和b。变量x从来没有声明,但是它用来储存a和b的和。javascript允许这样。这很糟糕,而且这也是它为什么糟糕的原因。问题在于没有声明的变量javascript解释器会自动的把它进行声明,而你却完全不知道。如果你在其它地方使用同样名字的变量,你的程序可能发生你意想不到的结果。另外,如果你使用了很多不同的变量,你最好同时记录这些变量。但是最大的问题是下面这个:

var myDaughtersAge = 12;
var myAge = 36;
var ourAgeDifference = myAge - mydaughtersAge;

当编写这些指令时,你希望的是ourAgeDifference的值是24.但是,这个值是未定义的。这是因为第三行这里有个打字错误。变量的名字不是mydaughtersAge,而是myDaughtersAge。这种情况下,浏览器/解释器是悄悄的声明一个叫做mydaughtersAge的变量而不是抛出一个错误停止运行脚本。因为变量没有定义,所有与此变量有关的计算都是未定义的。因此,变量ourAgeDifference也是未定义的。

这个问题真的很棘手。幸运的是,新的EMCAScript5标准有个叫做严格模式的东西。当脚本用严格模式来解释时,它不允许在没有声明变量之前使用变量。如果你想你的脚本在严格模式下执行,你需要做的仅仅只是在脚本开始加上下面这行,例如:

"use strict";
var myDaughtersAge = 12;
var myAge = 36;
var ourAgeDifference = myAge - mydaughtersAge;

“use strict”告诉了解释器在严格模式下解释脚本。如果你现在执行这段代码,浏览器会停止运行且抛出错误告知有变量没有进行声明。

除了能检查变量在使用之前是否声明了,严格模式也包含了其他一些能让书写正确javascript代码更简单的东西。

我非常推荐你在严格模式下书写你所有的javascript代码。所以本书的所有javascript代码都是严格模式下书写的,这能帮程序员省掉很多麻烦且这样的代码在未来版本的javascript也是无可挑剔的。

指令和表达式

如果你看到语法图里面的元素,你可能已经注意到一些在赋值语句右边的值或者程序片段,它们被叫做表达式。那么表达式和指令有什么不同呢?两者不同的是指令某种方式上改变内存,而表达式有一个值。指令通常使用表达式。这里有几个表达式的例子:

16
numberOfBananas
2
a + 4
numberOfBananas + 12 - a
-3
"myCanvas"

所有的这些表达式代表了一个确定的类型。除了最后一行,所有的表达式都是数值。最后一行是字符串。除了数值和字符串,还有其他类型的表达式。我讨论的是本书最重要的表达式。比如,下节我会讨论运算符的表达式,第7章会讲使用函数或者方法作为一个表达式。

运算符和更复杂的表达式

这节讨论javascript中不同的运算符。你会了解到运算符的优先级。你也可以了解到有些时候,在javascript中表达式也能相当的复杂。比如,一个变量可以包含多个值,或者可以代表一个函数。

算术运算符

(省略)

运算符优先级

(省略)

把一个函数赋值给变量

在javascript中,函数被储存在内存里。正因为如此,函数也是表达式。所以,可以给一个变量赋值为函数。例如:

var someFunction = function () {
// do something
}

这个例子声明了一个变量并进行了赋值。这个变量的值是一个无名函数。如果你想执行这个函数,你可以通过变量名字调用,如下:

someFunction();

那么像下面这样定义一个函数和你之前看到的有什么不同呢?

function someFunction () {
// do something
}

实际上,这并没有什么不同。主要是如果不像传统方式那样定义一个函数,那么这个函数在定义之前不能使用。当浏览器执行一个javascript文件,有两个步骤。第一个步骤,浏览器构造一个函数的列表。第二步,浏览器解释剩下的脚本。这对正确执行脚本很有必要,浏览器需要知道哪个函数是有效的。比如,下面的这段代码可以运行,即使这个在后面被定义:

someFunction();
function someFunction () {
// do something
}

然而,如果一个函数被赋值给一个变量,那么就只剩上述的第二步了。意味着下面的代码会报错。

someFunction();
var someFunction = function () {
// do something
}

浏览器会告知有一个变量没有进行声明。在定义之后进行调用就可以了,比如:

someFunction();
var someFunction = function () {
// do something
}

多个值组成的变量

一个变量可以由多个值组成而不是只能单一值。这就像函数里面做的一样,把指令组合在一起。比如:

function mainLoop () {
canvasContext.fillStyle = "blue";
canvasContext.fillRect(0, 0, canvas.width, canvas.height);
update();
draw();
window.setTimeout(mainLoop, 1000 / 60);
}

跟函数一样,你可以把一些变量放在一个更大的变量里面。这个更大的变量就有了更多的值。就像下面这个例子:

var gameCharacter = {
name : "Merlin",
skill : "Magician",
health : 100,
power : 230
};

这是一个复合变量的例子。变量gameCharacter有一些变量。这些变量有名字和值。因此,在某种意义上说,变量gameCharacter由其它一些变量组成。每个子变量都有一个名字,冒号后面是值。这个包含名字的表达式和花括号之间的值被叫做对象字变量。图3-6显示了对象字变量的的语法图:

(省略图3-6)

在声明和实例化变量gameCharacter之后,这块内存看起来如图3-7:

(省略3-7)

你可以像下面这样获取一个复合变量的值。

gameCharacter.name = "Arjan";
var damage = gameCharacter.power * 10;

正如你看到的那样,你可以获取gameCharacter变量中的某个变量,通过在gameCharacter后面加上一个点和子变量名。javascript甚至允许在声明和实例化复合变量后修改这个复合变量的值。举个例子,看下面这段代码:

var anotherGameCharacter = {
name : "Arthur",
skill : "King",
health : 25,
power : 35000
};anotherGameCharacter.familyName = "Pendragon";

现在anotherGameCharacter有5部分了,name, skill, health, power, familyName。

因为变量也可以指向函数,所以你可以包含一个指向函数的子变量。如下所示:

var anotherGameCharacter = {
name : "Arthur",
familyName : "Pendragon",
skill : "King",
health : 25,
power : 35000,
healMe : function () {
anotherGameCharacter.health = 100;
}
};

像之前一样,你可以在这之后也能为其子变量添加一个函数。

anotherGameCharacter.killMe = function () {
anotherGameCharacter.health = 0;
};

你可以调用其他变量一样调用这些函数。下面的指令恢复了游戏角色的生命:

anotherGameCharacter.healMe();

如果你想杀死角色,可以调用anotherGameCharacter.killMe();组合变量和函数最棒的地方在于你可以把相关的变量和函数放在一起。这个例子就是把与同一个游戏角色相关的变量放在了一起,同时增加了几个相关的函数。从现在开始,如果一个函数属于一个变量,我把这个函数叫做方法。把一个由其他变量组成的变量叫做对象。如果一个变量是对象的一部分,这个变量叫做成员变量。

你可以想象对象和方法的能量有多强大。它们提供了一个进入复杂游戏世界的方式。如果javascript没有这种能力,那么在程序的开头,你会声明一长串的变量,并且不知道这些变量之间如何相关且能做什么。把变量装进对象里且给对象提供方法,你可以写出更容易理解的程序。在下节,你就要使用这种强大的能力来写一个简单的移动方块程序。

方块移动游戏

这节实现了一个方块在画布上移动的简单程序。主要有两个目的:

  • 关于游戏循环里Update和draw函数的更多细节
  • 如何使用对象来结构化程序

在写这个程序之前,让我们再一次看看BasicGame例子的代码:

var canvas = undefined;
var canvasContext = undefined;
function start () {
canvas = document.getElementById("myCanvas");
canvasContext = canvas.getContext("2d");
mainLoop();
}
document.addEventListener('DOMContentLoaded', start);
function update () {
}
function draw () {
canvasContext.fillStyle = "blue";
canvasContext.fillRect(0, 0, canvas.width, canvas.height);
}
function mainLoop () {
update();
draw();
window.setTimeout(mainLoop, 1000 / 60);
}

我们现在用上面学到的关于对象的知识来把这段代码重新整理成一个游戏程序。如下:

"use strict";
var Game = {
canvas : undefined,
canvasContext : undefined
};Game.start = function () {
Game.canvas = document.getElementById("myCanvas");
Game.canvasContext = Game.canvas.getContext("2d");
Game.mainLoop();
};
document.addEventListener('DOMContentLoaded', Game.start);
Game.update = function () {
};
Game.draw = function () {
Game.canvasContext.fillStyle = "blue";
Game.canvasContext.fillRect(0, 0, Game.canvas.width, Game.canvas.height);
};
Game.mainLoop = function () {
Game.update();
Game.draw();
window.setTimeout(mainLoop, 1000 / 60);
};

你创建了一个叫做Game的复合变量。这个对象有两个成员变量,canvas和canvasContext。此外,你给这个对象添加了几个方法,包括构成这个游戏循环的方法。你分开定义了这个对象的方法。这样做的原因是你可以清楚的分辨出这些数据和方法组成的对象可以如何与数据打交道。需要注意的是,像我推荐的一样,添加了“use strict”。

现在,让我们对这个程序进行扩展。它需要显示一个在屏幕上移动的方块。你想随着时间改变方块的X坐标值。为了做到这些,你必须把现在的X坐标值储存在变量里。那样你就可以在update里面给变量进行赋值并且使用这个值在draw方法里画出这个方块。放置这个变量的地方是在Game对象里,你可以像下面一样声明和实例化:

var Game = {
canvas : undefined,
canvasContext : undefined,
rectanglePosition : 0
};

使用变量rectanglePosition来储存在方块的X坐标值。在draw方法里,你可以使用这个值在屏幕上画出方块。这个例子里,绘画出一个不超过画布大小的方块,下面是draw方法的内容:

Game.draw = function () {
Game.canvasContext.fillStyle = "blue";
Game.canvasContext.fillRect(Game.rectanglePosition, 100, 50, 50);
}

现在你需要做的就是计算X的坐标值。在update方法里计算X值,因为改变X值以为着更新着游戏世界。在这个例子里,我们基于时间的流逝来改变方块的坐标值。在javascript获取系统的时间值:

var d = new Date();
var currentSystemTime = d.getTime();

在此之前,你还没看过像第一行那样的符号。现在,假设new Date()创造了一个复合变量(对象),里面有跟时间相关的信息,还有一些有用的方法。其中一个方法是getTime。你通过对象d调用此方法并储存在currentSystemTime里。现在这个变量就有了从1970年1月1日开始的时间。你可以想象到这个变量值有点大。如果你想设置X坐标值,那么就要一个很大的屏幕。当然,不可能这样做,你用时间对画布的宽度求余,余数作为X坐标值。那样,你始终得到的是一个在0到画布宽度之间的值。update方法如下:

Game.update = function () {
var d = new Date();
Game.rectanglePosition = d.getTime() % Game.canvas.width;
};

如你所知,update和draw方法顺序调用,大约每秒60帧。每一次时间改变,系统时间也改变,意味着方块的坐标值也改变,那么方块显示的地方就与之前不一样。

在这个例子运行的如你所想之前你还要做一件事情。如果你像这样运行程序,一个蓝色的条将出现在屏幕上。因为你在旧的方块上绘画了新的方块。为了解决这个问题,每次画方块之前你需要清除画布。清除画布用clearRect方法。这个方法清除掉指定大小的画布。举例:

Game.canvasContext.clearRect(0, 0, Game.canvas.width, Game.canvas.height);

为了方便,把这条指令放在一个叫做clearCanvas的方法里,如下:

Game.clearCanvas = function () {
Game.canvasContext.clearRect(0, 0, Game.canvas.width, Game.canvas.height);
};

你需要做的就是在游戏循环里,在update和draw方法之前调用上面的方法。

Game.mainLoop = function() {
Game.clearCanvas();
Game.update();
Game.draw();
window.setTimeout(Game.mainLoop, 1000 / 60);
};

这个例子就完成了。运行结果如图3-8所示:

(省略图3-8)

变量的范围

你声明变量的地方决定了你能在哪些地方使用这些变量。看上面程序的d变量。它声明在update方法里,所以它只能在update方法里面使用。就是说,你不能在draw方法里面使用这个变量。当然,你可以在draw方法里面重新申请一个d变量,但是需要意识到的是这里的d变量和update方法里面的d变量是不一样的。

相对的,你在一个对象的水平上声明一个变量,你就可以在任何地方使用这个变量。你需要在update和draw方法里面使用方块的X坐标,因为在update里面需要更新坐标值,draw里面需要绘画出方块。因此需要在对象这个水平上声明变量,那样对象的所有方法都可以使用这个变量。

变量可以在哪里使用叫做变量范围。在这个例子里面,d的变量范围是update方法,Game.recentPostion是全局范围。

你学到了什么

在这章里,你学到了:

  • 怎样使用变量在内存里储存信息
  • 怎样创建含有变量和方法的对象
  • 怎样通过变量和update方法改变游戏世界和draw方法在屏幕上显示游戏世界

转载于:https://my.oschina.net/u/1587304/blog/399862

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

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

相关文章

我女朋友让我删前任,我明明删了她还是要分手...

1 人家都已经删了你还有什么不满意&#xff1f;&#xff1f;&#xff1f;▼2 高跟鞋翻车现场▼3 渣男总能渣出新花样▼4 现在的小朋友懂得也太多了吧&#xff01;▼5 耍帅不可怕&#xff0c;谁失败谁尴尬▼6 朋友&#xff0c;你清醒一点&#xff01;那个小手是鼠标&#…

你知道哪些开源基金会?

从 RMS 创立 FSF 发起自由软件运动&#xff0c;再到 OSI 成立并明确开源软件定义&#xff0c;这种崇尚开放协作的软件开发模式迅速席卷全球。除 FSF 与 OSI 外&#xff0c;还陆续诞生了许多致力于推广和发展开源的基金会。开源基金会对于开源软件和开源社区的组织、发展、协同创…

bpmn如何查看代码 idea_提高程序员效率的IDEA插件推荐(五大神器)

1. SequenceDiagramSequenceDiagram 可以根据代码调用链路自动生成时序图&#xff0c;超级赞&#xff0c;超级推荐&#xff01;这对研究源码&#xff0c;梳理工作中的业务代码有极大的帮助&#xff0c;堪称神器。安装完成后&#xff0c;在某个类的某个函数中&#xff0c;右键 -…

一张纸还能上天能救命?理工男宁愿放弃NASA百万年薪,也要回家折纸?!

全世界有3.14 % 的人已经关注了爆炸吧知识一张纸能做什么&#xff1f;小时候&#xff0c;它可能默默记录着你天马行空的想象力&#xff1a;而到了艺术家手中&#xff0c;它们就会变幻成各种各样精妙绝伦的艺术品&#xff1a;可当一双文艺的手&#xff0c;遇上一颗聪明无比的“理…

【干货】单日10亿GMV的.NET5电商平台,是如何设计的?

自京东和唯品会转了Java&#xff0c;.NET就一直缺乏高并发电商案例&#xff0c;.NET5能做高并发电商吗&#xff1f;必须的&#xff0c;别停留在.NET Framework的旧印象了&#xff01;这里为大家分享一家上市公司的项目案例&#xff0c;纯.NET5电商平台&#xff0c;轻松承接双11…

通过 Lotus Domino Java 代理消费 Web 服务

Web 服务是一种允许两台或更多的计算机在网络中交互的系统设计。这种服务的主要优点是&#xff0c;它是在多台不同操作系统的计算机和应用服务器之间发送对象的标准解决方法。例如&#xff0c;我们的公司使用 Web 服务从一台运行 Microsoft .NET Framework 的计算机向基于 IBM …

goahead如何使用cgi服务_QQ如何设置使用代理服务器?

很多人可能会问了&#xff0c;QQ上可以设置代理服务器吗?答案是可以的。今天就为大家详细介绍一下&#xff0c;如何在QQ上设置代理服务器的。1、双击QQ图标&#xff0c;打开QQ登录界面&#xff0c;我们就可以看到界面右上角有一个“设置”按钮。QQ如何设置使用代理服务器12、点…

android listview添加数据_Android面经分享,失业两个月,五一节前拿到offer

秦子帅明确目标&#xff0c;每天进步一点点.....作者 | 天天有道地址 | juejin.im/post/5eb01866f265da7b9c24562c基本介绍今天介绍一位朋友的经历&#xff1a;从3月初开始复习&#xff0c;准备面试题。复习的资料主要为《Android开发艺术探索》和jsonchao的博客&#xff0c;…

Dapr + .NET 实战(四)发布和订阅

什么是发布-订阅发布订阅是一种众所周知并被广泛使用的消息传送模式&#xff0c;常用在微服务架构的服务间通信&#xff0c;高并发削峰等情况。但是不同的消息中间件之间存在细微的差异&#xff0c;项目使用不同的产品需要实现不同的实现类&#xff0c;虽然是明智的决策&#x…

这些数学趣图,数学老师看了后会怎么想?

全世界有3.14 % 的人已经关注了爆炸吧知识这个扣分不?我的人生98%的时间都是无比正确的数学与我不能言语的关系最深情的告白限速是......当我完成数学作业后....维生素C的来历高数课堂恩..... 来拜师了啊, 好好学习. 为师给你命名: 阿尔法狗.这个是驻点, 这是最值, 这些机器学…

COM 组件设计与应用(六)

一、前言  1、与 《COM 组件设计与应用(五)》的内容基本一致。但本回讲解的是在 vc.net 2003 下的使用方法&#xff0c;即使你不再使用vc6.0&#xff0c;也请和上一回的内容&#xff0c;参照比对。   2、这第一个组件&#xff0c;除了所有 COM 组件必须的 IUnknown 接口外&…

python 柱状图 间距_专题第18篇:Python 绘图入门

我的施工之路1我的施工计划2数字专题3字符串专题4列表专题5流程控制专题6编程风格专题7函数使用8面向对象编程(上篇)9面向对象编程(下篇)10十大数据结构11包和模块使用总结12Python正则专题总结13设计模式14Python时间模块总结15 Python 装饰器16 Python 迭代器17 Python 生成器…

WPF实现截屏(仿微信)

WPF开发者QQ群&#xff1a; 340500857 | 微信群 -> 进入公众号主页 加入组织欢迎转发、分享、点赞、在看&#xff0c;谢谢~。 前言有小伙伴需要在软件反馈窗体增加截图功能需求&#xff0c;所以今天来实现一个仿微信的截图。01—效果预览效果预览&#xff08;更多效果请下…

我妈要把闺蜜介绍给我当女朋友......

1 反正手没闲着啊▼2 这...这女孩子不会是您跳广场舞认识的吧&#xff1f;▼3 这就是生活▼4 有画面感了▼5 这种运动会想想就觉得很好看▼6 电脑屏幕不亮手机玩起来不够舒服▼7 这种脱衣方式可真是太酷啦&#xff01;▼你点的每个赞&#xff0c;我都认真当成了喜欢

topic数量是指什么_一个网站的IP、UV和PV到底是什么

在百度统计后台会看到“IP统计”、“UV统计”、“PV统计”&#xff0c;那么、什么是IP&#xff0c;什么是UV&#xff0c;什么又是PV&#xff0c;三者之间有什么关系&#xff0c;IP重要&#xff0c;还是UV重要&#xff0c;还是PV重要。什么是IP&#xff1f;IP即&#xff1a;Inte…

发布一个博客园专用Windows Live Writer代码插件

一直用Windows Live Writer写博客&#xff0c;不过没找到能与博客园配合得很好的代码插件&#xff0c;每次写完文章发布到博客园总要手动修改代码。所以我自己写了一个博客园专用的Windows Live Writer代码插件&#xff08;我知道这世界上已经有N个代码插件&#xff0c;好吧&am…

js深拷贝和浅拷贝

一、数组的深浅拷贝 在使用JavaScript对数组进行操作的时候&#xff0c;我们经常需要将数组进行备份&#xff0c;事实证明如果只是简单的将它赋予其他变量&#xff0c;那么我们只要更改其中的任何一个&#xff0c;然后其他的也会跟着改变&#xff0c;这就导致了问题的发生。 va…

dbeaver 数据转化 mapping_Python机器学习实例:数据竞赛-足球运动员身价估计

前言1&#xff0c;背景介绍每个足球运动员在转会市场都有各自的价码。本次数据练习的目的是根据球员的各项信息和能力来预测该球员的市场价值。2&#xff0c;数据来源FIFA20183&#xff0c;数据文件说明数据文件分为三个&#xff1a;train.csv         训练集     文件…

对SQL server、Oracle、MySQL和PostgreSQL进行OLTP性能测试(Benchmark)

&#x1f4e2;欢迎点赞 &#xff1a;&#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff0c;赐人玫瑰&#xff0c;手留余香&#xff01;&#x1f4e2;本文作者&#xff1a;由webmote 原创&#xff0c;首发于 【掘金】&#x1f4e2;作者格言&#xff1a;生活在于…

【完整版】当大师遇到了理工男,只能吐血了...

全世界有3.14 % 的人已经关注了爆炸吧知识1、青年问禅师&#xff1a;“大师&#xff0c;我很爱我的女朋友&#xff0c;她也有很多优点&#xff0c;但是总有几个缺点让我非常讨厌&#xff0c;有什么方法能让她改变&#xff1f;”禅师浅笑&#xff0c;答&#xff1a;“方法很简单…