V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
WarWithinMe
V2EX  ›  JavaScript

不用class的JS程序员是野生程序员?

  •  
  •   WarWithinMe · 2013-02-04 22:01:14 +08:00 · 9525 次点击
    这是一个创建于 4311 天前的主题,其中的信息可能已经有所发展或是发生改变。
    前因:我不止一次地被问倒“请用JS写一个类,然后再写一个子类来继承它”。当谈及为什么要写一个类的时候。提问者往往会回答“因为面向对象能够让我们复用代码,多态,应对不同的产品需求,blah blah blah”。然后如果你答不出的话,大概就被认为是个野生程序员,能力底下之类。

    但是,在JS里面,为了实现封装、多态的目的,真的只能用“类”这种方式吗?我觉得JS提供的匿名函数、闭包等特性就能够达到代码封装和可扩展的目的。

    我怎么就觉得他们认为写代码就是要面向对象,面向对象就是要写类。。。

    很想听一下大家的看法。
    64 条回复    1970-01-01 08:00:00 +08:00
    binux
        1
    binux  
       2013-02-04 22:03:14 +08:00
    作为野生程序员,我确实从不写类
    RTNelo
        2
    RTNelo  
       2013-02-04 22:04:42 +08:00
    好吧。。。没写过JS。。。只对那句“我怎么就觉得他们认blablabla”评论一下。。。
    RTNelo
        3
    RTNelo  
       2013-02-04 22:07:19 +08:00
    @RTNelo 哦*。。。我怎么回复过去了。。。一般情况下我是一边写一边改(Python)。。。有代码用到2次(及以上)的就写成函数。。。相关联的函数多了有可能就搞成一个类。。。相关联的类多了可能会放到一个模块里。。。blablablabla
    WarWithinMe
        4
    WarWithinMe  
    OP
       2013-02-04 22:20:38 +08:00
    @RTNelo 主要是我觉得用JS其他的特性也能实现和“类”能做的事情,但说如果不用类来做这些事情就是野生的话,那我就真的只能理解他们是为了写类而写类。。
    WarWithinMe
        5
    WarWithinMe  
    OP
       2013-02-04 22:21:49 +08:00
    @binux 你是真野生还是伪野生。。。。
    davidx
        6
    davidx  
       2013-02-04 22:24:43 +08:00   ❤️ 1
    那用jQuery的都是野生的了?
    binux
        7
    binux  
       2013-02-04 22:26:51 +08:00
    @WarWithinMe w3school毕业真野生
    zythum
        8
    zythum  
       2013-02-04 22:54:37 +08:00
    js属于prototype继承,原生并没有super的概念。这些东西都是用各种蛋疼的方式做出来的。
    所以js的继承都不是完全的。并且也没有虚函数的概念所以所有的约定都不是强制的。这些所谓的设计模式感觉是为了设计模式而设计模式。

    需要的时候可以做一些。但是不要太过于使用继承。做1,2层就可以了。
    尽量做调用。类似于oc的概念。
    kran
        9
    kran  
       2013-02-04 23:05:05 +08:00
    越来越少写类了
    xvfeng
        10
    xvfeng  
       2013-02-04 23:18:06 +08:00
    try coffee
    tux
        11
    tux  
       2013-02-04 23:18:12 +08:00
    别人问就说自己不会编程,自己写自己的~
    viator42
        12
    viator42  
       2013-02-04 23:25:31 +08:00
    用Extjs算什么程度?
    iwinux
        13
    iwinux  
       2013-02-04 23:57:56 +08:00   ❤️ 1
    楼主可以把 Organizing Programs Without Classes 这篇经典论文印出来摔他们脸上……
    wang2191195
        14
    wang2191195  
       2013-02-05 00:02:09 +08:00 via iPhone
    为了面向对象而面向对象 也只能哦了
    qq286735628
        15
    qq286735628  
       2013-02-05 00:18:10 +08:00
    野生的~
    都是prototype,都是对象~
    说不定过几年,正统的类会完整继承JAVA的那些个特性.....
    j
        16
    j  
       2013-02-05 01:41:50 +08:00
    没必要给野生主管干活吧!
    用原生js随便写一个class的实现就好了~
    qzwex2006
        17
    qzwex2006  
       2013-02-05 09:56:48 +08:00
    面向对象只是一种思想0 0
    不管什么方法能解决问题, 并且更好的解决就行吧.
    DrWeb
        18
    DrWeb  
       2013-02-05 10:40:52 +08:00
    javascript是原型继承,并不是一个完全的面向对象的语言,类这个东西,js里没有.Javascript本身并不支持面向对象,它没有访问控制符,它没有定义类的关键字class,它没有支持继承的extend或冒号,它也没有用来支持虚函数的virtual.如果一定要用也可以,不过没必要的话就算了吧,不是什么语言都一定要用面向对象的.
    zhangxiujiao
        19
    zhangxiujiao  
       2013-02-05 10:49:57 +08:00
    @DrWeb 建议你把面向对象的三大要素在复习下
    aisk
        20
    aisk  
       2013-02-05 10:56:59 +08:00
    @DrWeb 真想找个什么东西糊你脸上啊。。。
    DrWeb
        21
    DrWeb  
       2013-02-05 11:04:07 +08:00
    @aisk 干吗呀,说得不对你就指出来呗,这么鄙视我干什么
    DrWeb
        22
    DrWeb  
       2013-02-05 11:05:06 +08:00
    @zhangxiujiao 你还是直接说错在哪吧
    willerce
        23
    willerce  
       2013-02-05 11:23:33 +08:00
    @zhangxiujiao @aisk 请问二位大神,@DrWeb 说的错在哪?面向对象,封装、继承、多态。ECMA Script 有定义这些实现方法么?
    zythum
        24
    zythum  
       2013-02-05 11:24:59 +08:00
    @zhangxiujiao
    @aisk

    @DrWeb 说的是没有错的。除了"Javascript本身并不支持面向对象", 因为Javascript本身什么都是对象。但是是prototype继承,并没有java那么好的继承逻辑。所有的规定都需要人去遵守,并不是强制,那么虚函数和super都是各种的问题和漏洞。现在没有一个框架的super是完美的。

    设计模式什么的看看是没错,但是不能所有的东西都套着设计模式来。可以写个数据类,写个简单的所谓的基类使得代码可读。但是不要过度得这么玩。会死很惨。就像我现在维护的前人的代码一样。
    liudao
        25
    liudao  
       2013-02-05 11:27:14 +08:00
    DrWeb
        26
    DrWeb  
       2013-02-05 11:27:15 +08:00
    @zhangxiujiao
    @aisk
    js语法中确实没有类这个说法,你们想表达什么
    WarWithinMe
        27
    WarWithinMe  
    OP
       2013-02-05 11:30:43 +08:00
    @davidx 当时说我平常用的jquery。。。然后是无尽的鄙视。。.
    @zythum 我觉得前端的代码并不像其他程序一样需要复杂的结构,也觉得has-a要比is-a反而要好一些。
    zythum
        28
    zythum  
       2013-02-05 11:41:58 +08:00
    @WarWithinMe os也是has-a的思想。同样也能写复杂的结构。现在js也是越来越复杂了。今年各种个样的mvc都出现了。都没时间看。瞬间感到落伍了有木有。复杂并不可怕,主要是代码的可读,可维护很重好。朱一在这方面一直做的不好。在慢慢改进中。
    sivacohan
        29
    sivacohan  
       2013-02-05 11:49:36 +08:00
    "因为面向对象能够让我们复用代码,多态,应对不同的产品需求,blah blah blah”
    尼玛,说的好像函数就不能复用,回调函数就不能多态了一样……
    WarWithinMe
        30
    WarWithinMe  
    OP
       2013-02-05 11:52:57 +08:00
    @zythum 我意思是你用has-a的思想的话,就不用建立一整套很复杂的类结构。。。不然的话,你要想弄明白这个结构的话你得去看整个类结构。MVC是为了那种像gmail这样的web app而设的吧。。。但是像gmail这样的web app又有多少呢。。。国内的前端不就是给各种连接,各种按钮,各种输入框加入些功能而已嘛。。
    zythum
        31
    zythum  
       2013-02-05 12:30:02 +08:00
    @WarWithinMe 其实微博的构架已经近似app了。基本不刷页的。只有在不用产品线之间做跳页。因为开发的团队不一样。

    类结构可以不复杂。可以简单的做一些规范。便于阅读。不要一层套一层就可以了。
    luikore
        32
    luikore  
       2013-02-05 12:52:27 +08:00
    写 class 的都是不懂 js 的半吊子
    用 class 的还要折腾元对象协议才能有 prototype 一半功能...
    aisk
        33
    aisk  
       2013-02-05 13:14:59 +08:00
    @zythum @DrWeb @willerce
    我来说@DrWeb 的错误
    访问控制符一向都不是面向对象必须的,Python基本上就处于没有的状态(除了那个“__”,不过也是不提倡使用的,而且也并不能真正隐藏属性)。虚函数这个概念对于有鸭子类型的动态语言就更没什么意义,js里要真有虚函数真是搞笑了。js用原型继承,当然用不到extends一类的关键词,原型继承和类似模板的类继承只是两个不同的思路。
    cyberscorpio
        34
    cyberscorpio  
       2013-02-05 13:51:20 +08:00
    程序员要:
    以野生为荣,以家养为耻。


    楼下继续。。。
    zhangxiujiao
        35
    zhangxiujiao  
       2013-02-05 14:07:52 +08:00
    这个问题就不要争了,你们让我想起了那句经典的台词——php是世界上最美的语言。javascript到底是不是面向对象的,JavaScript.The.Definitive.Guide里解释的很详细,没看过的建议去翻翻。另外,理解面向对象不要用java,c#的规则去生搬硬套。
    davidx
        36
    davidx  
       2013-02-05 14:29:04 +08:00
    @WarWithinMe 你也鄙视他吧, 一顿胡吹...
    clowwindy
        37
    clowwindy  
       2013-02-05 14:54:07 +08:00
    一般说到 js 的“类”,指的都是用 Cat.create 模拟类方法,Cat.prototype.walk = function(){...} 模拟实例方法, Cat.prototype = new Animal() 来模拟继承的写法。
    你可以说你用了“类”,也可以说你用了 prototype。这只是说法的问题。

    不管它叫什么,如果不用这种写法,你不大容易写出一个可以复用的组件,比方说一个数据表格,或者一个下拉菜单,或者一个可以随处摆的 like 按钮,使你的 ***下游用户*** 能仅仅通过创建一个你的对象出来,通过匿名函数、闭包等特性传入回调,调用对象上的方法,就能轻松使用你写的组件。(还记得你是怎么使用 jQuery 的吗?)
    DrWeb
        38
    DrWeb  
       2013-02-05 14:58:42 +08:00
    原来@别人要消耗那个什么金钱,-_-!,那我不@了。

    首先,javascript是不是面向对象,这个要看语境,我观楼主的意思,那肯定就是说主流java、c#之流的面向对象,我打赌楼主自己应该也是这意思,所以我是在传统面向对象的环境下说“并不是一个完全的面向对象的语言”,以及提到了一些普通意义上的面向对象的相关东西。

    两位大神一下就看到了“JS不是面向对象”,好吧,我承认我等是野生程序员,看书自学的,比不得二位一代宗师,已达到了“手中无剑,心中有剑”的至高境界,一切皆对象。这个可以有,我也说了可以某些方法实现。不巧二位传奇驾临我们这小位面,我等讨论的境界低了,惭愧、惭愧!

    至于JavaScript是不是面向对象,这得看怎么说,细一点讲,Javascript语言实际上是两种语言风格的混合产物----(简化的)函数式编程+(简化的)面向对象编程。
    这是由Brendan Eich的设计思路决定的:

     (1)借鉴C语言的基本语法;

     (2)借鉴Java语言的数据类型和内存管理;

     (3)借鉴Scheme语言,将函数提升到"第一等公民"(first class)的地位;

     (4)借鉴Self语言,使用基于原型(prototype)的继承机制。

    作为第一个主流的lambda语言,相对Java来说,其与Lisp和Scheme有更多的共同点(JavaScript: The Good Parts里有解释,没看过的建议去翻翻)。

    他只有简单的面向对象。

    当然,Brendan Eich作为设计者,他一点也不喜欢自己的这个作品:
    "与其说我爱Javascript,不如说我恨它。它是C语言和Self语言一夜情的产物。十八世纪英国文学家约翰逊博士说得好:'它的优秀之处并非原创,它的原创之处并不优秀。'(the part that is good is not original, and the part that is original is not good.)"


    哦,对了至于面向对象的至高境界,建议移驾云风的一篇文章
    http://blog.codingnow.com/2010/03/object_oriented_programming_in_c.html
    去观看,不是不可以,玩玩嘛,蛮好的,但是我觉得什么语言你干什么事,按着语言设计思路来保险点。
    yun77op
        39
    yun77op  
       2013-02-05 15:02:15 +08:00
    js中的class是通过new function实现的,方式和传统的java那种不一样,并不是说不存在

    复用代码的核心(之一)是模块化,场景不同可以使用直接使用对象、工厂模式、Cached Functions in the Module Pattern、prototype模式等

    “觉得JS提供的匿名函数、闭包等特性就能够达到代码封装和可扩展的目的” 不是可以实现就可以,还要考虑可维护性
    Narcissu5
        40
    Narcissu5  
       2013-02-05 15:09:12 +08:00
    其实看到这个帖子我就想说原型继承到底是不是面向对象也是程序界的热点圣战之一。翻了翻回复发现根本不用说,已然掐起来了-_-!
    FrankFang128
        41
    FrankFang128  
       2013-02-05 16:24:27 +08:00   ❤️ 1
    明明是面向对象,为什么要面向类呢?
    leegorous
        42
    leegorous  
       2013-02-05 18:05:08 +08:00
    曾经我也迷信继承什么的,后来用多了才发现不用那么麻烦,使用组合更好更灵活。而使用组合,也是面向对象的一种方式,路子不必自己越走越窄了。

    野生?相对的是什么,饲养的程序员?
    kernel1983
        43
    kernel1983  
       2013-02-05 18:11:43 +08:00
    CMU取消面向对象课程, 已经是前年的事情了, 搞不懂还有人在执着个啥?

    http://developers.slashdot.org/story/11/03/26/0016229/cmu-eliminates-object-oriented-programming-for-freshman
    krazy
        44
    krazy  
       2013-02-05 19:39:06 +08:00
    面试的时候也就这些好问了吧..
    闭包是什么?怎么实现继承?用过jquery没?

    有些书上,是把类式继承比原型式继承更适合其他程序员理解当作优点的..
    WarWithinMe
        45
    WarWithinMe  
    OP
       2013-02-05 20:25:27 +08:00
    @yun77op 可维护性这种东西比较主观。但我觉得很多情况不同方法应该都有差不多的可维护性。其实我本意不是说JS不要写Class什么的。而是觉得过分强调只有类才能"拯救世界"是不是有点太过盲目了。
    iwege
        46
    iwege  
       2013-02-05 20:54:35 +08:00
    一般不是过分强调类,因为现在这种类oo的开发方式多起来了,所以才需要对方了解这个东西,不然不好介入实际的开发。如果对方的开发当中有用到这个玩意,你不理解,他就知道这个项目当中你可以操作的部分有哪些。

    其实这里最关键,能理解原型继承就ok了。如果应聘者不理解,但是OO是自己项目当中又是一块核心,招募进来就需要自己教育了。


    继承这块也算是JS的基础知识了,问两句没什么的。至于说要不要写Class,还是要看场景,一般来说就算不写Class,也会用类似的方式实现。



    另外关于野生:JS哪里有非野生的?哪个学校现在教JS?
    WarWithinMe
        47
    WarWithinMe  
    OP
       2013-02-16 15:31:50 +08:00
    @iwege 其实是他们的leader后来问我有没有考虑过如何做大规模的软件开发。。。。。其实言下之意是觉得这样不用Class的程序员很野生,只会写一些小应用。。。但其实每种语言有他自己的写法,不代表不理解OO和代码维护什么的。。。。所以我觉得他们的思维太过狭窄了。
    RisingV
        48
    RisingV  
       2013-02-17 13:02:34 +08:00
    Javascript语言实际上是两种语言风格的混合产物(简化的)函数式编程+(简化的)面向对象编程。这是由Brendan Eich(js原作者)(函数式编程)与网景公司(面向对象编程)共同决定的。

    所以不必纠结是class还是function,它本身就不纯粹
    RisingV
        49
    RisingV  
       2013-02-17 13:05:18 +08:00
    @kernel1983 有没有看清楚啊?是取消大一的面向对象课程(本身过早接触就不合适),大二再上。毕竟面向过程是面向对象基础
    RisingV
        50
    RisingV  
       2013-02-17 13:09:59 +08:00
    @WarWithinMe 这话说对了,语言有自己的写法,把自己熟悉的语言的思维方式迁移到自己可能陌生的语言这种做法太狭隘。而且诞生比较早的语言本身,也受到芯片性能瓶颈和编程语言理论发展程度的限制
    RisingV
        51
    RisingV  
       2013-02-17 13:14:55 +08:00
    @leegorous 没错,组合(聚合)+duck typing也是OO的一种良好实现(Go就是这么做的),没有人说过继承是OO的绝对内涵
    heroicYang
        52
    heroicYang  
       2013-02-17 13:51:29 +08:00
    噢...又浮起来了...这个得看具体的应用场景!
    reusFork
        53
    reusFork  
       2013-02-17 13:53:46 +08:00
    复用代码不一定要用到面向对象,用面向对象不一定要用到类,用类也不一定要用到继承
    对js这种弱类型语言来说,多态这个概念根本不需要引入,因为不做静态类型检查

    野生动物的生存能力显然比驯化了的要强,所以用野生来形容能力低下不适当
    chunshuai
        54
    chunshuai  
       2013-02-17 16:24:50 +08:00
    野生不野生 无所谓。 JS 关键是 得闭包
    arkilis
        55
    arkilis  
       2013-02-17 17:11:06 +08:00
    为了对象而对象,这样合适吗?
    jiyinyiyong
        56
    jiyinyiyong  
       2013-02-17 23:49:26 +08:00
    野生.. 后来终于接触到 OOP 相关内容时那个难懂,
    想了很多天, 最后觉得 `this` 和 `__proto__` 组合基本上 `class` 不用么
    结果就想不通, 纠结了又好几天, 还在网上问啊
    http://stackoverflow.com/questions/14019655/how-about-simulating-objects-with-javascript-objectsrather-than-constructors
    请教过一个学长, 他在学校精通 C++ C# Java, 面向对象头头是道
    从 JS 入门, 跟人家真是没法比了
    supersheep
        57
    supersheep  
       2013-02-18 10:20:39 +08:00
    野生好味。
    dreampuf
        58
    dreampuf  
       2013-02-18 11:06:32 +08:00
    我觉得他们是想让你的程序更加抽象,易维护。
    OO只是一种手段,上面各位执着Class才能OO的童鞋,你让那些写C的大叔情何以堪。

    OO提供的抽象多态封装继承无非都是为了解决软件工程规模的问题,他们都只是总结良好的经验,但是条条大路通罗马,非得限制哪一条就是自己死板。
    GreatHan
        59
    GreatHan  
       2013-02-18 11:48:35 +08:00
    组合比继承要好
    gouflv
        60
    gouflv  
       2013-02-18 13:04:03 +08:00
    目前coffee是最简单的实现方法
    有些时候 jq的写法确实不利于维护, 而很多jq插件的内部其实也是new Class
    WarWithinMe
        61
    WarWithinMe  
    OP
       2013-02-18 13:44:32 +08:00
    @dreampuf Cannot agree more...
    chone
        62
    chone  
       2013-02-20 17:54:15 +08:00
    恰当使用类确实能提高代码质量,另外用原型继承模拟类继承,很多时候能让项目更健壮,更容易维护,而且熟悉基于类的面向对象的程序员更容易找。
    WarWithinMe
        63
    WarWithinMe  
    OP
       2013-02-20 19:08:18 +08:00
    @chone 继承会导致强耦合。。。
    chone
        64
    chone  
       2013-02-20 21:53:56 +08:00
    @WarWithinMe 耦合性太高会导致问题的两类东西就不应该是class和subclass的关系吧,耦合不是绝对的贬义词。只有稳定性要求非常高的的系统才需要尽可能的避免这样的情况,我能想到的生态系统算是一个吧,还有一个能想到linux肯定不是这样的系统。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5570 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 47ms · UTC 09:22 · PVG 17:22 · LAX 01:22 · JFK 04:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.