为什么在 javascript 中使用基于类的 OOP 风格继承?

发布于 2024-07-19 07:27:03 字数 266 浏览 10 评论 0原文

如果我没有完全错的话,JavaScript 中的每个框架/库/方法现在都倾向于模仿基于类的 OOP 风格继承。 其原因似乎是人们认为基于类的 OOP 继承更容易理解,并且大多数程序员都了解 OOP。

根据我的经验,我没有找到这两种观点的证据。 我认为 javascript 原型继承就很好(而且我怀疑在一种语言上强加另一种范式而不是它所构建的范式是否有用)。 我遇到的大多数开发人员甚至在经典 OOP 方面也不是那么擅长。 那么选择经典 OOP 风格继承而不是原型继承的原因是什么?

If I'm not completely wrong every framework/library/approach in javascript tends today to mimick class based OOP style inheritance. Reasons for this seem to be people thinking class based OOP inheritance is far easier to understand and that most programmers know OOP.

In my experience I don't find evidence for either of this opinions. I think javascript prototypal inheritance is just fine (and I doubt the usefulness to force another paradigm upon a language than the one it is built on). Most of the developers I meet aren't even that good in classical OOP either. So what are the reasons to choose classical OOP style inheritance over prototypal inheritance?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

吾性傲以野 2024-07-26 07:27:04

我认为答案就在你的问题中——大多数程序员对基于类的 OOP 比基于原型的 OOP 更熟悉。

事实上,我什至可以说,大多数人不相信可以拥有没有类的对象。

I think the answer is in your question - most programmers are far more familiar with class-based OOP than prototype-based.

In fact I'd go so far as to say the majority don't believe you can have objects without classes.

冷弦 2024-07-26 07:27:04

请注意,即使您主张基于原型的 OOP,您也可以将其称为“原型”,而基于类的 OOP 只是“OOP”。 所以,你自己也遭受了这种偏见,认为 OOP=> 类,原型 => 其他的东西。

由于大多数人认为无论问题如何,OOP 都是正确的方法,那么原型一定是较差的。

所以,要回答你的问题,有两个因素:

  1. 一个错误的定义:“OOP => 类”
    • 宣传:“必须是 OOP,否则你不配”

因为你仍然受到第一个的限制,你试图解释原型是第二个的例外。 纠正它们要容易得多:

  1. 处理对象的方法有很多,类只是静态语言中最简单的一种。 大多数人都被教导使用静态语言进行编程,并且他们中的大多数人尝试使用任何语言,就像他们学的第一种语言一样。

    • 构建编程解决方案的方法有很多种,OOP 在某些方面很擅长,而在另一些方面则很糟糕。

note that even if you're arguing for prototype-based OOP, you call it 'prototypal', and class-based OOP just 'OOP'. so, you yourself suffer from this bias, thinking OOP=>classes, prototypes => something else.

and since most people think that OOP is the right way no matter the problem, then prototypes must be inferior.

so, to answer your question, it's two factors:

  1. a bad definition: "OOP => classes"
    • propaganda: "it must be OOP, or you're not worthy"

since you're still bounded by the first, you try to explain that prototypes are an exception of the second. much easier is to correct them:

  1. there are many ways to do objects, classes are just the easiest one for static languages. most people are taught to program with static languages, and most of them try to use any language just like the first one they learned.

    • there are many ways to structure a programming solution, OOP are great at some and lousy at others.
没有伤那来痛 2024-07-26 07:27:04

我觉得你好像已经知道你的问题的答案了,因为你说的时候已经说了一部分

造成这种情况的原因似乎是人
基于OOP继承的思维类
更容易理解
大多数程序员都了解 OOP。

对于解决问题,这两种范式都不比另一种更正确。 我相信主要原因是现在每个人都通过 Java 来教授 OOP。 因此,当人们遇到 OOP 时,他们会想到“哦,类”,因为这是他们所熟悉的。 每当他们想要解决问题时,他们很可能会使用他们所知道的东西。

我还要指出的是,使用他不熟悉的范例对程序员没有任何好处。 我们大多数人必须使用 javascript 进行客户端 Web 开发,并在服务器上使用基于类的 OOP 语言。 每当我不得不查看应用程序的 javascript 端时,我个人都不希望 OOP 阻抗不匹配。

在某种程度上,每个人都试图在 javascript 中实现基于类的 OOP 这一事实是一个教育问题。 从另一个层面来说,这是心理层面的。

I feel as if you already know the answer to your question because you stated a part of it when you said

Reasons for this seem to be people
thinking class based OOP inheritance
is far easier to understand and that
most programmers know OOP.

Neither paradigm is more right than the other for tackling a problem. I believe the main reason is that everyone is taught OOP through Java these days. So when people encounter OOP they think "oh classes" because it's what they are familiar with. And whenever they want to solve a problem they will most likely use what they know.

I would also state that it does no benefit for the programmer to use a paradigm he is unfamiliar with. Most of us must use javascript for client side web development and use a class based OOP language on the server. I personally would not want that OOP impedance mismatch whenever I had to look at the javascript side of an application.

At a certain level the fact that everyone is trying to implement class based OOP in javascript is an educational issue. At another level it's a psychological one.

沫离伤花 2024-07-26 07:27:04

很长一段时间,我认为基于原型的 OOP 是基于类的 OOP 的弱、糟糕和错误版本。 然后,在大量信息渗入我的头脑之后,我现在以更抽象的方式理解 OOP,并且发现这两种方式总体上都是可以接受的。

For a long time I considered prototype-based OOP as weak, bad and wrong version of class-based OOP. Then, after a critical amount of information leaked into my head, I now understand OOP in more abstract way, and find both ways acceptable in general.

得不到的就毁灭 2024-07-26 07:27:04

