在构造函数内部分配原型方法*

编程入门 行业动态 更新时间:2024-10-28 11:34:43
本文介绍了在构造函数内部分配原型方法* - 为什么不呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

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

Stylistically, I prefer this structure:

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; }

从功能上讲,以这种方式构建代码有什么缺点吗?将一个原型方法添加到构造函数体内的原型对象(即在构造函数的表达式语句关闭之前)会导致意外的范围问题吗?

Functionally, are there any drawbacks to structuring my code this way? Will adding a prototypical method to a prototype object inside the constructor function's body (i.e. before the constructor function's expression statement closes) cause unexpected scoping issues?

我用过第一个成功之前的结构,但我想确保我不会让自己陷入调试困境,或者由于编码错误而导致开发人员悲痛和恶化。

I've used the first structure before with success, but I want to make sure I'm not setting myself for a debugging headache, or causing a fellow developer grief and aggravation due to bad coding practices.

推荐答案

从功能上讲,以这种方式构建代码有什么缺点吗? 将原型对象添加到构造函数体内的原型对象(即在构造函数的表达式语句关闭之前)会导致意外的范围问题吗?

Functionally, are there any drawbacks to structuring my code this way? Will adding a prototypical method to a prototype object inside the constructor function's body (i.e. before the constructor function's expression statement closes) cause unexpected scoping issues?

是的,有缺点和意外的范围问题。

Yes, there are drawbacks and unexpected scoping issues.

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

  • Assigning the prototype over and over to a locally defined function, both repeats that assignment and creates a new function object each time. The earlier assignments will be garbage collected since they are no longer referenced, but it's unnecessary work in both runtime execution of the constructor and in terms of garbage collection compared to the second code block.

    在某些情况下存在意外的范围问题。有关显式示例,请参阅我的答案末尾的 Counter 示例。如果从prototype方法引用构造函数的局部变量,那么您的第一个示例会在代码中创建一个可能令人讨厌的错误。

    There are unexpected scoping issues in some circumstances. See the Counter example at the end of my answer for an explicit example. If you refer to a local variable of the constructor from the prototype method, then your first example creates a potentially nasty bug in your code.

    还有一些其他(更小的)差异。你的第一个方案禁止在构造函数之外使用原型,如:

    There are some other (more minor) differences. Your first scheme prohibits the use of the prototype outside the constructor as in:

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

    当然,如果有人使用:

    Object.create(Filter.prototype)

    没有运行过滤器构造函数,这也会产生不同的结果,这可能不太可能,因为期望使用的东西是合理的过滤器原型应该运行过滤器构造函数,以达到预期的效果。

    without running the Filter constructor, that would also create a different result which is probably not as likely since it's reasonable to expect that something that uses the Filter prototype should run the Filter constructor in order to achieve expected results.

    从运行时性能的角度来看(在对象上调用方法的性能),你最好用这个:

    From a run-time performance point of view (performance of calling methods on the object), you would be better off with this:

    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专家声称不再需要使用原型节省内存(我几天前看了一个关于那个的视频讲座)所以是时候开始直接在对象而不是原型上使用更好的方法性能了。我不知道我是否已经准备好自己提倡,但这是一个值得思考的问题。

    There are some Javascript "experts" who claim that the memory savings of using the prototype is no longer needed (I watched a video lecture about that a few days ago) so it's time to start using the better performance of methods directly on the object rather than the prototype. I don't know if I'm ready to advocate that myself yet, but it was an interesting point to think about.

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

    The biggest disadvantage of your first method I can think of is that it's really, really easy to make a nasty programming mistake. If you happen to think you can take advantage of the fact that the prototype method can now see local variables of the constructor, you will quickly shoot yourself in the foot as soon as you have more than one instance of your object. Imagine this circumstance:

    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

    演示问题:jsfiddle/jfriend00/c7natr3d/

    这是因为,虽然看起来像 get 方法形成一个闭包,并且可以访问构造函数的局部变量的实例变量,它在实践中不会那样工作。因为所有实例共享相同的原型对象,所以 Counter 对象的每个新实例都会创建 get 函数的新实例(可以访问刚刚创建的实例的构造函数局部变量)并将其分配给原型,所以现在所有实例都有一个 get 方法来访问本地变量最后一个实例的构造函数。这是一个编程灾难,因为这可能永远不会是预期的,并且可能很容易成为弄清楚出错的原因和原因。

    This is because, while it looks like the get method forms a closure and has access to the instance variables that are local variables of the constructor, it doesn't work that way in practice. Because all instances share the same prototype object, each new instance of the Counter object creates a new instance of the get function (which has access to the constructor local variables of the just created instance) and assigns it to the prototype, so now all instances have a get method that accesses the local variables of the constructor of the last instance created. It's a programming disaster as this is likely never what was intended and could easily be a head scratcher to figure out what went wrong and why.

  • 更多推荐

    在构造函数内部分配原型方法*

    本文发布于:2023-11-25 16:40:45,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1630532.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:原型   函数   分配   方法

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!