如果类永远不会被子类化,原型在JavaScript中真的很重要吗? [英] Does prototype really matter in JavaScript if the class will never be subclassed?

查看:130
本文介绍了如果类永远不会被子类化,原型在JavaScript中真的很重要吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,在回答本网站上的另一个问题时,我为某人编写了一个类,用于在JavaScript中创建BitArray实例。我发布的代码如下所示:

So, in answering another question on this site, I wrote a class for someone to create a BitArray instance in JavaScript. The code I posted looked like this:

var foo = function(param1) {
    this._member = param1;
    this.getMember = function() { return this._member; };
    this.setMember = function(val) { this._member = val; };
    this.alertMember = function() { alert(this._member); };
    foo.STATIC_CONSTANT = "some value";
}

我收到的一条评论是相当严厉的你应该绝对添加foo.prototype的方法,而不是这个。如果我接受批评并将其应用于上述内容,则会将代码转换为:

One of the comments I received was a rather stern "You should absolutely add the methods to foo.prototype instead of this". If I take that criticism and apply it to the above, it turns the code into:

var foo = function(param1) {
    this._member = param1;
}
foo.prototype.getMember = function(){ return this._member; };
foo.prototype.setMember = function(val) { this._member = val; };
foo.prototype.alertMember = function() { alert(this._member); };
foo.STATIC_CONSTANT = "some value";

我的问题是,假设foo永远不会被子类化,这两种方法之间有什么区别?

My question is, what's the difference here between the two approaches assuming foo will never be subclassed?

要说清楚,我并不是在提倡编写草率的代码 - 我认为评论员会让我感到草率 - 但是因为我正在考虑他的正确性,所以它确实做到了让我思考 - 如果我正在创建一个有效密封的课程,我为什么要原型?

To be clear, I'm not advocating writing sloppy code - I credit the commentor with catching me being sloppy - but as I was conceeding to his correctness, it really did make me think - why should I prototype if I'm creating an effectively sealed class?

我在这里缺少某些表现或功能后果吗?或者当一个类不被子类化时使用原型无效?

Is there some performance or functional consequence I'm missing here? Or when a class won't be subclassed is using the prototype irrelevent?

推荐答案

有各种原因。首先,我想在JavaScript中讲课是误导性的。 JavaScript中没有类,但只有原型。

There are various reasons. Firstly though I guess speaking of classes in JavaScript is misleading. There are no classes in JavaScript, but only prototypes.

让我们分析第一种方法中实际发生的情况以及第二种方法中会发生什么。当第一种方法的代码运行时,它定义了一个函数,当它被称为构造函数时,它将创建一堆其他函数并将它们分配给新创建的对象的成员。您应该知道每次调用该函数时都会执行此操作。因此,如果您调用该函数一次,您将拥有一个共有4个函数的对象。如果两次调用该函数,则将有两个对象,总共有8个函数,依此类推。每次使用此构造函数创建新对象时,您将为其创建一组完整的函数。每个功能都需要内存。此外,现代JIT编译器试图在代码中发现热点可能无法将这些函数识别为热点,因为不是一个函数被多次调用,而是有几个函数,每个函数只被调用一次。此外,即使JIT能够将这些功能作为热点发现,它也必须单独编译这些功能,这需要额外的工作。

Let us analyze what actually happens in your first approach and what happens in the second approach. When the code of the first approach is run it defines a function, which, when it is called as a constructor, will create a bunch of other functions and assign them to members of the newly created object. You should be aware that this is done every time you call the function. So if you call the function once, you will have one object with a total of 4 functions. If you call the function twice, you will have two objects with a total of 8 functions, and so on. Each time, you create a new object using this constructor you will create a complete set of functions for it. Each of those function will require memory. Also, modern JIT compilers trying to spot hotspots in your code might fail to identify those functions as hot spots, since instead of having one function that is called multiple times you have several functions where each is only called once. Additionally even if the JIT is able to spot those functions as hotspots, it will have to compile each of those functions separately which will require additional work.

据说我相信假设foo永远不会被子类化应该是无效的。您不能假设其他人不想继承您的对象或想要扩充对象的原型。目前这是不可能的。想象一下,我想改变foo.STATIC_CONSTANT。我不能,因为每次我构造一个新的foo时,它将覆盖我改变的foo.STATIC_CONSTANT。对于我可能想做的任何其他扩充也是如此。

That being said I believe the assumption "foo will never be subclassed" shouldn't be valid. You cannot assume that others won't want to inherit from your object or would like to augment the prototype of your object. This is currently not possible. Imagine I would like to change foo.STATIC_CONSTANT. I couldn't, because each time I construct a new foo, it will override my changed foo.STATIC_CONSTANT again. Same is true for any other augmentation I might like to do.

所有这些问题都不会出现在第二个正确的面向对象的javascript 模式中。

All these problems do not arise in the second, correct object oriented javascript pattern.

这篇关于如果类永远不会被子类化,原型在JavaScript中真的很重要吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