2012年7月31日星期二

阮一峰的网络日志

阮一峰的网络日志


小额支付试验的结果

Posted: 30 Jul 2012 07:47 PM PDT

去年5月,Google关闭了我的Adsense广告账户。

我在网上宣布,由于没有了广告收入,我决定卖文。还承诺一年之后,公布收到多少钱。

现在一年过去了,今天我就公布结果。

需要道歉的是,晚了两个月。5月底的时候,有一家报纸对这个题材有兴趣。我就想先发表在报纸,再公布在网志。谁知报社最后还是没发表,整件事就这样拖下来了。

下面的文章,就是我给报纸的稿子。根据要求,字数1500字,内容针对非专业读者,没有进行微支付的深入讨论。

==============================================================

网络卖文记

作者:阮一峰

把自己的作品放上互联网,能收到钱吗?下面就是我的亲身经历。

事情的起因是,我有一个博客网站。为了弥补网站的支出,我参加了Google公司的网络广告计划。只要访问者点击广告,我就会收到广告费。

可是一年前,Google送来一封邮件,宣布由于某种原因,我的广告账户将被关闭。也就是说,我不会再收到广告费了。虽然这笔钱并不多,但是毕竟少了一笔收入,我感到很不情愿。

思前想后,我决定正好借这个机会,做一个试验:在网上出售自己的文章,看看多少人愿意付费。

2011年5月16日,我在每篇博客的底下,加上了一个按钮,上面写着四个字"付费支持"。用户点击这个按钮,就会看到这样一段话:

"如果你读了我的文章,觉得有帮助,欢迎向我支付一小笔金钱作为回报。

每篇文章的价格是0.99元人民币,或者0.99元美元。读完文章以后,如果你觉得它值这个价,欢迎付费。谢谢。

这不仅是我解决网站收入问题的一种手段,也是一个实验。一年之后,我会公布一共收到多少钱。如果微支付这条路能够走得通,就会鼓励更多的人在网络上提供高质量的内容,逐步改变中文网络的生态环境。"

猜猜结果怎么样?头一个月,每天都有人付费!

可惜好景不长,正当我欢欣鼓舞,预料之外的状况纷纷出现,种种外部限制让这个试验困难重重。对于付款阅读,我有了新的认识。

(1)中介机构收费偏高。

我的收款工具,是国内最大的网络支付平台"支付宝"。它每月前20笔交易免费,此后每笔交易收取1%的手续费,最低不少于1元,最高不超过25元。

我很快发现,如果每篇文章的定价是0.99元,还不足以弥补手续费。我不仅一分钱都收不到,而且还要自掏腰包,每笔交易另行向"支付宝"支付0.01元。出于无奈,我不得不把付款金额提高到9.9元,相当于一次性购买10篇文章。

要求读者一次性付费9.9元,无疑是偏高的,大多数报纸的定价也不过1元。可是,所有的第三方支付网站都有最低收费门槛,使得"微支付"几乎不可能实现。

(2)操作麻烦。

就算访问者愿意接受我的价格,他很快就会发现,支付过程非常麻烦。首先,必须输入用户名和密码,登录支付宝,然后才能付款。如果他的账户是空的,或者他根本就没有支付宝账户,事情就会变得复杂。他必须输入银行卡信息,直接从银行账户向我划款,这又涉及到银行网站的登录和验证。

基本上,访问者至少需要3--5分钟完成支付过程。考虑到他所要购买的只是一篇文章而已,我觉得实在没有理由让别人浪费这么多时间。很多愿意付款的人,也确实因为这个理由而懒得付款。

(3)用户体验糟糕。

真正致命的是这一点。交易应该是等价交换,可是由于我采用"先阅读,再付费"的方式,导致整个过程实际上类似捐赠。访问者并没有因为付费,而得到新的体验,付款之后,他的满意度并无变化,事实上由于付款平台的限制,我甚至无法向他显示一句"谢谢你"。

如果对一方来说,交易是否进行并无差别,只取决于你是否愿意对另一方做一些善意的补偿,那么我觉得这肯定长久不了。

因为上面这三点不利条件,付费阅读的人逐渐稀少。我慢慢开始接受一个事实:我的文章很难卖出去。

但是,我前面说过,一年之后,我会公布这个试验的结果,披露一共收到了多少钱。现在就是揭晓结果的时刻了。

从去年5月到今年5月,我一共写了88篇博客,共计收到1079笔付款,其中美元255.97元,人民币4106.04元。

