为什么在构造函数中使用this关键字

2023-12-02

比较代码1和代码2,哪一个是正确的?

function Rectangle(height, width) {
  this.height = height;
  this.width = width;
  this.calcArea = function() { // why use this here?
      return this.height * this.width;
  };

}

代码2 我认为这样就可以了:

function Rectangle(height, width) {
      this.height = height;
      this.width = width;
      calcArea = function() {
          return this.height * this.width;
      };

    }

哪一个是正确的?

这取决于你如何看待“正确”:

  • Will either declaration fail to be parse correctly?
    • 不,两者都是有效的 JavaScript。
  • Which one will calculate calcArea?
    • 代码 1 将正确计算它,代码 2 不会创建该成员函数Rectangle类,但你可以让它正确计算,但广告重定向有点困难。见下文。
  • Is either one good practice for creating classes?
    • 不,他们都不是。请参阅底部。

代码 1 -calcArea()

如果您创建一个新实例Rectangle在代码1中然后:

function Rectangle(height, width) {
    this.height = height;
    this.width = width;
    this.calcArea = function() { // why use this here?
        return this.height * this.width;
    };    
}

var rect = new Rectangle( 3, 4 );
console.log( rect.calcArea() );

会正确输出12

代码 2 -calcArea()

如果您创建一个新实例Rectangle在代码2中然后:

function Rectangle(height, width) {
    this.height = height;
    this.width = width;
    calcArea = function() {
        return this.height * this.width;
    };
}

var rect = new Rectangle( 3, 4 );
console.log( rect.calcArea() );

会抛出错误:TypeError: rect.calcArea is not a function

calcArea相反,附加到全局范围,因此我们可以执行以下操作:

console.log( calcArea() );

会输出NaN as calcArea在全局范围的一部分,因此不知道任何实例Rectangle类和全局范围没有height or a width属性。

如果我们这样做:

var rect = new Rectangle( 3, 4 );
width = 7;   // Set in the global scope.
height = 10; // Set in the global scope.
console.log( calcArea() );

然后它会返回70(并不是12因为,在calcArea(), this引用全局范围而不是rect目的)。

如果我们改变什么this指使用.call()调用该函数:

var rect = new Rectangle( 3, 4 );
width = 7;   // Set in the global scope.
height = 10; // Set in the global scope.
console.log( calcArea.call( rect ) );

然后就会输出12 (since this现在指的是rect对象而不是全局范围)。

您可能不想每次使用时都必须这样做calcArea().

为什么代码 1 不是最优的

代码 1 可以工作,但不是最佳解决方案,因为每次创建新的Rectangle它将创建一个对象calcArea该对象的属性与任何对象都有不同的功能calcArea任何其他的属性Rectangle object.

如果您这样做,您可以看到这一点:

function Rectangle(height, width) {
    this.height = height;
    this.width = width;
    this.calcArea = function() { // why use this here?
        return this.height * this.width;
    };    
}

var r1 = new Rectangle( 3, 4 ),
    r2 = new Rectangle( 6, 7 );

console.log( r1.calcArea.toString() === r2.calcArea.toString() ); // Line 1
console.log( r1.calcArea === r2.calcArea );                       // Line 2

哪个会输出true当测试函数的字符串表示形式时,它们是相同的,但是false测试功能是否相同时。

这是什么意思?如果您创建 10,000 个实例Rectangle那么你将有 10,000 个不同的实例calcArea属性也是如此,每个副本都需要额外的内存(加上分配该内存并在最后进行垃圾收集的时间)。

什么是更好的做法?

function Rectangle(height, width) {
      this.setHeight( height );
      this.setWidth( width );
}
Rectangle.prototype.setHeight = function( height ){ this.height = height; }
Rectangle.prototype.setWidth  = function( width  ){ this.width = width; }
Rectangle.prototype.calcArea  = function(){ return this.height * this.width; }

那么如果你这样做:

var r1 = new Rectangle( 3, 4 ),
    r2 = new Rectangle( 6, 7 );

