当前位置: 首页 > 面试题库 >

在构造函数内部*分配原型方法-为什么不呢?

邬阳
2023-03-14
问题内容

从风格上讲,我更喜欢这种结构:

var Filter = function( category, value ){
  this.category = category;
  this.value = value;

  // product is a JSON object
  Filter.prototype.checkProduct = function( product ){
    // run some checks
    return is_match;
  }

};

为此结构:

var Filter = function( category, value ){
  this.category = category;
  this.value = value;
};// var Filter = function(){...}

Filter.prototype.checkProduct = function( product ){
  // run some checks
  return is_match;
}

从功能上讲,以这种方式构造代码是否有任何弊端?将原型方法添加到构造函数内部的原型对象中(即,在构造函数的表达式语句关闭之前)会导致意外的作用域问题吗?

在成功使用之前,我已经使用了第一种结构,但是我想确保自己不会因为调试错误而使自己陷入头痛,也不会引起开发人员的同情和痛苦。


问题答案:

从功能上讲,以这种方式构造代码是否有任何弊端?将原型方法添加到构造函数内部的原型对象中(即,在构造函数的表达式语句关闭之前)会导致意外的作用域问题吗?

是的,存在缺陷和意外的范围界定问题。

  1. 一遍又一遍地将原型分配给本地定义的函数,都将重复该分配并每次都创建一个新的函数对象。较早的分配将被垃圾回收,因为不再引用它们,但是与第二个代码块相比,在构造函数的运行时执行和垃圾回收方面,这都是不必要的工作。

  2. 在某些情况下会出现意外的范围问题。有关Counter明确的示例,请参见答案末尾的示例。如果从原型方法中引用构造函数的局部变量,则第一个示例将在代码中创建潜在的讨厌的错误。

还有一些其他(较小的)差异。您的第一个方案禁止在构造函数外部使用原型,如下所示:

Filter.prototype.checkProduct.apply(someFilterLikeObject, ...)

而且,当然,如果有人使用过:

Object.create(Filter.prototype)

如果不运行Filter构造函数,那还会产生不同的结果,可能不太可能,因为可以合理地预期使用Filter原型的某些东西应该运行Filter构造函数才能达到预期的结果。

从运行时性能的角度(对象上调用方法的性能)来看,这样做会更好:

var Filter = function( category, value ){
  this.category = category;
  this.value = value;

  // product is a JSON object
  this.checkProduct = function( product ){
    // run some checks
    return is_match;
  }

};

有一些Javascript“专家”声称不再需要使用原型节省内存(我几天前看了一个视频讲座),是时候开始直接在对象上使用性能更好的方法了,而不是比原型
我不知道我是否准备倡导自己,但这是值得考虑的有趣问题。

我能想到的第一种方法的最大缺点是,犯下讨厌的编程错误确实非常容易。如果您碰巧认为可以利用原型方法现在可以看到构造函数的局部变量这一事实,那么只要有多个对象实例,您就会很快地陷入困境。想象一下这种情况:

var Counter = function(initialValue){
  var value = initialValue;

  // product is a JSON object
  Counter.prototype.get = function() {
      return value++;
  }

};

var c1 = new Counter(0);
var c2 = new Counter(10);
console.log(c1.get());    // outputs 10, should output 0

这是因为,尽管该get方法看起来像一个闭包,并且可以访问作为构造函数的局部变量的实例变量,但实际上它并不起作用。由于所有实例共享同一个原型对象,因此该Counter对象的每个新实例都会创建该get函数的新实例(可以访问刚刚创建的实例的构造函数局部变量)并将其分配给原型,因此现在所有实例都具有一个get访问最后创建的实例的构造函数的局部变量的方法。这是一场编程灾难,因为这可能永远都不是原本打算的,并且很容易成为弄清问题出在哪里和原因的起点。



 类似资料:
  • 问题内容: 我为什么可以这样做: 但是我不能这样做: 这两个函数都破坏了this的值并将其更改为,但是第二个函数抛出以下错误: 我怀疑这是因为允许分配意味着我可以将数组更改为其他内容(例如字符串),但是我希望那里的人可以肯定并且/或者有更详细的解释。 问题答案: 不允许在函数内分配值。假设您 可以 执行此操作,并且您的代码如下所示: 现在,如果您这样做: 在对象上调用函数的行为不应更改对象的 身份

  • 问题内容: 这有任何重要目的吗?可以省略吗? 问题答案: 并非总是必要的,但是它确实有其用途。假设我们想在基类上创建一个复制方法。像这样: 现在,当我们创建一个新的并复制它时会发生什么? 该副本不是的实例。这是因为(没有显式检查),我们无法从“基本”类返回副本。我们只能返回。但是,如果我们重置了构造函数: …然后一切都按预期进行:

  • 当我通过从调用初始化bean时,一切都按预期进行。我的问题是为什么通过和组合注入bean不调用方法

  • 问题内容: 我是Java编程语言的初学者,最近我研究了 构造函数 不能在Java中继承,有人可以解释 为什么 吗? 问题答案: 简而言之,构造函数不能被继承,因为在子类中它具有​​不同的名称(子类的名称)。 您只能执行以下操作: 相反,方法是使用“相同名称”继承的,可以使用。 理由如下:继承构造函数没有多大意义,因为类A的构造函数意味着创建类型A的对象,而类B的构造函数意味着创建类B的对象。 不过

  • 本文向大家介绍浅谈js构造函数的方法与原型prototype,包括了浅谈js构造函数的方法与原型prototype的使用技巧和注意事项,需要的朋友参考一下 把方法写在构造函数内的情况我们简称为函数内方法,把方法写在prototype属性上的情况我们简称为prototype上的方法。 •函数内的方法: 使用函数内的方法我们可以访问到函数内部的私有变量,如果我们通过构造函数new出来的对象需要我们操作

  • 伊登 JLS所说的是: 设C是ClassName表示的类。设n是一个整数,使得C是类的第n个词汇封闭类,在该类中出现有条件的this表达式。 [...] 如果当前类不是类C或C本身的内部类,则为编译时错误。 在的情况下,内部类集。这意味着上面的代码应该可以正常工作。发生了什么?