大家喜欢用 JavaScript 中哪一种继承方式?大家来说说自己的看法 OwO

2015-06-12 21:47:09 +08:00
 bramblex

JavaScript继承主要是两种形式:
1. 原型链继承
2. 拷贝继承

注:ES7标准中的class就暂时不考虑了,因为还没有具体去了解过,希望以后能完善到不需要自己实现那么那么蛋疼的东西了。

我个人倾向于原型链继承,因为原型链继承是JavaScript规范里面推荐的继承,并且最重要的是,可以用原生的 instanceof 判断类型!而拷贝继承不行!


因为以上的一些问题,所以我就自己做了一个简单的JavaScript面的对象库。大概有实现这么几个功能:
1. 封装好的构造函数不管写不写new操作符都不会产生错误了,当然我是倾向于不写new操作符。
2. 返回的构造函数是命名的,方便调试的时候追踪函数栈。
3. 封装了一个parent方法,可以方便访问父原型的构造函数或者父原型的方法。
4. 封装了一个alias方法,可以创建一个方法别名。

具体实现在具体实现在github上 >> 代码传送门

接下来来看一些简单的示例来看看怎么用。

// 首先定义一个Animal类(姑且称为类吧),继承自Objec,有一个构造函数。
var Animal = BlxClass.extend('Animal', Object, function(name, sound){
  this.name = name || null;  
  this.sound = sound || null;
});

Animal.prototype.call = function(){
  console.log(this.sound);
};

// 现在我希望定义一个doge类,继承自Animal。第一个参数 ‘Doge’ 是用来给构造函数命名的。
var Doge = BlxClass.extend('Doge', Animal, function(name){
  var sound = 'wang';
  BlxClass.parent(this, Doge, [name, sound]); // 调用父类的构造函数,因为初始化对象属性在父类构造函数里。
});

Doge.prototype.wang = BlxClass.alias('call');

// 现在实例化一个doge对象
var doge = Doge('Tom'); // 有没有 new 都没关系,结果相同。
doge.call(); // =>'wang'
doge.wang(); // =>'wang'

然后这样就跟其他语言类的继承大致相似了。然后大家更喜欢哪一种继承方式呢?都来说说自己看法吧。

4541 次点击
所在节点    JavaScript
54 条回复
arbipher
2015-06-13 15:49:27 +08:00
我建议使用ES6的class关键字和babel
bramblex
2015-06-13 16:08:20 +08:00
@arbipher

谢谢。然而我的目的并不是要别人告诉我用什么工具,我的目的是自己实现一个。类似babel这类的complier之后我也会自己实现一个。反正作为学生党,我觉得玩玩也挺有意思的。
exoticknight
2015-06-14 18:55:53 +08:00
我觉得讨论这么多,都老是想用类的继承来写 javascript,然而 js 中的原型机制根本就不是类的机制,而是能够模拟实现类的机制。
所以要怎么用就怎么写,需要查找原型链那么就直接将 new function 的 prototype 直接等于被继承对象的 prototype。希望被继承对象不会被修改就深复制其 prototype 作为新对象的 prototype。
比如我在自己的项目中需要的只是原型链的查询实现变量作用域的嵌套
https://github.com/exoticknight/simpleTemplate.js/blob/master/simpleTemplate.advanced.js
所以用大神 Douglas Crockfor 的代码就够了。
bramblex
2015-06-14 19:20:10 +08:00
@exoticknight

但是为什么不能总是想着类继承来些JavaScript呢?类继承机制在绝大多数情况下确实比原型机制更直观也更好用。其实为什么一定要拘泥于语言本身所谓“够了”的特性,而不能追求更直观更方便更强大的特性呢?

我觉得永远都没有什么 xxxx 就够了这么一说。
exoticknight
2015-06-14 21:37:49 +08:00
@bramblex
看清楚我的表达,什么什么就够了是有条件的,不要歪曲了。不用原型链而非要用其模拟类继承并非不可以,然而若写简洁的代码就能完成任务为什么还要增其实体?
另外,我不认为“类继承机制在绝大多数情况下确实比原型机制更直观也更好用”,那是可能因为你先学了 OOP 而已。
而你所谓的“更直观更方便更强大的特性”也只是主观因素。
我也没有认为 js 超越其他语言,因为<del>PHP才是最好的语言</del>。我只是想说 js 的原型链能解决,就不要用类继承了。
当然如果你只写ES6,我无话可说。
bramblex
2015-06-14 23:29:48 +08:00
@exoticknight

