gpt4 book ai didi

javascript - 在对象类声明中设置 javascript 原型(prototype)函数

转载 作者:行者123 更新时间:2023-12-02 23:37:40 24 4
gpt4 key购买 nike

通常,我见过在类定义之外声明的原型(prototype)函数,如下所示:

function Container(param) {
this.member = param;
}
Container.prototype.stamp = function (string) {
return this.member + string;
}

var container1 = new Container('A');
alert(container1.member);
alert(container1.stamp('X'));

此代码生成两个警报,其值分别为“A”和“AX”。

我想在类定义的内部定义原型(prototype)函数。这样做有什么问题吗?

function Container(param) {
this.member = param;
if (!Container.prototype.stamp) {
Container.prototype.stamp = function() {
return this.member + string;
}
}
}

我正在尝试这样做,以便我可以访问类中的私有(private)变量。但我发现,如果我的原型(prototype)函数引用私有(private)变量,则私有(private)变量的值始终是最初创建原型(prototype)函数时使用的值,而不是对象实例中的值:

Container = function(param) {
this.member = param;
var privateVar = param;
if (!Container.prototype.stamp) {
Container.prototype.stamp = function(string) {
return privateVar + this.member + string;
}
}
}
var container1 = new Container('A');
var container2 = new Container('B');
alert(container1.stamp('X'));
alert(container2.stamp('X'));

此代码生成两个警报,其值为“AAX”和“ABX”。我希望输出是“AAX”和“BBX”。我很好奇为什么这不起作用,以及是否有其他模式可以替代。

编辑:请注意,我完全理解,对于这个简单的示例,最好只使用像 this.stamp = function() {} 这样的闭包,而不是完全使用原型(prototype)。我也会这么做。但我正在尝试使用原型(prototype)来了解更多信息,并且想了解一些事情:

  • 什么时候使用原型(prototype)函数而不是闭包有意义?我只需要使用它们来扩展现有对象,例如 Date。我读过closures are faster .
  • 如果我出于某种原因需要使用原型(prototype)函数,是否可以在类内部定义它(如我的示例中所示),还是应该在外部定义它?
  • 我想了解为什么原型(prototype)函数无法访问每个实例的 privateVar 值,只能访问第一个实例的值。

最佳答案

When does it make sense to use prototype functions instead of closures?

嗯,这是最轻量级的方法,假设您在 prototype 中有一个方法某些构造函数,并且您创建了 1000 个对象实例,所有这些对象都将在其原型(prototype)链中包含您的方法,并且所有这些对象都将仅引用一个函数对象

如果您在构造函数内初始化该方法,例如( this.method = function () {}; ),您的所有 1000 个对象实例都将拥有一个函数对象作为自己的属性。

If I need to use a prototype function for some reason, is it "OK" to define it INSIDE the class, like in my example, or should it be defined outside?

在其内部定义构造函数原型(prototype)的成员没有多大意义,我将向您解释更多相关信息以及为什么您的代码不起作用。

I'd like to understand why the privateVar value of each instance is not accessible to the prototype function, only the first instance's value.

让我们看看您的代码:

var Container = function(param) {
this.member = param;
var privateVar = param;
if (!Container.prototype.stamp) { // <-- executed on the first call only
Container.prototype.stamp = function(string) {
return privateVar + this.member + string;
}
}
}

关于您的代码行为的关键点是 Container.prototype.stamp函数在第一次方法调用时创建

当您创建函数对象时,它将当前封闭范围存储在名为 [[Scope]] 的内部属性中。 .

当您调用该函数时,此范围随后会通过使用var在其中声明的标识符(变量)进行扩展。或函数声明。

[[Scope]] 的列表属性形成作用域链,当您访问标识符(例如 privateVar 变量)时,就会检查这些对象。

由于您的函数是在第一次方法调用 ( new Container('A') ) 时创建的, privateVar绑定(bind)到第一个函数调用的作用域,并且无论您如何调用该方法,它都将保持绑定(bind)状态。

看看这个 answer ,第一部分是关于with声明,但在第二部分我将讨论作用域链如何用于函数。

关于javascript - 在对象类声明中设置 javascript 原型(prototype)函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2784844/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com