这个数字算多吗?我的每篇博客,读者人数平均接近2万人。根据上面的统计,可以推算出,其中大概有12个人愿意向我付款。"转化率"(访问者转化为消费者的比率)不到0.1%,而电子商务网站的正常转化率大概是2%到5%。呜呼,付费阅读的艰难可见一斑。

我想,如此之低的转化率,说明目前阶段付费阅读还不可行。但是,另一方面,我们也必须看到,即使有各种不利条件,还是有人愿意付款。如果交易费用更低、支付过程更便利、付费后能得到实际利益,我觉得付费阅读是可行的。当然,前提是你的内容必须对读者有用。

(完)

文档信息

2012年7月25日星期三

阮一峰的网络日志

阮一峰的网络日志


蒋经国与台湾民主进程

Posted: 24 Jul 2012 09:23 PM PDT

英国《经济学家》杂志,每年公布一次"民主指数"(Democracy Index),用来评估世界各国和地区的民主程度。

2011年的评选中,台湾排在第33位,是排名最高的华人地区。(香港排名第80位,新加坡第81位,还有的地区倒数。)

为什么台湾可以推行民主制度,其他华人地区却做不到?二战结束后,台湾还是一个高度集权的社会,蒋介石实行独裁统治,为什么半个世纪之后一切完全改变?如果台湾可以在和平条件下,实现民主转变,其他地区行不行?

最近,我读完了美国人陶涵的《蒋经国传》,了解了台湾民主制度的由来,对上面这些问题有了新的认识。这本《蒋经国传》是同类书籍中最好的一本,资料详实,信息量大,叙述清晰,立场客观,推荐阅读。(以下的引文都出自该书。)

《蒋经国传》(英文版:哈佛大学出版社,2000;繁体中文版:时报出版公司,2001;简体中文版:新华出版社,2002,天津华文天下图书有限公司,2010。)

一、民主的起步

1986年3月,蒋经国在国民党十二届三中全会上,提出"政治革新"的主张,决定开放党禁报禁,允许自由成立政党、自由出版报纸。

一般把这个事件,当做台湾民主制度的开端。但是实际上,它的根源可以追溯到很久以前。

1950年,国民党退守台湾不久,就举行了第一次地方选举,95%的选民参加了投票。结果,在举行选举的四个县市之中,国民党只赢了基隆和澎湖,党外人士赢得了台南和台中的市长。1954年,最重要的台北市长选举,国民党候选人"警务处长"王民宁,居然被无党派人士高玉树击败。

由此可知,早在50年代初,台湾就有全民投票的选举。虽然,选出来的县市长没有实权,只是行政官僚,财政、立法、政策、组织、人事全掌握在国民党手中,但是至少有形式上的民主选举。

蒋介石为什么允许举行县市长普选?主要有三个原因:

  (1)1947年通过的《中华民国宪法》,规定人民有选举,罢免,创制,复决权,因此有必要落实宪法权利。

  (2)国民党在大陆被共产党击败,退守台湾后痛定思痛,决定推行一定程度的政治改革。

  (3)国民党想要守住台湾,离不开美国支持。举行选举,有助于获得美国的好感和援助。

二、蒋经国的贡献

如果台湾的选举早已有之,那么蒋经国的历史作用体现在哪里呢?

可以这样说,蒋经国将台湾民主从"形式"推进到了"实质",完成了关键的转变。他认识到,台湾处境困难,如果要想实现繁荣稳定,要想国民党真正获得台湾人的支持,必须扩大统治基础,让大多数人民参与政治决策。而实现这一目标的唯一途径,就是建立真正的民主制度。

在经济上,蒋经国推行"土地改革",让佃农获得土地,让中下阶层上升为中产阶级,防止贫富分化,以收入增长获取大多数人的支持。

在政治上,蒋经国逐步扩大民众的自由,允许反对派的存在和发展,将政治权力逐渐从外省人向本省人让渡。

"蒋经国把高级将领召集到日月潭开会。有一天晚餐后,他散步回来,有一群将领在阳台纳凉聊到把本省人晋升到高阶,在安全上有何风险。他驻足听了一会儿,打断众人谈话,他说:'各位,这是一个严肃的题目。如果我们不把本省人当做中国人看待,我们的麻烦就大了'。 蒋经国不久就让500名将军、2000名校官(全是外省人)退役,同时本省人进军校就读的人数亦稳定增加,第一个本省人亦授阶为将官。"

三、雷震和彭明敏

蒋经国的思想转变是逐步发生的。

50年代后期,有一个外省人雷震主持出版《自由中国》半月刊,鼓吹军队国家化、开放地方自治、反对蒋介石连任总统,还组建了"中国民主党"。蒋经国毫不犹豫地批准逮捕雷震,判处10年有期徒刑。

