0

老问题,问了很多次,回答了很多次,但有点扭曲。首先是原型版本:

someA = function() {
    this.val = 'a';
}
someA.prototype.getVal = function() {
    return this.val;
}

现在另一个版本:

someA = function() {
    this.val = 'a';
    this.getVal = function() {
        return this.val;
    }
}

现在,假设 getVal() 函数是HUGE,您将创建数以千计的 someA 对象,但无论出于何种原因,您想使用 this.getVal 版本?如果我们这样写会怎样:

someA =function() {
    this.val = 'a';
    this.getVal = this._getVal;
}
someA.prototype._getVal = function() {
    return this.val;
}

这样做,你是否会同时拥有两者的优势?

ps 在一个完全不同(但仍然有些相关)的主题上,如何在问题或答案之一中添加问题和评论

已编辑:将所有出现的情况更改return valreturn this.val-- 愚蠢的错误 ;-)

4

3 回答 3

0

下面的示例起作用的原因是,该getVal函数位于闭包中,将所有变量保留在外部函数的范围内,因此,创建运行实例的结果someA为您提供了一个对象,该对象具有getVal可以访问的方法的值val

var someA = function() {
  var val = 'a';
  this.getVal = function() {
    return val;
  }
};

如果您将 val 公开为成员变量(即:),this.val = 'a';那么您将需要该getVal方法还返回成员变量版本,而不仅仅是return val;.

var someA = function() {}
someA.prototype = {
  val: 'a',
  getVal: function() {
    return this.val;
  }
};

使用原型意味着这在功能上等同于:

var someA = function() {
  this.val = 'a';
  this.getVal = function() {
    return this.val;
  }
}

但具有显着的性能提升,因为只有一个 getVal 函数实例。但是,您可以通过将其重写为来使用具有多个引用的单个函数实例:

var _getVal = function() {
  return this.val;
};
var someA = function() {
  this.val = 'a';
  this.getVal = _getVal;
}
于 2012-08-06T07:51:25.083 回答
0

您只是给原型函数起别名,没有任何好处。当您将其分配给某物时,在别处定义的函数不会意识到任何变量。它并没有突然出现val在它的范围内。

然而,无论函数是在哪里定义的,一个函数对于每次调用都可以有不同的对象上下文。这允许对不同对象进行真正的函数重用,并且不需要将所有内容保存在巨大的闭包链中并为每个对象重新创建它们。

您可以尝试运行代码,看看它不起作用:

someA =function() {
    var val = 'a';
    this.getVal = this._getVal;
}
someA.prototype._getVal = function() {
    return val; //This will throw reference error because the `val` is not
                //known here.
}
于 2012-08-06T07:43:19.347 回答
0

做这个IMO真的没有意义。

有些人可能会争辩说,原型版本会节省你的内存并给你带来更好的性能。尽管您可以尝试在 jsPerf 上设置测试并查看您得到的结果,但这可能是正确的,但可能不足以产生显着差异。

两者当然是有区别的。原型只会创建属性或方法的一个实例,而构造函数将创建与对象实例一样多的实例。

我会说,只要选择对你有意义的东西,或者将两者结合起来。如果您真的关心性能,那么使用构造函数添加可能更改的属性或每个实例必须唯一的属性,并使用原型创建适用于所有实例的公共方法。

于 2012-08-06T07:46:53.830 回答