console.log( r1.calcArea.toString() === r2.calcArea.toString() ); // Line 1
console.log( r1.calcArea === r2.calcArea );                       // Line 2

它会返回true对于两者 - 意味着r1.calcArea and r2.calcArea引用相同的函数,无论有多少个实例Rectangle有。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么在构造函数中使用this关键字 的相关文章

  • 在占位符中添加 HTML

    我喜欢使用 HTML 占位符 因为它有助于向用户描述他们需要输入的内容类型 但是 有时您需要为用户提供更多信息 而不仅仅是简单的句子 基本上我希望能够在我的文本区域占位符中添加换行符 制表符等 我听说过使用特殊编码来做到这一点 并且已经使用
  • crypto-js 中的 AES 解密返回空字符串

    我正在尝试将加密数据存储在 localStorage 中 并在需要时使用 crypto js 对其进行解密 这是加密函数 const passphrase CryptoJS enc Utf8 parse key const iv Crypt
  • Google Analytics API - 跟踪子域

    我有一个网站 每个用户都注册为子域 username domain com 我正在使用以下代码跟踪所有子域 var gaq gaq gaq push setAccount UA XXXXXX X gaq push setDomainName
  • 在 HTML TextArea 中设置(或读取)光标/插入符的值

    我正在尝试 但失败了 在 HTML 文本区域中实现拖放机制 使用 jQuery 或 Scriptaculous 我们都使用 拖放机制相对容易 因此我愿意接受使用这两者之一的答案 问题是 我似乎找不到读取或设置插入点的方法 我最终想要做的是确
  • 使用过渡添加子项时 div 的平滑增长

    尽管使用了以下代码 但其行为并不符合我的预期transition所以可能有些事情我不明白 理想情况下 单击该按钮会将一个子项添加到id2div 并制作id1分区增长smoothly因此 function id1 button click g
  • 每 x 秒重复一次代码,但如果 [在此处插入检查] 则不重复

    这是后续这个问题 https stackoverflow com questions 13304471 javascript get code to run every minute 我在那里找到了如何使代码每 x 秒重复一次 是否有可能举
  • 为什么我在 ECMAScript / ActionScript 3 中看到不精确的浮点结果?

    大家好 让我们直接跳到代码示例 以展示 ECMAScript JavaScript AS3 如何无法正确执行简单的数学运算 AS3 对 Number 类使用 IEEE 754 双精度浮点数 据说与JavaScript 中使用的 trace
  • AngularJS Youtube 播放器嵌入非常大的播放列表

    我目前正在构建一个 AngularJS 应用程序 我知道它有点过时 但我对它很有信心 我的应用程序需要嵌入一个 YouTube 播放器 其中包含一个非常大的播放列表 大约 1500 个项目 但我无法对其进行编码 以便它实际上可以嵌入超过 2
  • Javascript 清理:插入可能的 XSS html 字符串的最安全方法

    目前我正在将此方法与 jQuery 解决方案结合使用 以清除字符串中可能的 XSS 攻击 sanitize function str return htmlentities str ENT QUOTES return div div tex
  • 适用于 HTML5 混合应用程序的 CORS

    我读过很多关于 CORS 的文章 以及允许 Access Control Allow Origin 如何成为 Web 服务器的安全漏洞 但没有一篇文章解释了如何允许 HTML5 混合应用程序访问某些不允许使用通配符 的域上托管的 Web 服
  • 如何使用 JavaScript 禁用滚动条?

    当我仅在 Internet Explorer 7 中显示代表模式窗口的 div 时 我需要锁定浏览器滚动条 谷歌搜索我发现我可以使用document body style overflow hidden 但这不适用于 IE7 我也尝试过do
  • javascript 代码只能在函数之外工作 - 为什么?

    为什么这段代码不能像下面写的那样工作 但如果我注释掉function testBgChange 并将代码保留在该函数内 它可以正常工作 如果我将代码保留在函数中然后调用该函数 会有什么区别
  • 如何从代码隐藏文件中的asp.net用户控件注册(调用)jQuery函数?

    如何从代码隐藏文件中的asp net用户控件注册 调用 jQuery函数 您可以使用ClientScriptManager RegisterStartupScript http msdn microsoft com en us librar
  • Node.js 连接 createServer 代码

    我正在阅读 Node js Connect 版本 2 15 0 Create a new connect server return Function api public function createServer function ap
  • 变量值的 swap() 函数[重复]

    这个问题在这里已经有答案了 我无法达到下面这个交换函数的预期结果 我希望将值打印为 3 2 function swap x y var t x x y y t console log swap 2 3 任何线索将不胜感激 您的函数正在内部交
  • Angular 8 webpack-bundle-analyzer 寻找错误的polyfill 文件

    无论我做什么 构建项目后我都会收到以下错误 Error parsing bundle asset
  • IE7 问题 - 当禁用文件下载自动提示时无法下载流式文件

    我的应用程序是基于 J2EE JSP Servlet 的 当我尝试从 JSP 打开新窗口 弹出窗口 并调用 Servlet 操作 例如 Streamer do 以在该弹出窗口内传输 PDF 文件时 我遇到了问题 问题 当 IE 7 gt 工
  • 从另一台服务器读取 Node.js 中的大文件

    我有两台相互通信的服务器 Server1 向 Server2 请求文件的部分内容 并将收到的数据存储到一个文件中 Server2 应该接收每个请求并创建一个流管道传输数据 假设服务器2中存储的文件 目录 如下 bigfile gz bigf
  • 如何防止IE11弹出(您确定要离开此页面)

    我正在处理一个页面 除了一个下拉菜单可供选择外 我无需输入任何内容 但在 IE11 中 当我尝试转到下一页时 它会弹出该消息 我想阻止这种弹出的发生 所以我只是想知道 IE11 中弹出窗口的默认行为是什么 因为它不会出现在 Chrome 或
  • 查看元素的所有 dom 事件

    我有一个 jQuery UI 日期选择器 当您单击日期时 它会清除我的 URL 哈希值 并且不会更改文本框中的日期 我假设某个地方还有其他一些 JavaScript 实用程序 它也正在调用某种委托事件 抛出错误并终止 jquery 处理程序