1964年,本省知识分子彭明敏反对国民党,鼓吹台独。他被逮捕后,蒋经国同意只判决有期徒刑8年,坐牢7个月后签署"悔过书",特赦出狱。

"彭明敏获释后就失业,赋閒在家。1966年初,意外地出现一位官员到访,表示蒋经国想'听听他的建言'。彭明敏踏进办公室时,蒋经国起身迎接这位前政治犯,问候他的家人,也问起有什么事需要他帮忙。鉴于蒋经国态度亲切,彭明敏表示希望能回到大学教书。蒋经国暗示他会试试看。不久,彭明敏被邀请到蒋经国的"智库"国际关系研究所担任研究员,彭谢绝了。其后几年,彭明敏继续遭到跟监,不过他偶尔仍与想法相近的知识分子来往。同时蒋经国不时派出情报人员向彭明敏表示,国民党内的自由派依然希望能说服他参与体制内的改革运动。"

由此可知,蒋经国对待反对派的态度是逐步趋向宽容的。

四、民主选举的发展

蒋经国对待民主选举的策略是,"举办干净选举、公正计票,以吸引有声望的党外人士参选,然后依靠严格的竞选限制(包括什么能说、什么不能说)以及国民党巨大的财力优势及掌控媒体,来争取多数席次的胜选。"

(1969年的立法委员选举,)"蒋经国允许各候选人史无前例地抨击政府,国民党第一次受到倾向党外的媒体的公开批评。党外候选人郭国基和黄信介,抗议本省人受到歧视,当局把极大数额岁入拨给军方等等。他们甚至要求直接民选台湾省长,结束戒严。黄信介更大胆表示,反攻大陆已经无望,如果蒋总统继续长久占着位置,对国家不利。郭国基和黄信介都当选立法委员,这代表立法院里首次出现两位真正的反对党人士。"

当年的县市选举,省议会71席议员,国民党赢得61席;15个县长席次,国民党候选人当选了14席。可是台北、高雄和台中的市长都被党外人士占据。党外势力普遍受到受过良好教育的台湾人的支持。

三年后的1972年立法委员选举,100多名党外人士在台北集会,呼吁修改选举法。这是党外人士1960年以来首度正式集会。蒋经国不断接到报告,详述党外候选人挑拨性质的言行,并建议他法办几个人,包括把发言激烈的康宁祥抓起来。幕僚还说,康宁祥是"匪谍",蒋经国不理会这些报告,反而问部属,为什么国民党籍立法委员问不出这样的问题?后来,他邀请康宁祥喝茶,两人讨论起立法议程上的一些议题。

1976年11月,举办中央及地方五项公职人员选举。投票日之前,幕僚向蒋经国报告,国民党有可能丢掉几个重要席位。蒋经国表示,党应该好好运用自己的优势,但不该允许有作弊行为。他说:"我们只要掌握51%就可以"。 这次五项公职人员竞选,总共有个1318席次,国民党只赢了76%,丢掉好几个县市长宝座。

五、新闻自由

民主制度有两大基石,除了一人一票的选举,就是新闻自由。蒋经国在推行民主选举的同时,逐步扩大新闻自由。

1975年,蒋介石去世后,蒋经国把核准新刊物登记、发行的权力,由警备总部移交到"行政院新闻局"。不过,国民党的文工会和警备总部仍然保有取缔、关闭刊物的权力。

党外人士康宁祥、黄信介申请发行《台湾政论》,获得批准。该杂志大肆进行政治批判,不仅抨击国民党,呼吁全面改选"中央民意代表",还公开要求本省人、外省人之间的权力分配要更平均。甚至发表文章,主张台湾人民若不是推翻国民党独裁政权,就只有早早跟祖国统一这条路可走。蒋经国同意警备总部的看法,认为这是"煽动叛乱",勒令停刊。

后来,康宁祥申请发行新刊物《八十年代》,黄信介申请发行《美丽岛》,都获得批准。这两本杂志都以政治评论为主,《美丽岛》的言论尤其激进,采取对抗性、法律边缘策略。很长时间内,它们都被允许出版,没有被关闭。

六、反对党的成立

集权政府向民主政府过渡,重要标志和关键就是出现一个有力的反对党。这往往是最困难的部分,因为很难想象,当权派同意将权力和利益,拱手让给反对派。蒋经国在这方面,表现出了真正的伟大之处。

1979年,蒋经国接到报告,称党外人士准备未经许可举行大型集会。蒋经国的指示是:只要守秩序,照规矩来,警方不应干预。他放出讯息,他"个人在推动对话政策"。当年12月10日,国民党举行十一届四中全会,蒋经国发表关于台湾民主的重要演讲。他说,实行民主宪政是国家政治建设应走的大道,必须继续向前迈进,决不容许后退。

