JavaScript原型继承的缺点是什么?

Dan*_*don 21 javascript inheritance prototype-programming

我最近观看了Douglas Crockford的JavaScript演示文稿,他对JavaScript原型继承表示赞赏,好像它是切片白面包以来最好的东西.考虑到克罗克福德的声誉,它可能很好.

有人可以告诉我JavaScript原型继承的缺点是什么?(例如,与C#或Java中的类继承相比)

Aln*_*tak 8

根据我的经验,一个显着的缺点是你不能通过在闭包中封装变量来模仿Java的"私有"成员变量,但仍然可以访问随后添加到原型中的方法.

即:

function MyObject() {
    var foo = 1;
    this.bar = 2;
}

MyObject.prototype.getFoo = function() {
    // can't access "foo" here!
}

MyObject.prototype.getBar = function() {
    return this.bar; // OK!
}
Run Code Online (Sandbox Code Playgroud)

这使得被教导使成员变量成为私有的OO程序员感到困惑.

  • @ gion_13你在创建的是一个私有的**static**变量,该变量在MyObject的所有其他实例之间共享.拥有真正的私有实例变量的唯一方法是通过功能OOP,它不使用原型. (3认同)
  • @Rice不,它不止于此 - 原型中的函数无法访问_their own_"private"变量,更不用说基类中的任何内容了. (2认同)

jfr*_*d00 5

在Javascript中对现有对象进行子类化而不是继承自C++中的类时,我会想到的事情:

  1. 无论哪个开发人员编写它,都没有标准(内置到语言)编写它的方式看起来相同.
  2. 编写代码并不像C++中的类头文件那样自然地产生接口定义.
  3. 没有标准的方法来执行受保护的和私有的成员变量或方法.某些事情有一些惯例,但不同的开发人员也会采用不同的方式.
  4. 当您在定义中犯了愚蠢的输入错误时,没有编译步骤可以告诉您.
  5. 你想要它没有类型安全.

不要误解我的意思,javascript原型继承的方式与C++相比有很多优点,但这些是我发现javascript工作不太顺畅的地方.

4和5与原型继承没有严格的关系,但是当你有一个包含很多模块,很多类和很多文件的大型项目而你希望重构某些类时,它们会发挥作用.在C++中,您可以更改类,更改尽可能多的调用者,然后让编译器找到需要修复的所有剩余引用.如果您已添加参数,更改的类型,更改的方法名称,移动的方法等...编译器将显示您需要解决的问题.

在Javascript中,没有简单的方法来发现需要更改的所有可能的代码片段,而不是逐字地执行每个可能的代码路径,看看你是否错过了什么或者做了一些错字.虽然这是javascript的一般缺点,但我发现它在重构大型项目中的现有类时特别有用.我已经接近一个大型JS项目的发布周期结束,并决定我不应该做任何重构来解决问题(即使这是更好的解决方案),因为没有找到所有可能的后果的风险JS中的变化比C++高得多.

因此,我发现在JS项目中进行某些类型的与OO相关的更改风险更大.

  • 图4和5是关于具有动态类型的JavaScript,而不是关于原型的. (4认同)
  • 在我用C++实现它们之前,我*不要错过"声明"我的函数 (2认同)
  • 这听起来更像是JS的一般缺点,而不是那些与Prototype继承有关的缺点. (2认同)