随机推荐

  • 删除列标签的背景颜色,同时保留绘图背景颜色 ggpairs

    我定义了一个函数来设置 ggpairs 中的背景 以匹配两个变量之间的相关程度 但是 我还想从沿图外部运行的变量标签中删除灰色背景 但如果不删除相关颜色 我就无法做到这一点 library GGally Loads some data mt
  • 在cuda中求对数

    如何在cuda中找到对数 我正在寻找设备功能 Thanks 您可以使用 logf x logf x log2f x log2f x log10f x log10f x 取自CUDA 编程指南 附录 D
  • 在cuda中分配结构数组后变量丢失

    我有一个用 C 语言编写的结构体 其中包含结构体数组 我需要在 GPU 中复制该结构体 为此 我正在编写一个函数 使一些cudaMalloc and cudaMemcpy从主机到设备的结构体中的变量 该结构的一个简单版本 真正的版本内部有各
  • java中为什么需要方法重载和重写? [复制]

    这个问题在这里已经有答案了 可能的重复 多态 重写 重载 我很难知道为什么需要方法重载和覆盖在java中 我读过一些关于此的文章 但无法理解为什么实际上需要它 我还访问了 stackoverflow 中的以下网址 但我还不清楚这个主题 Ja
  • 使用 Entity Framework 4 数据注释进行日期范围验证

    我使用 Entity Framework 4 为 ASP NET MVC3 Razor2 Web 应用程序提供模型 我正在使用 DataAnnotations 来实现验证 我需要将某些日期限制在 SQL Smalldatetime 类型接受
  • jpa 获取连接查询

    这是我的域名的样子 public class Template implements Serializable private static final long serialVersionUID 1L OneToOne cascade C
  • Excel 2007 MS Query 中出现多部分标识符错误,但 SQL Server 2008 中没有

    我有以下 SQL 代码 SELECT pd1 Meter pd1 BasicPool pd1 RateClass pd1 Flowdate SELECT upOrDownContract FROM PipelineData pd WHERE
  • 如何在后台显示 Swift UI 中的通讯通知?

    我正在 SwiftUI 和 firebase 中制作一个聊天应用程序 我想在用户收到新消息时显示通知 我能够在 firebase 中使用云消息发送推送通知 但这些通知不会自动发送 现在我想在用户收到消息时自动发送通信通知 我无法在 swif
  • 如何在 CDE 中添加全选选项来选择组件

    对于学生项目 我们正在与 Pentaho CDE 合作创建一个仪表板 一开始它工作得很好 但现在我们正处于添加多个选择组件的阶段 我们将选择组件的参数插入到Where语句中的SQL查询中 但现在我们遇到了一个问题 即不可能选择一个选择组件中
  • 在 C 中使用 libcurl 保存文件

    我正在从 perl 扩展到 C 并且尝试使用curl 的库来简单地从远程 url 保存文件 但我很难找到一个很好的示例来工作 另外 我不确定是否应该使用curl easy recv或curl easy perform I find 这个资源
  • 使用 const 引用延长临时对象的寿命

    我需要一些关于 const 引用的澄清 从这个链接 const Foo myFoo FuncBar const 引用延长了本地对象的寿命 但当我检查时这个链接尽管他们使用了 const 引用 Sandbox const string n m
  • 如何将Struts 2操作类中的InputStream值传递给JSP页面中的Ajax并将该值转换为JSON数组

    我想将 JSON 数组从 Struts 2 操作类传递到 JSP 页面 我正在尝试将数据集作为字符串发送 我想知道的是 如何在 JavaScript 中读取这些数据 这是我的方法Action class private InputStrea
  • Javascript - 模拟 Chrome 53 上的按键事件

    我正在尝试模拟按键事件 按下 铬53 我在 StackOverflow 上找到的所有解决方案似乎都不起作用 我的目标是拥有一个函数keyCode并用它模拟按键 需要纯JS function keyPressSimulate keyCode
  • 更新实体框架 4.1 代码优先中的外键关联

    我得出的结论是 我应该在我的代码优先设计中定义独立关联和外键关联 例如 public class Book public int ID get set public int AuthorID get set ForeignKey Autho
  • 如何适当地从 java.lang.Process 关闭 std-streams?

    这个问题是关于java lang Process及其对 stdin stdout 和 stderr 的处理 我们的项目中有一个类是对org apache commons io IOUtils 我们有一个安静的新方法来关闭进程对象的标准流吗
  • 更新 SQL 列

    所以我有一个有6列的表 每列对应于某种产品类型 每列都有一个数字 该数字对应于人们选择该产品类型的次数 A B C D E F 0 0 0 0 0 0 所以如果用户选择类型A 然后我想更新列A的号码来自0 to 1 所以这是我写的 SQL
  • 我如何能够在没有 #include 的情况下使用字符串?

    STL参考中给出了字符串类位于字符串头中 那么在不包含头的情况下 以下程序如何运行而不出错 include
  • 如何在字符串中的特定模式之后提取特定文本

    我有一些 Bash 代码 计划从字符串中提取 ID 我已尝试使用代码来查找模式 ID 之后的 ID 它正在提取 ID 值 但之后它会提取 ID 后的剩余文本 我只想提取该行中的 ID 而不提取剩余的文本 我试过下面的代码 string ID
  • 禁用分组单选操作按钮中的单个单选选择

    我有一个下面闪亮的代码 我试图禁用分组单选按钮中的单个单选按钮选择 我可以使用禁用完整的单选按钮shinyjs disable 功能 但是 无法禁用单一选择 library shiny library shinyjs library shi
  • 为什么在构造函数中使用this关键字

    比较代码1和代码2 哪一个是正确的 function Rectangle height width this height height this width width this calcArea function why use thi