1981年,蒋经国请人传话给美国驻台代表李洁明(James R. Lilley),提到他的四点计划。第一点是民主化,包括全面选举。第二点是台湾化,外省人掌权的日子行将结束,本省人必将全面逐步出任要职。第三点是"完成前两点的关键",也就是大幅提升国民所得和生活水准,这个目标则需要有更多的基础建设,更重视科技与出口。第四点,就是与中华人民共和国发展工作关系。

1984年5月,台湾的反对派人士成立"党外公政会",提出成立正式反对党的目标。内政部命令"党外公政会"解散,反对派拒绝从命。国民党则持续研商,没有结论,使得"党外公政会"看上去似乎多少有点合法性。

1986年9月28日,135个反对派在台北市圆山大饭店集会,提议即日起建立新党,取名为民主进步党。幕僚得到消息,"跑进蒋经国卧室向他报告,他点点头,没有回应,过了半小时才交代副官通知几位核心高级官员到官邸开会。党政军要员迅速赶到接待室。蒋经国坐在轮椅上出现,开口就说:'时代在变,环境在变,潮流也在变'。接下来又讲了几分鐘这类有哲学意味的话。他说,国民党过去'太骄傲、太自负',现在起,不能再跟从前一样。 虽然警备总部已准备一份抓人名单,蒋经国却说:'抓人解决不了问题......政府应该避免冲突,保持镇定'。 他指示行政院新闻局起草一份公开声明说,组织新政党的问题已在研究中,尚待做出决定,目前的政策不变:亦即没有所谓合法的反对党。因此,政府在此时并不承认民进党。他又说,国民党中常会应加快研究政治革新,公佈一个时间表,让民众瞭解党的改革方向。"

"次日,国民党中常会正式集会讨论此一问题,蒋经国重申他的论点。然后就没有再进一步讨论了。在适当程序完成前,当局不会承认民进党;但是对于民进党人士,当局也不会采取法律行动。"

1986年10月15日,国民党中常会通过了制订新的《国家安全法》以取代《戒严法》、修订《民间团体法》和《选罢法》以允许组成新政党的议案。当专案小组开始起草《国家安全法》条文时,高级情报首长建议可以让当局保存对言论自由随时管束的大权的文字时,蒋经国不同意。他说:"那不是新瓶装旧酒,换汤不换药吗!"

1986年12月的立法委员选举,民进党候选人毫无顾忌地发表各式反对言论,举起了"反对蒋家"、"反对一切暴政"的旗帜。有些漫画把蒋经国丑化为对美国人卑躬屈膝,还有些更大胆把他画成猪头猪脑。"抗议者并不仅限于言词抨击,他们焚烧国旗、国民党党旗,还有人向国民党中央党部庭院拋进一枚炸弹。此时,戒严在法律上还没有取消,警备总部再度促请蒋经国批准他们逮捕若干位民进党领袖。蒋经国依然不肯同意。他还释放13名政治犯,使得牢里的反对派人士只剩110人。"

选举结果公布,国民党得票率70%,"立法院"73席的改选席次,国民党佔了59位。民进党建党才3个月,在各项不同职务的竞选提名44人,当选23人,已经是一股不可漠视的反对力量。

七、逝世

1987年12月25日,蒋经国已经病入膏肓,距离逝世只有三个星期。

他依然坐轮椅参加行宪纪念日大会。"幕僚劝阻他,由于民进党鼓动群众抗争,情势紧张。他说:'你们怕他们打我是吧?没关系,他们要打就让他们打好了!一切照常来做'。 当他坐车前往会场时,3000名示威群众围住会场呼喊抗争口号,镇暴警察以铁丝网阻挡住他们。会场里,11个民进党籍国大代表掀出'老贼下台'的抗议布条。"

"蒋经国示意副官推著轮椅上台,欢迎掌声稍止,民进党代表继续高声喊叫。蒋经国似乎不以为意,继续向代表们简短地问好。然后他坐在轮椅上,让国民大会秘书长代为宣读大约5分鐘长的讲词。这件事过后不久,宋楚瑜拿一份杂志给经国先生看,杂志的封面故事赫然是,蒋经国有意给自己兴建一座豪华的纪念堂。蒋经国笑了:'我连给自己盖栋房子都没有,干嘛要盖个大坟墓呀?'"

1988年1月1日,在蒋经国的指示下,当局正式结束对报纸的限证(维持在29家)、限张(维持在三大张)的禁令,数天之内,就有200家左右新出版物向当局办理登记,街头立刻出现许多新兴画报。同时也有60多个政治团体申请註册成立政党。后来,包括民主进步党在内,共有20个政治组织获得通过,正式成立政党。

"1月13日上午,蒋经国抱怨身体不舒服,虽然医生一时找不到原由,还是替他注射静脉点滴。蒋经国要见见他的长子孝文。孝文见过父亲后,向母亲表示,父亲病容满面。下午1时50分左右,蒋经国在午睡中,突然发生胃肠道严重大出血。血液阻碍呼吸,使他陷入休克状态。由于他身上装置的心律调整器把心跳维持在每分鐘70,他的心臟无法快速供应氧气到全身各部位,医生还来不及把他送到医院施救,就已经撒手人寰。医师记得,当天下午天气晴朗,阳光和煦。"

"行政院新闻局在4个小时后公佈了蒋经国辞世的消息。当天夜里9点鐘,李登辉宣誓就职。中华民国有史以来第一次没有了强人,可是倒也似乎没起任何涟漪。翌晨,行政院例行院会,花了两个小时讨论河川污染防治问题。13年前,蒋介石逝世时,新闻界及高级官员使用过去帝王宫廷的生花妙语来追述撒手人寰的领袖之伟大事功。但是经国之死,不见传统的溢美讚颂和半宗教性质的諛辞。新闻媒体的评论和个人的悼词,都集中在蒋经国平凡的一面。"

八、总结

蒋经国是一个独裁者,但是他看到了民主制度的大势所趋,允许成立反对党和实现新闻自由,领导他的政党逐步让渡权力,最终使得台湾在社会基本稳定、经济没有衰退的情况下,从专制制度成功过渡到了民主制度。这就是蒋经国的历史地位,他总体上是一个正面的历史人物。

虽然台湾的民主化有其特殊的历史背景(国民党在中共和美国的双重压力之下,作为一个台湾的外来政权,必须改革求生),不具有普遍意义。但是,它终究是世界历史上少有的成功案例,尤其是在等级森严的数千年儒家文化的影响之下。蒋经国的实践表明,在坚定的勇气和决心之下,至上而下的集权社会渐进式民主转变是可以实现的。

"蒋经国在1978年可能认为自己还有十年以上的时间,可以完成台湾的民主转型。美国和台湾断交,不仅是一股强大的刺激力量,也是迈进改革的大好时机。事实上,蒋经国竟能把台湾在国际上的受挫转化为优势,一方面消除台湾本省籍人士心目中的独立意识,一方面又可用以说服外省人交出权力。80年代中期,中国、苏联和其他地方发生的种种事件,使蒋经国相信,几乎不敢想像的事也有可能实现。这些因素,加上他本身健康日益走下坡,使得他决心放手推动民主进程。当他逝世时,民主转型的工作仍有许多地方有待进一步推动。大体而言,到了1988年元月,民主政治虽然未臻完善,也相当粗糙,却已在台湾软着陆。"

(完)

文档信息

2012年7月10日星期二

阮一峰的网络日志

阮一峰的网络日志


Javascript定义类(class)的三种方法

Posted: 09 Jul 2012 08:58 AM PDT

将近20年前,Javascript诞生的时候,只是一种简单的网页脚本语言。如果你忘了填写用户名,它就跳出一个警告。

如今,它变得几乎无所不能,从前端到后端,有着各种匪夷所思的用途。程序员用它完成越来越庞大的项目。

Javascript代码的复杂度也直线上升。单个网页包含10000行Javascript代码,早就司空见惯。2010年,一个工程师透露,Gmail的代码长度是443000行!

编写和维护如此复杂的代码,必须使用模块化策略。目前,业界的主流做法是采用"面向对象编程"。因此,Javascript如何实现面向对象编程,就成了一个热门课题。

麻烦的是,Javascipt语法不支持"类"(class),导致传统的面向对象编程方法无法直接使用。程序员们做了很多探索,研究如何用Javascript模拟"类"。本文总结了Javascript定义"类"的三种方法,讨论了每种方法的特点,着重介绍了我眼中的最佳方法。

==============================================

Javascript定义类(class)的三种方法

作者:阮一峰

在面向对象编程中,类(class)是对象(object)的模板,定义了同一组对象(又称"实例")共有的属性和方法。

Javascript语言不支持"类",但是可以用一些变通的方法,模拟出"类"。

一、构造函数法

这是经典方法,也是教科书必教的方法。它用构造函数模拟"类",在其内部用this关键字指代实例对象。

  function Cat() {

    this.name = "大毛";

  }

生成实例的时候,使用new关键字。

  var cat1 = new Cat();

  alert(cat1.name); // 大毛

类的属性和方法,还可以定义在构造函数的prototype对象之上。

  Cat.prototype.makeSound = function(){

    alert("喵喵喵");

  }

关于这种方法的详细介绍,请看我写的系列文章《Javascript 面向对象编程》,这里就不多说了。它的主要缺点是,比较复杂,用到了this和prototype,编写和阅读都很费力。

二、Object.create()法

为了解决"构造函数法"的缺点,更方便地生成对象,Javascript的国际标准ECMAScript第五版(目前通行的是第三版),提出了一个新的方法Object.create()

用这个方法,"类"就是一个对象,不是函数。

  var Cat = {

    name: "大毛",

    makeSound: function(){ alert("喵喵喵"); }

  };

然后,直接用Object.create()生成实例,不需要用到new。

  var cat1 = Object.create(Cat);

  alert(cat1.name); // 大毛

  cat1.makeSound(); // 喵喵喵

目前,各大浏览器的最新版本(包括IE9)都部署了这个方法。如果遇到老式浏览器,可以用下面的代码自行部署。

  if (!Object.create) {

    Object.create = function (o) {

       function F() {}

      F.prototype = o;

      return new F();

    };

  }

这种方法比"构造函数法"简单,但是不能实现私有属性和私有方法,实例对象之间也不能共享数据,对"类"的模拟不够全面。

三、极简主义法

荷兰程序员Gabor de Mooij提出了一种比Object.create()更好的新方法,他称这种方法为"极简主义法"(minimalist approach)。这也是我推荐的方法。

3.1 封装

这种方法不使用this和prototype,代码部署起来非常简单,这大概也是它被叫做"极简主义法"的原因。

首先,它也是用一个对象模拟"类"。在这个类里面,定义一个构造函数createNew(),用来生成实例。

  var Cat = {

    createNew: function(){

      // some code here

    }

  };

然后,在createNew()里面,定义一个实例对象,把这个实例对象作为返回值。

  var Cat = {

    createNew: function(){

      var cat = {};

      cat.name = "大毛";

      cat.makeSound = function(){ alert("喵喵喵"); };

      return cat;

    }

  };

使用的时候,调用createNew()方法,就可以得到实例对象。

  var cat1 = Cat.createNew();

  cat1.makeSound(); // 喵喵喵

这种方法的好处是,容易理解,结构清晰优雅,符合传统的"面向对象编程"的构造,因此可以方便地部署下面的特性。

3.2 继承

让一个类继承另一个类,实现起来很方便。只要在前者的createNew()方法中,调用后者的createNew()方法即可。

先定义一个Animal类。

  var Animal = {

    createNew: function(){

      var animal = {};

      animal.sleep = function(){ alert("睡懒觉"); };

      return animal;

    }

  };

然后,在Cat的createNew()方法中,调用Animal的createNew()方法。

  var Cat = {

    createNew: function(){

      var cat = Animal.createNew();

      cat.name = "大毛";

      cat.makeSound = function(){ alert("喵喵喵"); };

      return cat;

    }

  };

这样得到的Cat实例,就会同时继承Cat类和Animal类。

  var cat1 = Cat.createNew();

  cat1.sleep(); // 睡懒觉

3.3 私有属性和私有方法

在createNew()方法中,只要不是定义在cat对象上的方法和属性,都是私有的。

  var Cat = {

    createNew: function(){

      var cat = {};

      var sound = "喵喵喵";

      cat.makeSound = function(){ alert(sound); };

      return cat;

    }

  };

上例的内部变量sound,外部无法读取,只有通过cat的公有方法makeSound()来读取。

  var cat1 = Cat.createNew();

  alert(cat1.sound); // undefined

3.4 数据共享

有时候,我们需要所有实例对象,能够读写同一项内部数据。这个时候,只要把这个内部数据,封装在类对象的里面、createNew()方法的外面即可。

  var Cat = {

    sound : "喵喵喵",

    createNew: function(){

      var cat = {};

      cat.makeSound = function(){ alert(Cat.sound); };

      cat.changeSound = function(x){ Cat.sound = x; };

      return cat;

    }

  };

然后,生成两个实例对象:

  var cat1 = Cat.createNew();

  var cat2 = Cat.createNew();

  cat1.makeSound(); // 喵喵喵

这时,如果有一个实例对象,修改了共享的数据,另一个实例对象也会受到影响。

  cat2.changeSound("啦啦啦");

  cat1.makeSound(); // 啦啦啦

(完)

文档信息

2012年7月5日星期四

阮一峰的网络日志

阮一峰的网络日志


Git分支管理策略

