JS--JS 的 new 做了什么?

article/2025/10/22 3:51:22

1. 创建临时对象/新对象

2. 绑定原型

3. 指定 this = 临时对象

4. 执行构造函数

5. 返回临时

参考借鉴其他博客非原创,总结下,以制作一个策略类战争游戏为例,玩家可以操作一堆士兵攻击敌方。

我们着重来研究一下这个游戏里面的「制造士兵」环节。

一个士兵的在计算机里就是一堆属性,如下图:

我们只需要这样就可以制造一个士兵:

var 士兵 = {ID: 1, // 用于区分每个士兵兵种:"美国大兵",攻击力:5,生命值:42, 行走:function(){ /*走俩步的代码*/},奔跑:function(){ /*狂奔的代码*/  },死亡:function(){ /*Go die*/    },攻击:function(){ /*糊他熊脸*/   },防御:function(){ /*护脸*/       }
}兵营.制造(士兵)

制造一百个士兵

如果需要制造 100 个士兵怎么办呢?

循环 100 次吧:

var 士兵们 = []
var 士兵
for(var i=0; i<100; i++){士兵 = {ID: i, // ID 不能重复兵种:"美国大兵",攻击力:5,生命值:42, 行走:function(){ /*走俩步的代码*/},奔跑:function(){ /*狂奔的代码*/  },死亡:function(){ /*Go die*/    },攻击:function(){ /*糊他熊脸*/   },防御:function(){ /*护脸*/       }}士兵们.push(士兵)
}兵营.批量制造(士兵们)

哎呀好简单。

质疑

上面的代码存在一个问题:浪费了很多内存。

  1. 行走、奔跑、死亡、攻击、防御这五个动作对于每个士兵其实是一样的,只需要各自引用同一个函数就可以了,没必要重复创建 100 个行走、100个奔跑……
  2. 这些士兵的兵种和攻击力都是一样的,没必要创建 100 次。
  3. 只有 ID 和生命值需要创建 100 次,因为每个士兵有自己的 ID 和生命值。

改进

看过我们的专栏以前文章(JS 原型链)的同学肯定知道,用原型链可以解决重复创建的问题:我们先创建一个「士兵原型」,然后让「士兵」的 __proto__ 指向「士兵原型」

var 士兵原型 = {兵种:"美国大兵",攻击力:5,行走:function(){ /*走俩步的代码*/},奔跑:function(){ /*狂奔的代码*/  },死亡:function(){ /*Go die*/    },攻击:function(){ /*糊他熊脸*/   },防御:function(){ /*护脸*/       }
}
var 士兵们 = []
var 士兵
for(var i=0; i<100; i++){士兵 = {ID: i, // ID 不能重复生命值:42}/*实际工作中不要这样写,因为 __proto__ 不是标准属性*/士兵.__proto__ = 士兵原型 士兵们.push(士兵)
}兵营.批量制造(士兵们)

优雅?

有人指出创建一个士兵的代码分散在两个地方很不优雅,于是我们用一个函数把这两部分联系起来:

function 士兵(ID){var 临时对象 = {}临时对象.__proto__ = 士兵.原型临时对象.ID = ID临时对象.生命值 = 42return 临时对象
}士兵.原型 = {兵种:"美国大兵",攻击力:5,行走:function(){ /*走俩步的代码*/},奔跑:function(){ /*狂奔的代码*/  },死亡:function(){ /*Go die*/    },攻击:function(){ /*糊他熊脸*/   },防御:function(){ /*护脸*/       }
}// 保存为文件:士兵.js

然后就可以愉快地引用「士兵」来创建士兵了:

var 士兵们 = []
for(var i=0; i<100; i++){士兵们.push(士兵(i))
}兵营.批量制造(士兵们)

JS 之父的关怀

JS 之父创建了 new 关键字,可以让我们少写几行代码:

只要你在士兵前面使用 new 关键字,那么可以少做四件事情:

  1. 不用创建临时对象,因为 new 会帮你做(你使用「this」就可以访问到临时对象);
  2. 不用绑定原型,因为 new 会帮你做(new 为了知道原型在哪,所以指定原型的名字为 prototype);
  3. 不用 return 临时对象,因为 new 会帮你做;
  4. 不要给原型想名字了,因为 new 指定名字为 prototype。

这一次我们用 new 来写

function 士兵(ID){this.ID = IDthis.生命值 = 42
}士兵.prototype = {兵种:"美国大兵",攻击力:5,行走:function(){ /*走俩步的代码*/},奔跑:function(){ /*狂奔的代码*/  },死亡:function(){ /*Go die*/    },攻击:function(){ /*糊他熊脸*/   },防御:function(){ /*护脸*/       }
}// 保存为文件:士兵.js

然后是创建士兵(加了一个 new 关键字):

var 士兵们 = []
for(var i=0; i<100; i++){士兵们.push(new 士兵(i))
}兵营.批量制造(士兵们)

new 的作用,就是省那么几行代码。(也就是所谓的语法糖)

注意 constructor 属性

new 操作为了记录「临时对象是由哪个函数创建的」,所以预先给「士兵.prototype」加了一个 constructor 属性:

士兵.prototype = {constructor: 士兵
}

如果你重新对「士兵.prototype」赋值,那么这个 constructor 属性就没了,所以你应该这么写:

士兵.prototype.兵种 = "美国大兵"
士兵.prototype.攻击力 = 5
士兵.prototype.行走 = function(){ /*走俩步的代码*/}
士兵.prototype.奔跑 = function(){ /*狂奔的代码*/  }
士兵.prototype.死亡 = function(){ /*Go die*/    }
士兵.prototype.攻击 = function(){ /*糊他熊脸*/   }
士兵.prototype.防御 = function(){ /*护脸*/       }

或者你也可以自己给 constructor 重新赋值:

士兵.prototype = {constructor: 士兵,兵种:"美国大兵",攻击力:5,行走:function(){ /*走俩步的代码*/},奔跑:function(){ /*狂奔的代码*/  },死亡:function(){ /*Go die*/    },攻击:function(){ /*糊他熊脸*/   },防御:function(){ /*护脸*/       }
}

完。


http://chatgpt.dhexx.cn/article/h89wb0fL.shtml

相关文章

29-js

JS—Day01 第0节&#xff1a;JS简介 编译语言&#xff1a;在运行之前会源代码进行编译。 为什么需要编译&#xff1a;我们写的代码通过高级语言写&#xff08;C&#xff0c;java&#xff09;面向用户友好。但是计算机只认识0或1&#xff0c;所有我们需要将写好的源代码便以为…

jQuery.fn.extend() 的源码实现

jQuery.fn.extend(object) 概述 在 jQuery 下添加实例方法 参数 参数说明object扩展 jQuery 实例方法的对象&#xff0c;里面包含着函数 示例 目的&#xff1a;在 jQuery 下增加两个实例方法 代码&#xff1a; const aMin function (a, b) {return a < b ? a : b;…

[JavaScript实例] 兼容IE和最新FF的复制粘贴代码

在网上看了很多这样的代码&#xff0c;但是在最新版本的火狐上都是失效了…… 没办法了&#xff0c;只能自己写了&#xff01; 这个方法主要是复制文本的内容包括HTML代码&#xff0c;以及很多网站实现的文章末尾添加的文章来源功能&#xff01;好了&#xff0c;话就不多说了&a…

JSF 组件开发

组件模型的关键考验就是&#xff1a;能否从第三方供应商购买组件&#xff0c;并把它们插入应用程序&#xff1f;与可购买可视 Swing 组件一样&#xff0c;也可以购买 Java ServerFaces (JSF) 组件&#xff01;需要一个好玩的日历&#xff1f;可以在开源实现和商业组件之间选择。…

欧拉函数及其计算

欧拉函数 1. 定义 什么是欧拉函数&#xff1f; 任意给定正整数n&#xff0c;请问在小于等于n的正整数之中&#xff0c;有多少个与n构成互质关系&#xff1f;&#xff08;比如&#xff0c;在1到8之中&#xff0c;有多少个数与8构成互质关系&#xff1f;&#xff09; 计算这个值…

欧拉公式理解

https://blog.csdn.net/xieyan0811/article/details/72833722 欧拉公式是数学里最令人着迷的公式之一&#xff0c;它将数学里最重要的几个常数联系到了一起&#xff1a;两个超越数&#xff1a;自然对数的底e&#xff0c;圆周率π&#xff1b;两个单位&#xff1a;虚数单位i和自…

高数 不定积分 欧拉代换

高数 不定积分 欧拉代换&#xff1a;

用虚数i与欧拉公式来解释分数阶微积分

ps:如果研究又遇到分数阶相关课题的童鞋可以与博主联系获取分数阶相关的源代码&#xff0c;不图什么&#xff0c;就图个点赞 一、问题简介 在最近的课题中接触到了分数阶导数相关的东西&#xff0c;比如函数 f ( t ) f(t) f(t)对t的0.5阶导等等&#xff0c;网上有一些对于分数…

常用的积分方法讨论(数学表达与代码整理)(龙格-库塔、中值积分、欧拉积分)

积分方法讨论&#xff08;数学表达与代码整理&#xff09; 数学原理 1.1 四元数与角速度的关系 在无人机或无人车的导航系统中常常采用四元数代替欧拉角来表示机体的旋转&#xff0c;因为欧拉角在计算过程中容易产生奇异&#xff0c;这与欧拉角的计算需要利用正弦、余弦公式…

常微分方程的解法 (二): 欧拉(Euler)方法

上一节讲了 常微分方程的三种离散化 方法:差商近似导数、数值积分、Taylor 多项式近似。 目录 2 欧拉&#xff08;Euler&#xff09;方法 2.1 向前 Euler 公式、向后 Euler 公式 2.2 Euler 方法的误差估计 3 改进的 Euler 方法 3.1 梯形公式 …

微积分 --- 欧拉数e的计算方法(个人学习笔记)

计算方法1&#xff1a; 计算方法2&#xff1a; 对于100来说&#xff0c;分37份的话&#xff0c;其值最接近e&#xff0c;且所有份的乘积最大为9.2944e15。 下面是从微积分的角度去求证&#xff0c;如果要让y为最大值&#xff0c;应该让xc/e&#xff0c;这就是最优份数。 &am…

考研数二第十七讲 反常积分与反常积分之欧拉-泊松(Euler-Poisson)积分

反常积分 反常积分又叫广义积分&#xff0c;是对普通定积分的推广&#xff0c;指含有无穷上限/下限&#xff0c;或者被积函数含有瑕点的积分&#xff0c;前者称为无穷限广义积分&#xff0c;后者称为瑕积分&#xff08;又称无界函数的反常积分&#xff09;。 含有无穷上限/下…

#欧拉第二积分(伽马函数)

伽玛函数&#xff0c;也叫欧拉第二积分&#xff0c;是阶乘函数在实数与复数上扩展的一类函数。 伽玛函数作为阶乘函数的延拓&#xff0c;是定义在复数范围内的亚纯函数&#xff0c;通常写成&#xff0c;负整数和0是它的一阶极点。 实数域&#xff1a; 复数域&#xff1a; 在解…

常见的数值积分方法 (欧拉、中值、龙格-库塔,【常用于IMU中】)

1. 积分基本概念 设F(x)为函数f(x)的一个原函数&#xff0c;我们把函数f(x)的所有原函数F(x)C&#xff08;C为任意常数&#xff09;叫做函数f(x)的不定积分(indefinite integral)。 非线性微分方程: 在有限的时间间隔Δt积分: 连续时间内积分: 工程上最常见的有三种&#xff…

欧拉积分法

数值积分法是求定积分的近似值的数值方法。即用被积函数的有限个抽样值的离散或加权平均近似值代替定积分的值。 数值积分法也是计算机仿真中常用的一种方法。在已知函数的微分方程时&#xff0c;求解函数下一时刻的值&#xff0c;我们主要有欧拉法、梯形法和龙格库塔法。 欧拉…

欧拉积分

欧拉积分 两个公式&#xff1a; $\Gamma(s)\int_{0}^{\infty}x^{s-1}e^{-x}dx,s>0$ (1) $B(p,q)\int_{0}^{1}x^{p-1}(1-x)^{q-1}dx,p>0,q>0$ (2) 一 、$\Gamma(Gamma)$函数 性质&#xff1a; 1.$\Gamma(s)$在定义域…

Oracle现使用CVSS 3.0对漏洞进行评级

Oracle今年4月关键补丁更新(Critical Patch Update)涉及多款产品中的136个漏洞&#xff0c;其中最大的变化是切换到通用安全漏洞评分系统3.0版本或者说CVSSv3&#xff0c;该版本可更准确反映漏洞带来的影响。 Oracle公司在其补丁公告中指出&#xff0c;这个关键补丁更新中的漏洞…

Cvss v2 complete documentation

通用漏洞计分系统&#xff08;CVSS&#xff09;为沟通IT漏洞的特征和影响提供了一个开放的框架。 CVSS由3组组成&#xff1a;基础&#xff0c;时间和环境。 每个组产生的范围从0到10的数字分数&#xff0c;以及Vector&#xff0c;一个反映用于得出分数的值的压缩文本表示。 基础…

东莞dell服务器维修上门服务,CVSS 10分漏洞影响Dell Wyse Thin客户端设备

近日&#xff0c;CyberMDX 研究人员公开了今年6月在Dell Wyse Thin客户端中发现了2个安全漏洞&#xff0c;漏洞CVE编号为CVE-2020-29491 和 CVE-2020-29492&#xff0c;这两个漏洞CVSS 评分都为10分&#xff0c;漏洞影响运行ThinOS v8.6及更低版本的所有设备。攻击者利用这两个…

通用漏洞评估方法CVSS3.0简表

CVSS3.0计算分值共有三种维度&#xff1a; 1. 基础度量。 分为 可利用性 及 影响度 两个子项&#xff0c;是漏洞评估的静态分值。 2. 时间度量。 基础维度之上结合受时间影响的三个动态分值&#xff0c;进而评估该漏洞的动态分值。 3. 环境度量。 根据用户实际环境需求结合时间…