那么选择经典 OOP 风格继承而不是原型继承的原因是什么?
实际上,我相信某些框架是“某种”组合方法。 以寄生组合继承模式为例。 这就是 YAHOO.lang.extend 正在做的事情。

它使用原型继承和辅助函数来继承原型和构造函数窃取。 哇,这听起来很复杂......是的,它是 - 例如,这是我的实现和测试:

// Prototypal Inheritance
Object.prototype.inherit = function(p) {
    NewObj = function(){};
    NewObj.prototype = p;
    return new NewObj(); 
};

// Paraphrasing of Nicholas Zakas's Prototype Inheritance helper
function inheritPrototype(subType, superType) {
    var prototype = Object.inherit(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
};
function SubType(name, age) {
    Parent.call(this, name);
    this.age = age;    
};
inheritPrototype(SubType, Parent);  
SubType.prototype.getAge = function() {
    return this.age;
};

我对此代码进行了测试:

   describe 'Parisitic Combination Inheritance'
 it 'should use inheritPrototype (to call parent constructor once) and still work as expected'
     sub = new SubType("Nicholas Zakas", 29)
     sub.toString().should.match /.*Nicholas Zakas/
     sub.getAge().should.eql 29
     charlie = new SubType("Charlie Brown", 69)
     charlie.arr.should.eql([1,2,3])
     charlie.arr.push(999)
     charlie.arr.should.eql([1,2,3,999])
     sub.arr.should.eql([1,2,3]) 
     sub.should.be_an_instance_of SubType
     charlie.should.be_an_instance_of SubType
     (sub instanceof SubType).should.eql true 
     (sub instanceof Parent).should.eql true 
 end
    end

当然,如果您注意我的文字,您会看到:Nicholas Zakas,那个家伙我从 ;) 这一个的重大胜利:instanceof 工作(有人说很重要,我有点同意); 实例不共享引用类型(如数组)的状态(这是一个大问题!); 父构造函数只调用一次(很重要!)。

顺便说一句,我在这里提供了大多数流行继承模式的示例:我的 TDD JS 示例

So what are the reasons to choose classical OOP style inheritance over prototypal inheritance?
Actually, I believe that some frameworks are "sort of" combining approaches. Take for example the Parasitic Combination Inheritance pattern. This is what YAHOO.lang.extend is doing.

It uses prototypal inheritance and a helper function to inherit prototypes and constructor stealing. Wow, that sounds complex...well yes it is - here's my implementation and test for example:

// Prototypal Inheritance
Object.prototype.inherit = function(p) {
    NewObj = function(){};
    NewObj.prototype = p;
    return new NewObj(); 
};

// Paraphrasing of Nicholas Zakas's Prototype Inheritance helper
function inheritPrototype(subType, superType) {
    var prototype = Object.inherit(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
};
function SubType(name, age) {
    Parent.call(this, name);
    this.age = age;    
};
inheritPrototype(SubType, Parent);  
SubType.prototype.getAge = function() {
    return this.age;
};

I have a test for this code:

   describe 'Parisitic Combination Inheritance'
 it 'should use inheritPrototype (to call parent constructor once) and still work as expected'
     sub = new SubType("Nicholas Zakas", 29)
     sub.toString().should.match /.*Nicholas Zakas/
     sub.getAge().should.eql 29
     charlie = new SubType("Charlie Brown", 69)
     charlie.arr.should.eql([1,2,3])
     charlie.arr.push(999)
     charlie.arr.should.eql([1,2,3,999])
     sub.arr.should.eql([1,2,3]) 
     sub.should.be_an_instance_of SubType
     charlie.should.be_an_instance_of SubType
     (sub instanceof SubType).should.eql true 
     (sub instanceof Parent).should.eql true 
 end
    end

And of course, if you're paying attention to my literals you see: Nicholas Zakas, the guy I got this from ;) The big wins for this one: instanceof works (big deal some say and I kind of agree); instances don't share state on reference types like arrays (a biggie!); parent constructor only called once (a biggie!).

BTW, I have examples of most of the popular inheritance patterns here: My TDD JS Examples

半夏半凉 2024-07-26 07:27:04

我认为,语言本身通过选择“新”作为关键字,并在语言规范中引入“构造函数”等概念,引导人们进入经典思维模式。 在某种程度上,这是有限的——想象一下,如果我们有一个克隆关键字,以及特质的概念,那么思维方式会发生什么变化。

I'd argue that the language itself steers people into the classical mindset with it's choice of "new" as a keyword, and by introducing concepts like "constructors" in the language specification. In a way this is limiting - imagine the change in mindset if instead we had a clone keyword, and the concept of traits ala SELF.

独夜无伴 2024-07-26 07:27:04

当我编写第一个脚本时,拥有如此简单的语言非常酷且方便。
但今天您不仅仅想切换按钮颜色,您还想用 JavaScript 构建复杂的应用程序。 其他人可能喜欢使用您流行的应用程序,并且希望看到社区提供插件。

现在,使用 OOP 更容易实现这一点 - 特别是因为很多程序员都熟悉 OOP 概念。

When I was writing my first scripts, it was cool and handy to have such a simple language.
But today you do not just want to toggle a buttoncolor, you want to build complex applications in JavaScript. Others might like to use your popular application and would love to see s community providing plugins.

Now, this is much easier to realize with OOP - especially because a lot of programmers a familiar with OOP concepts.

小ぇ时光︴ 2024-07-26 07:27:04

原因之一可能是您的服务器端可能是面向对象的(ASP.NET、Java 等),因此在客户端上以相同的范例进行思考会更容易。 不一定更好,但更容易。

One reason may be that your server side is likely to be OO (ASP.NET, Java, etc.), so it's just easier to think in the same paradigm on the client. Not necessarily better, but easier.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文