Posted: 05 Jul 2012 03:23 AM PDT

如果你严肃对待编程,就必定会使用"版本管理系统"(Version Control System)。

眼下最流行的"版本管理系统",非Git莫属。

相比同类软件,Git有很多优点。其中很显著的一点,就是版本的分支(branch)和合并(merge)十分方便。有些传统的版本管理软件,分支操作实际上会生成一份现有代码的物理拷贝,而Git只生成一个指向当前版本(又称"快照")的指针,因此非常快捷易用。

但是,太方便了也会产生副作用。如果你不加注意,很可能会留下一个枝节蔓生、四处开放的版本库,到处都是分支,完全看不出主干发展的脉络。

Vincent Driessen提出了一个分支管理的策略,我觉得非常值得借鉴。它可以使得版本库的演进保持简洁,主干清晰,各个分支各司其职、井井有条。理论上,这些策略对所有的版本管理系统都适用,Git只是用来举例而已。如果你不熟悉Git,跳过举例部分就可以了。

一、主分支Master

首先,代码库应该有一个、且仅有一个主分支。所有提供给用户使用的正式版本,都在这个主分支上发布。

Git主分支的名字,默认叫做Master。它是自动建立的,版本库初始化以后,默认就是在主分支在进行开发。

二、开发分支Develop

主分支只用来分布重大版本,日常开发应该在另一条分支上完成。我们把开发用的分支,叫做Develop。

这个分支可以用来生成代码的最新隔夜版本(nightly)。如果想正式对外发布,就在Master分支上,对Develop分支进行"合并"(merge)。

Git创建Develop分支的命令:

  git checkout -b develop master

将Develop分支发布到Master分支的命令:

  # 切换到Master分支
  git checkout master

  # 对Develop分支进行合并
  git merge --no--ff develop

这里稍微解释一下,上一条命令的--no--ff参数是什么意思。默认情况下,Git执行"快进式合并"(fast-farward merge),会直接将Master分支指向Develop分支。

使用--no--ff参数后,会执行正常合并,在Master分支上生成一个新节点。为了保证版本演进的清晰,我们希望采用这种做法。关于合并的更多解释,请参考Benjamin Sandofsky的《Understanding the Git Workflow》

三、临时性分支

前面讲到版本库的两条主要分支:Master和Develop。前者用于正式发布,后者用于日常开发。其实,常设分支只需要这两条就够了,不需要其他了。

但是,除了常设分支以外,还有一些临时性分支,用于应对一些特定目的的版本开发。临时性分支主要有三种:

  * 功能(feature)分支

  * 预发布(release)分支

  * 修补bug(fixbug)分支

这三种分支都属于临时性需要,使用完以后,应该删除,使得代码库的常设分支始终只有Master和Develop。

四、 功能分支

接下来,一个个来看这三种"临时性分支"。

第一种是功能分支,它是为了开发某种特定功能,从Develop分支上面分出来的。开发完成后,要再并入Develop。

功能分支的名字,可以采用feature-*的形式命名。

创建一个功能分支:

  git checkout -b feature-x develop

开发完成后,将功能分支合并到develop分支:

  git checkout develop

  git merge --no-ff feature-x

删除feature分支:

  git branch -d feature-x

五、预发布分支

第二种是预发布分支,它是指发布正式版本之前(即合并到Master分支之前),我们可能需要有一个预发布的版本进行测试。

预发布分支是从Develop分支上面分出来的,预发布结束以后,必须合并进Develop和Master分支。它的命名,可以采用release-*的形式。

创建一个预发布分支:

  git checkout -b release-1.2 develop

确认没有问题后,合并到master分支:

  git checkout master

  git merge --no-ff release-1.2

  # 对合并生成的新节点,做一个标签
  git tag -a 1.2

再合并到develop分支:

  git checkout develop

  git merge --no-ff release-1.2

最后,删除预发布分支:

  git branch -d release-1.2

六、修补bug分支

最后一种是修补bug分支。软件正式发布以后,难免会出现bug。这时就需要创建一个分支,进行bug修补。

修补bug分支是从Master分支上面分出来的。修补结束以后,再合并进Master和Develop分支。它的命名,可以采用fixbug-*的形式。

创建一个修补bug分支:

  git checkout -b fixbug-0.1 master

修补结束后,合并到master分支:

  git checkout master

  git merge --no-ff fixbug-0.1

  git tag -a 0.1.1

再合并到develop分支:

  git checkout develop

  git merge --no-ff fixbug-0.1

最后,删除"修补bug分支":

  git branch -d fixbug-0.1

(完)

文档信息

阮一峰的网络日志

阮一峰的网络日志


Git分支管理策略

Posted: 05 Jul 2012 03:23 AM PDT

如果你严肃对待编程,就必定会使用"版本管理系统"(Version Control System)。

眼下最流行的"版本管理系统",非Git莫属。

相比同类软件,Git有很多优点。其中很显著的一点,就是版本的分支(branch)和合并(merge)十分方便。有些传统的版本管理软件,分支操作实际上会生成一份现有代码的物理拷贝,而Git只生成一个指向当前版本(又称"快照")的指针,因此非常快捷易用。

但是,太方便了也会产生副作用。如果你不加注意,很可能会留下一个枝节蔓生、四处开放的版本库,到处都是分支,完全看不出主干发展的脉络。

Vincent Driessen提出了一个分支管理的策略,我觉得非常值得借鉴。它可以使得版本库的演进保持简洁,主干清晰,各个分支各司其职、井井有条。理论上,这些策略对所有的版本管理系统都适用,Git只是用来举例而已。如果你不熟悉Git,跳过举例部分就可以了。

一、主分支Master

首先,代码库应该有一个、且仅有一个主分支。所有提供给用户使用的正式版本,都在这个主分支上发布。

Git主分支的名字,默认叫做Master。它是自动建立的,版本库初始化以后,默认就是在主分支在进行开发。

二、开发分支Develop

主分支只用来分布重大版本,日常开发应该在另一条分支上完成。我们把开发用的分支,叫做Develop。

这个分支可以用来生成代码的最新隔夜版本(nightly)。如果想正式对外发布,就在Master分支上,对Develop分支进行"合并"(merge)。

Git创建Develop分支的命令:

  git checkout -b develop master

将Develop分支发布到Master分支的命令:

  # 切换到Master分支
  git checkout master

  # 对Develop分支进行合并
  git merge --no--ff develop

这里稍微解释一下,上一条命令的--no--ff参数是什么意思。默认情况下,Git执行"快进式合并"(fast-farward merge),会直接将Master分支指向Develop分支。

使用--no--ff参数后,会执行正常合并,在Master分支上生成一个新节点。为了保证版本演进的清晰,我们希望采用这种做法。关于合并的更多解释,请参考Benjamin Sandofsky的《Understanding the Git Workflow》

三、临时性分支

前面讲到版本库的两条主要分支:Master和Develop。前者用于正式发布,后者用于日常开发。其实,常设分支只需要这两条就够了,不需要其他了。

但是,除了常设分支以外,还有一些临时性分支,用于应对一些特定目的的版本开发。临时性分支主要有三种:

  * 功能(feature)分支

  * 预发布(release)分支

  * 修补bug(fixbug)分支

这三种分支都属于临时性需要,使用完以后,应该删除,使得代码库的常设分支始终只有Master和Develop。

四、 功能分支

接下来,一个个来看这三种"临时性分支"。

第一种是功能分支,它是为了开发某种特定功能,从Develop分支上面分出来的。开发完成后,要再并入Develop。

功能分支的名字,可以采用feature-*的形式命名。

创建一个功能分支:

  git checkout -b feature-x develop

开发完成后,将功能分支合并到develop分支:

  git checkout develop

  git merge --no-ff feature-x

删除feature分支:

  git branch -d feature-x

五、预发布分支

第二种是预发布分支,它是指发布正式版本之前(即合并到Master分支之前),我们可能需要有一个预发布的版本进行测试。

预发布分支是从Develop分支上面分出来的,预发布结束以后,必须合并进Develop和Master分支。它的命名,可以采用release-*的形式。

创建一个预发布分支:

  git checkout -b release-1.2 develop

确认没有问题后,合并到master分支:

  git checkout master

  git merge --no-ff release-1.2

  # 对合并生成的新节点,做一个标签
  git tag -a 1.2

再合并到develop分支:

  git checkout develop

  git merge --no-ff release-1.2

最后,删除预发布分支:

  git branch -d release-1.2

六、修补bug分支

最后一种是修补bug分支。软件正式发布以后,难免会出现bug。这时就需要创建一个分支,进行bug修补。

修补bug分支是从Master分支上面分出来的。修补结束以后,再合并进Master和Develop分支。它的命名,可以采用fixbug-*的形式。

创建一个修补bug分支:

  git checkout -b fixbug-0.1 master

修补结束后,合并到master分支:

  git checkout master

  git merge --no-ff fixbug-0.1

  git tag -a 0.1.1

再合并到develop分支:

  git checkout develop

  git merge --no-ff fixbug-0.1

最后,删除"修补bug分支":

  git branch -d fixbug-0.1

(完)

文档信息