如果js原型链能解决?嗯,那请问,在计算机上有什么能够用0和1解决呢?既然能解决,那干嘛还需要语言?

问题不是能不能解决,而是能不能更好的解决,尽量避免重复,尽量避免接触丑陋的底层细节,而不是“能解决”。

抱歉,我觉得我们还是就此打断这种毫无意义的价值观争端吧。欢迎讨论技术问题
exoticknight
2015-06-15 19:52:16 +08:00
@bramblex
貌似价值观问题是你先提出的
“问题不是能不能解决,而是能不能更好的解决”。我就一句话,js 上用原型链比类继承更“尽量避免重复,尽量避免接触丑陋的底层细节,而不是“能解决”。 ”
在想如何用类的时候你已经自我矛盾了。
bramblex
2015-06-15 20:08:54 +08:00
@exoticknight

然而只有论点却没有论据……
bramblex
2015-06-15 20:19:48 +08:00
@exoticknight

所以还是就此打住吧,别让这种没有营养的口水战继续下去了好吗?自始至终你根本拿不出任何证据来支撑你的论点——原形链继承比类继承好。同样的,我根本也找不出任何证据来反驳你。所以我们能不讨论这种圣战性质的谁比谁好的问题吗?

所以我们能单纯的讨论原形链继承和类继承分别有啥好有啥不好不行吗?如果不好,那我只能说一句了,PHP是最好的编程语言。
exoticknight
2015-06-15 20:31:02 +08:00
@bramblex
行,本来打算继续补充,怕你已经 block 了我所以没发。
1、原型链本身就是原生的方式,js 本身并不支持类继承,写类的 polyfill 本身就是强行加细节。
2、原型链机制在最少代码情况下用之前我贴出的代码就 ok,相反你看类继承包括你在内建了多少楼?又用了多少代码?
我也只是呼吁一下 js 有其独特的方式,写的时候多运用,而不要老想着上其他语言的那一套而已。
我在写 node 的时候觉得 inherit 也是很好的,但反对所有地方都用。
exoticknight
2015-06-15 20:33:19 +08:00
@bramblex
喂喂,分明你自己也没有提出证据全是问句啊……还直接说我了唉……
bramblex
2015-06-15 21:03:02 +08:00
@exoticknight

1. 首先我已经直说了我提不出证据反驳你啊……这个我记得我是清清楚楚写在上面了吧,不然您再仔细看看?

2. 即便你说的全都对,但是依旧没有证明你所说的“原型链继承比类继承更优”啊。能得出的结论只是我的实现比你多了几十行代码而已。

3. “我也只是呼吁一下 js 有其独特的方式,写的时候多运用,而不要老想着上其他语言的那一套而已。 ”这句话真的一点意义都没有,不行我反着给你说一遍:

我也只是呼吁一下大家要多想想其他的解决方案,写的时候多思考,而不要老是被js那一套限制住了思维而已。

4. 我不反对任何人在任何情况下写任何代码,除非我是他boss。不然我觉得我真的没有任何权力去反对别人写怎么样的代码唉,我能想象我反对别人写怎么样的代码的时候,别人会白我一眼然后淡淡回我一句:管你屁事。
exoticknight
2015-06-15 21:20:37 +08:00
@bramblex
1、我说的是更前的地方。43楼我表达了“哪里用什么就ok了没必要硬要用某模式”,44楼你自己说“类继承机制在绝大多数情况下确实比原型机制更直观也更好用。”,并没有提出证据,我说的是这里。之后我提出并非如此你反而要我提证据了。

2、如果全都对,*在使用 js 情况下*,为什么就没有证明更优?你这种情况不就是尝试在 java 中用原型链的行为不是?

3、这句话我承认自己脑子的确被驴踢了。

4、我从来没有指明反对你写什么代码,也承认类继承有其可用之处,你要写 babel 也好写 compiler 也好,管我屁事。难道我在论坛上提出观点也不行了?

还是打住吧

虽然说“如果是两个理性而真诚的真理追求者争论问题,争论的结果必然是二人达成一致。”,但是我还有其他事情要做……
bramblex
2015-06-15 21:29:47 +08:00
@exoticknight

我在46楼的时候已经说过要打住了吧……

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/198118

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX