缘来我们在这里

乱世天狼的博客


  • 首页

  • 归档

货币银行学05

发表于 2017-10-28

引子

哀公问政

子曰:文武之政,布在方策。其人存,则其政举;其人亡,则其政息。

人道敏政,地道敏树。夫政也者,蒲卢也。

为政就像种树,种下种子,以致蔚然成观。发展才是硬道理。

故为政在人。取人以身。修身以道。修道以仁。

仁者,人也,亲亲为大。义者,宜也,尊贤为大。亲亲之杀,尊贤之等,礼所生也。

在下位,不获而上,民不可得而治矣。

故君子,不可以不修身。思修身,不可以不事亲。思事亲,不可以不知人。思知人,不可以不知天。

天下之达道五,所以行之者三,曰:君臣也、父子也、夫妇也、昆弟也、朋友之交也。五者天下之达道也。知、仁、勇三者,天下之达德也。所以行之者一也。

子曰:好学近乎知。力行近乎仁。知耻近乎勇。

知斯三者,则知所以修身。知所以修身,则知所以治人。知所以治人,则知所以治天下国家矣。

凡为国家有九经,曰:修身也、尊贤也、亲亲也、敬大臣也、体群臣也、子庶民也、来百工也、柔远人也、怀诸侯也。

修身,则道立。尊贤,则不惑。亲亲,则诸父昆弟不怨。敬大臣,则不眩。体群臣,则士之报礼重。子庶民,则百姓劝。来百工,则财用足。柔远人,则四方归之。怀诸侯,则天下畏之。

齐明盛服,非礼不动,所以修身也。去谗远色,贱货而贵德,所以劝贤也。尊其位,重其禄,同其好恶,所以劝亲亲也。官盛任使,所以劝大臣也。忠信重禄,所以劝士也。时使薄敛,所以劝百姓也。日省月试,既禀称事,所以劝百工也。嘉善而矜不能所以柔远人也。继绝世,举废国,治乱持危,朝聘以时,厚往而薄来,所以怀诸侯也。

凡为天下国家有九经,所以行之者一也。

凡事,豫则立,不豫则废。言前定,则不跲。事前定,则不困。行前定,则不疚。道前定,则不穷。

在下位不获乎上,民不可得而治矣。获乎上有道:不信乎朋友,不获乎上矣。信乎朋友有道:不顺乎亲,不信乎朋友矣。顺乎亲有道:反者身不诚,不顺乎亲矣。诚身有道:不明乎善,不诚乎身矣。

诚者,天之道也。诚之者,人之道也。诚者,不勉而中不思而得:从容中道,圣人也。诚之者,择善而固执之者也。

博学之,审问之,慎思之,明辨之,笃行之。

有弗学,学之弗能,弗措也。有弗问,问之弗知,弗措也。有弗思,思之弗得,弗措也。有弗辨,辨之弗明,弗措也。有弗行,行之弗笃,弗措也。人一能之,己百之。人十能之,己千之。

果能此道矣,虽愚必明,虽柔必强。

– 《中庸》

商业银行:业务与管理

商业银行的历史和发展趋势

2000年前的巴比伦,古代的希腊和罗马,已经有了银钱业主和货币兑换商。现代意义的银行起源于文艺复兴时期的意大利。1694年,英国出现了第一家股份制商业银行 – 英格兰银行。

第二次世界大战之后,西方商业银行的业务和经营发生了深刻的变化:集中化,全能化,电子化和国际化趋势明显。

中国的银行业

中国银钱业大量记载出现在唐朝,北宋的时候,四川出现了世界上最早的纸币。明清两代,钱庄,银号,票号先后兴起。

第一家:1845年英国丽如银行在广东开设分行

第一家自办:1897年上海设立的中国通商银行

第一家中央银行:1904年北京设立的官商合办的户部银行,1908年改称大清银行,1912年改组为中国银行。

国民政府时期,四行两局一库:中央银行,中国银行,交通银行,中国农民银行,中央信托局,邮政储蓄汇业局,中央合作金库。

目前中国的银行体系是由中央银行,政策性银行,国有独资商业银行,股份制银行,合作银行和外资银行共同组成的。

商业银行的资产、负债与资本

资产总额 = 负债总额 + 银行资本

资产

  1. 准备金:商业银行为应付日常的提款要求而保留的流动性最高的资产。它由银行的库存现金(商业银行保留在保险柜中的现金)和商业银行在中央银行的存款两部分组成,其中后者占主要部分。超过法定准备金的那部分叫做超额准备金。

  2. 收款过程中的现金:它是指在支票清算过程中,已记入商业银行的负债,但商业银行还未收到的那部分资金。

  3. 在其他银行的存款(同业存款)

上述资产通常被合称为‘现金项目’。现金项目的流动性最高,是商业银行的一级储备。

  1. 证券:证券投资是银行重要的收入来源之一。主要投资各种债券。1,灵活运用闲置资金,获取收益。2,加强流动性。3,降低风险

  2. 贷款:贷款是流动性比较低的一种银行资产。相应地,利率也是最高的。贷款从不同角度可以有不同的划分。按照贷款的期限:短期贷款(1年内),中期贷款(1-5年),长期贷款(5年以上)。保障形式:信用贷款,担保贷款,票据贴现贷款。占用形态:正常贷款,逾期贷款,呆滞贷款和呆帐贷款(后三种为不良贷款)。

  3. 其他资产:包括实物资产(建筑,设备)等。

负债

负债代表商业银行的资金来源,与此相关的业务称之为负债业务。

  1. 支票存款:不付息的活期存款,有息的可转让提款单存款和超级可转让提款单存款,货币市场存款账户。
  2. 非交易存款:储蓄存款,小额定期存款,大额定期存款。
  3. 借款:商业银行可以向中央银行,其他商业银行或者企业借款。从中央银行借款称为贴现贷款,从其它银行或者金融机构的借贷称为同行拆借。商业银行向企业借款通常使用证券回购协议。

银行资本

银行资本 = 银行总资产 - 银行总负债

银行资本代表了商业银行所有者的净财富。

当它为负值或零,银行便资不抵债。

银行资本大体包括以下几种类型:

  • 股本
  • 资本盈余
  • 未分配利润
  • 补偿性准备金
  • 从属债务

商业银行的中间业务和表外业务

中间业务

所谓中间业务是指商业银行以中介人的身份代客户办理各种委托事项,并从中收取手续费的业务。

重要包括:结算业务、租赁业务、信托业务、代理业务、信用卡业务、代保管业务和信息咨询业务

表外业务

贸易融通业务

  • 银行承兑业务
  • 商业信用证业务

金融保证业务

  • 备用信用证业务
  • 贷款承诺业务
  • 贷款销售业务

衍生工具交易

  • 远期交易
  • 期货交易
  • 期权交易
  • 互换协议

商业银行的管理

商业银行管理的一般原则

  • 安全性原则
  • 流动性原则
  • 盈利性原则

资产管理

  1. 在满足流动性要求的前提下,力图使多余的现金资产减少到最低程度
  2. 尽可能买收益高、风险低的证券
  3. 尽可能选择信誉良好而又愿意支付较高利率的借款者
  4. 在不损失专业化优势的前提下,尽可能通过资产的多样化来降低风险

负债管理

  • 合理利用现有的负债渠道,完善银行的负债结构,降低负债风险和负债成本
  • 积极进行金融创新,在法规允许的范围内,尝试新的负债业务

资产负债联合管理

  • 资产分配法
  • 缺口管理法

货币银行学04

发表于 2017-10-27

引子

子曰:武王、周公,其达孝矣乎。

夫孝者,善继人之志,善述人之事者也。

春秋,修其祖庙,陈其宗器,设其裳衣,荐其时食。

宗庙之礼,所以序昭穆也。序爵,所以辨贵贱也。序事,所以辨贤也。旅酬下为上,所以逮贱也。燕毛所以序齿也。

践其位,行其礼,奏其乐,敬其所尊,爱其所亲,事死如事生,事亡如事存,孝之至也。

郊社之礼,所以事上帝也。宗庙之礼,所以祀其先也。明乎郊社之礼,禘常之义,治国其如示诸掌乎。

– 《中庸》

人们组织到一起,必须要有一整套规则,约束人们向同一目标努力。如果没有规则,人们会无所是从,会乱掉。

金融体系概述(大纲)

金融体系是有关资金的集中,流动,分配和再分配的一个系统。它由资金的流出方(资金盈余单位)和流入方(资金短缺单位),连接两者的金融中介机构和金融市场,以及对这一系统进行管理的中央银行和其他金融监管机构共同构成。

资金融通过程

资金盈余单位 –> 金融中介机构 –> 资金短缺单位
|
▽
资金盈余单位 –> 证券市场 –> 资金短缺单位

直接金融

  • 资金短缺单位从一级市场拿到资金
  • 二级市场使资金融通的难度减小
  • 二级市场间接的对证券发行单位有监督的作用

直接金融,避免银行等中介环节,短缺单位可以节省融资成本,盈余单位可以增加收益。投资者需要专业的知识和技巧,并承担巨大风险。

中小企业因为公信力不足,所以直接金融一般来说只是政府和一些大企业的专利

间接金融(有中介主体)

优点

  • 减少信息成本和合约成本
  • 通过多样化降低风险
  • 可以实现期限的转换

两种资金融通渠道的相对重要性

两种资金融通渠道有动态平衡的效应

金融中介机构

  • 存款机构
  • 投资性中介机构
  • 合约性储蓄机构
  • 政策性金融机构

存款机构

存款机构主要包括:商业银行,储蓄贷款协会,互助储蓄银行,信用社。共同点是都可以发行支票存款,并且以发放贷款为主要的资金运用方式。

  • 商业银行:主要发行支票存款,储蓄存款,定期存款来筹措资金,用于发放工商业贷款,消费者贷款和抵押贷款,购买政府债券等。

  • 储蓄贷款协会:资金来源主要是储蓄存款,支票存款和定期存款。主要用于发放抵押贷款。

  • 互助储蓄银行:类似于储蓄贷款协会

  • 信用社:围绕某一社会集团建立的合作性放款机构。

投资性中介机构

金融公司,共同基金,货币市场共同基金

合约性储蓄机构

保险公司,养老基金

政策性金融机构

政府支持或者政府直属机构,用于特定部门或者产业发展

金融工具及其市场

货币市场工具
  1. 短期国债:一年之内的政府债券。
  2. 可转让定期存单
  3. 商业票据:大银行或者财务公司或者企业发行的,无担保行为的短期本票。
  4. 回购协议:以证券为抵押的短期贷款
  5. 银行承兑汇票:以银行信用为担保
资本市场工具
  1. 股票
  2. 债券
  3. 抵押贷款
衍生金融工具

衍生金融工具是一种合约,它的价值取决于作为合约标的物的某一金融工具、指数或其他投资工具的变动状况。衍生金融工具主要包括远期合约、期权合约、认股权证、互换协议及可转换证券等。

  1. 远期合约:远期合约是最为简单的衍生金融工具。它是指在确定的未来的某一日期,按照确定的价格买卖一定数量的某种资产的协议。在远期合约中,双方约定买卖的资产称为标的资产,约定的成交价格称为协议价格,同意以约定价格卖出标的资产的一方称作空头,同意以约定价格买入标的资产的一方称为多头。

  2. 期货合约:期货合约类似于远期合约,却有几点不同

    • 期货合约为标准化合约
    • 期货合约在交易所集中进行
    • 远期合约主要参与者为大银行,金融机构和大企业之间,由私下信用保证。期货合约由交易所保证,中小企业也可以参与
    • 实际交割比例不同,期货实际交割比例只有很少一部分,远期合约90%到期交割。期货多被认为是一种投资(机)行为。
  3. 互换协议:货币互换协议和利率互换协议两种

货币银行学03

发表于 2017-10-23

引子

子曰:舜其大孝也与!德为圣人,尊为天子,富有四海之内。宗庙飨之,子孙保之。

故大德,必得其位,必得其禄,必得其名,必得其寿。

故天之生物必因其材而笃焉。故栽着培之,倾者覆之。

诗曰,嘉乐君子,宪宪令德,宜民宜人。受禄于天。保佑命之,自天申之。

故大德必受命。

–《中庸》

利率的计算

分类:年利,月利,日利。单位均为厘。年利基本单位为1%,月利为1‰,日利也叫拆息单位为0.1‰

固定利率与浮动利率:根据是否根据市场利率变化而定期调整来区分

单利与复利

单利计算公式:

1
2
3
I = Prn
S = P(1 + rn)
以上,I表示利息额,P表示本金,r表示利率,n表示时间,S表示本金和利息之和

现实中最有意义的往往是复利,现举例说明,假设老王账户上有100元,现在年利为12%。第一年末:

$TV_1 = 100 \times(1 +0.12)$
…
$TV_n =P \times(1 +r)^n$

上述是基本的复利计算

连续复利

设每年计费次数为m,则n年末终值公式为:

$TV_n =P \times(1 +r\div m)^{rm}$

瞬时复利

上式m趋于无穷时 为瞬时复利,公式变为:

$TV_n =P \times e^{rn}$

现值

系列现金流现值计算公式:

$PV = \dfrac{A_1}{1+r} + \dfrac{A_2}{(1+r)^2} + … + \dfrac{A_n}{(1+r)^n}$

其中 $ A_i$ 是第i年末的现金流量

年金的现值可以通过查年金现值系数表而简单地得到

连续复利的情况

$PV = \dfrac{A_n}{e^{rn}}$

常见的债务工具

  1. 普通贷款
  2. 分期付款的贷款
  3. 息票债券
  4. 永久债券
  5. 折扣债券(零息债券)

到期收益率计算

普通贷款:$ P = \dfrac{F}{(1+r)}$

分期付款的贷款:$P = \dfrac{C}{1+r} + \dfrac{C}{(1+r)^2} + … + \dfrac{C}{(1+r)^n}$

息票债券:$P = \dfrac{C}{1+r} + \dfrac{C}{(1+r)^2} + … + \dfrac{F}{(1+r)^n}$

永久债券:r = A/P

折扣债券:$ P = \dfrac{F}{(1+r)^n}$

利率概念的应用

利率的变化对经济的影响是全局性的。

美国:

  • 优惠利率:反应市场资金的紧缺程度,一般常用中期利率
  • 短期利率:主要看三个月,六个月,以及一年的政府债券的到期收益率
  • 长期利率:政府的30年债券的到期收益率

利率是资金价格的直接反应,是经济活动的晴雨表。经济过热的时候,央行提高利率,使企业和个人少借款。经济疲软时,降低利率,鼓励企业投资,个人消费。

风险与收益

资产需求财富弹性 = 资产需求数量的百分比变化 / 财富的百分比变化

必需品:需求收入弹性在1以下
奢侈品:需求收入弹性在1以上

预期收益率其实是收益率这个随机变量的数学期望值

$E(r) = \sum_{i=1}^{n} r_iP(i)$

资产流动性越高,预期收益率一般越低。

风险:收益率的方差或标准差可以反应风险的大小

通过资产组合降低风险

…

货币银行学02

发表于 2017-10-21

引子

君子之道,辟如行远必自迩,辟如登高必自卑。

诗曰,妻子好合,如鼓瑟琴。兄弟既翕,和乐且耽。宜尔家室,乐尔妻帑。

子曰:父母其顺乎矣。

–《中庸》

货币的定义和数量

  • 流通中的现金

M0表示流通中的现金

  • 支票存款
  • 信用卡

以上之和为M1,M1反映了社会的直接购买支付能力,商品供应量和M1应该保持合适的比例关系,不然经济会过热或者萧条

  • 储蓄存款

从全社会来看,储蓄持续上升,而储蓄、M1、市场上的商品保持一个适当的比例。有时,由于某种原因,大家都要提款,存款转换为现金,经济中就会出现挤兑,抢购等现象。这时候全社会的储蓄总量就会急剧下降,从而导致通货膨胀,导致经济秩序的混乱。

以上四者之和为M2,研究M2构成的变化,对整个国民经济情况的分析,预测都有特别重要的意义。

货币层次的划分

根据各国情况,划分有区别,目的在于研究和调控

货币的职能

  • 交易媒介
  • 价值尺度
  • 财富储存手段

货币与经济

货币与通货膨胀:通货膨胀特征,1,物价总水平上涨;2,价格水平持续上涨

通货膨胀为国家向人民征收的隐形的税

无论何时,通货膨胀都是一种货币现象

货币的政策(紧缩,宽松),影响经济发展

政府财政收入小于支出的时候,第一个方法是向国内外借款,借款还不够机会向银行透支,也就是说印钞票。所以财政赤字和通货膨胀有间接关系。

常用linux命令笔记

发表于 2017-10-12

Linux 的档案权限与目录

任何一个档案都有 user,group,others三种身份的个别权限。

1
-rw-r--r--   1 york  staff   292 10 12 13:31 app.js

这里暂时只讨论第一栏 -rw-r--r--

第一个字符代表文件类型:d(文件夹),-(文件),l(连结),b(可供存储的接口设备),c(串行端口设备)

接下来的字符中,三个为一组,且均为rwx的三个参数组合,r代表可读,w代表可写,x代表可执行,如果为-代表相应位置无权限。第一组为拥有者全县,第二组为同群组权限,第三组为其他非群组的权限。

chmod,改变权限

数字类型改变权限:r:4,w:2,x:1;
符号类型改变档案权限:chmod (u,g,o,a)(+,-,=)(r,w,x) (档案或目录)

10月舟山游记

发表于 2017-10-08

引子

舟山游记(一)

东海有山名普陀,传闻此处有佛国。
拜遍普济与慧济,为善为真福自多。

南天门上可远望,海天一色起碧波。
回首向来萧瑟处,三十六月成蹉跎。

舟山游记(二)

八月天气鲜,漫游朱家尖。
早起登白山,爽风吹山巅。

午后大青山,阳光照沙滩。
近海黄蓝线,分割为哪般?

正文

2017年10月份,十一长假和中秋节撞到了一起,放假延长到8天。秋高气爽,正好适合出游。

1号从上海出发,乘坐大巴到普陀长途客运站,途径杭州湾跨海大桥和金塘大桥。此二者,雄踞海陆,宛若长龙出海,又似长虹落地,三十年间今非昔比。

我是和cc君和c君一起来的,途中历时较长,大约下午6时到达旅社 – 66号客栈。略作安顿,根据热情的房东建议,我们去了临近的阿勇海鲜大排档,开始舟山之行的第一次晚餐。

不得不说,阿勇海鲜大排档味道确实不错,印象特别深的是小黄鱼和海鲜面,小黄鱼非常鲜嫩,入口即化,海鲜面香而不腻,面汤极其鲜美。cc君和我同时感叹,仅此一餐,值回票价。

我们的房间也很不错,宽敞明亮,住着非常舒服。一夜安眠无话。

2号8点钟出发,10点钟乘船到普陀山,开始信步游览。当然,游客人山人海。不知不觉毕业已经三年,我们再也称不上年青,顶多是年轻,据联合国最新标准,我们都是妥妥的中年人!然而三年又做了什么呢,满怀理想和信念,想要改变世界,然而因为迷茫和浮躁止步不前。我们先去了南天门,南天门是看海景极佳的地方,远望碧海清波,近看嶙峋奇石,海天一线处,时时涌动着暗波。

然后我们去拜了观世音大士,在这海天佛国,有非常多很虔诚的居士,长拜不起,还有一群纯洁的信徒,梵音不休。我不是纯正的佛学信徒,但是我和他们有相同的信仰,秉持真善美的处世态度。所以双手合十拜了一拜。有一句话说的好,改变世界从改变自己开始,在物欲横流的世界,到底应该如何摆正自己的态度呢?我始终坚持真善美的态度,对自己诚实,即使不做,也不做恶。天行健,君子以自强不息;地势坤,君子以厚德载物。对自己诚实,哪怕走的慢一些,但是步伐会更稳健。

一行三人,边走边聊,三年之中各有经历,慢慢走出生活的迷茫,走出自己人生的方向。只有我,空有理想,却只履行十不及一。用王阳明先生说的话就是没有知行合一。沉下心来仔细想一想,目前这种人生态度和做事方式到底是缺少了什么呢?知止而后有定,定而后能静,静而后能安,安而后能虑,虑而后能行,行而后能得。现在关键是心不定,不安,不静。追根问底是因为没有‘知止’,没有一个明确的奋斗目标,杂念太多!

走遍普济寺和慧济寺之后,发现走的路越远,人越会感觉到舒服,全身心调动起来,才能体会到豁达,才能体会到中和,才能体会到应物无穷。

3号,我们计划是游朱家尖,我们就住在朱家尖城区,所以此日并不匆忙。我们先到附近的白山游玩。印象最深刻的是爬到山巅,吹着爽风,全身心通透的舒服。有人说,身体和灵魂总有一个要在路上,其实身体和灵魂哪一个都要时时在路上。人生短暂,只有在路上才能够看到不同的风景。

下午我们去了大青山国家公园,不得不提一句,如果来这里游玩,最好自驾或租车,因为公园实在很大,而且晚了很难打车。大青山有很漂亮的沙滩,我人生中第一次接触海水就是在这里,匆匆忙忙脱下鞋子,踏进浪花中,非常惬意。午后阳光沙滩,能点亮人的心情。海水的味道很咸,没有尝过的还是要尝一下。

人生就是一场旅程,充满艰难和曲折,同时充满奇观妙景,本持着真善美的内心,坚持走自强不息的道路,未来会更雄伟壮丽。

– 2017.10.13

Add comment

yargs

发表于 2017-09-27

引子

仲尼曰:君子中庸;小人反中庸

君子中庸也,君子而士中。小人之反中庸也,小人而无忌惮也。

–《中庸》

yargs api 探索

1
2
var argv = require("yargs").argv; //等价于以下方法
var argv = require("yargs").parse(); //此二者用于拿到命令行参数

.alias(key, alias)

此接口用于使用短符号等价比较长的 key
例如:

1
.alias('i', 'ingredient')

.argv

取得输入参数,用 object 表示

.array(key)

指定 key 为数组,例:.array(‘foo’)设置之后,–foo foo bar 将会变成[‘foo’,’bar’]

.boolean(key)

指定 key 为 bool 值,例:.boolean(‘foo’)设置之后, –foo foo 将会变成 true

.check(fn, [global=true])

函数 fn 接受两个参数,argv,options

1
2
{ _: [], help: false, version: false, foo: 'test', '$0': 'app.js' } // argv
{ help: [], version: [] } // options

这个函数用于检测参数传的是不是合法,return 不为 true 的时候会显示抛出的错误,使用说明,然后退出。
global = true 的时候意思是这个应该放到顶层(检查嘛,应该在最开始检查)

.choices(key, choices)

给 key 预定义一些列可取的值,如果这个方法调用了多次,那么列举的值会被 merge 到一起。选项是一般的字符串或者数字,并且对大小写敏感。例:

1
2
3
4
var argv = require("yargs")
.choices("i", ["peanut-butter", "jelly", "banana", "pickles"])
.choices("i", ["apple"])
.parse();

另外,.choices()可以使用一个对象携带多个 key-choices。例:

1
2
3
4
5
6
var argv = require("yargs")
.choices({
j: ["butter", "ly", "ana", "kles"],
i: ["peanut-butter", "jelly", "banana", "pickles"]
})
.parse();

而且,choices 可以设置为 option()方法的一个 key

1
2
3
4
5
var argv = require("yargs").option("size", {
alias: "s",
describe: "choose a size",
choices: ["xs", "s", "m", "l", "xl"]
}).argv;

.coerce(key, fn)

这个接口是用来强制转换 key 的 value 值的。这个强转函数接受一个参数,也就是命令行中的 key 值。此函数必须返回一个新的值,或者抛出错误。返回的新值将会作为 key 的 value(或者 key 的 alias 的 value)。

抛出的错误,可以在fail()方法中捕获并打印。

强制转换可以在所有其他修改方法之后应用,比如在.normalize()方法之后应用。

例如:

1
2
3
4
5
var argv = require("yargs")
.alias("f", "file")
.coerce("file", function(arg) {
throw new Error("test");
}).argv;

当然,此方法也可以接受对象参数:

1
2
3
4
var argv = require("yargs").coerce({
date: Date.parse,
json: JSON.parse
}).argv;

还有,你可以使用一个函数对应好几个 key:

1
2
var path = require("path");
var argv = require("yargs").coerce(["src", "dest"], path.resolve).argv;

如果使用点操作或者数组,强制转换会应用到最终的 object 上:

1
2
3
4
5
6
7
8
9
// --user.name Batman --user.password 123
// gives us: {name: 'batman', password: '[SECRET]'}
var argv = require("yargs")
.option("user")
.coerce("user", opt => {
opt.name = opt.name.toLowerCase();
opt.password = "[SECRET]";
return opt;
}).argv;

.command(cmd, desc, [builder], [handler]);.command(cmd, desc, [module]);.command(module)

此用法用于定义应用暴露出来的的命令(默认我们程序命名为 app.js)

cmd用于定义命令(注意这里要和参数 key 区分开),可以为字符串或者字符串数组,当然也可以使用 alias,下面有专门叙述。

desc用于描述应用提供的所有命令(逐条对应)。定义为 false 可以生成一个隐藏命令,隐藏命令不会在帮助信息中展示,同时不能在.completion中使用

另外,也可以提供一个构建者 object 提供一些命令接受的选项信息

1
2
3
4
5
6
7
8
yargs
.command("get", "make a get HTTP request", {
url: {
alias: "u",
default: "http://yargs.js.org/"
}
})
.help().argv;

构建者 还可以是一个函数。函数携带一个 yargs 实例, 可以用来提供更详细的命令描述。

1
2
3
4
5
6
7
8
yargs
.command("get", "make a get HTTP request", function(yargs) {
return yargs.option("url", {
alias: "u",
default: "http://yargs.js.org/"
});
})
.help().argv;

而且,还可以加上一个处理函数,参数为转化后的argv对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
yargs
.command(
"get",
"make a get HTTP request",
function(yargs) {
return yargs.option("u", {
alias: "url",
describe: "the URL to make an HTTP request to"
});
},
function(argv) {
console.log(argv.url);
}
)
.help().argv;

想要进一步了解 command api 更详尽的特性,请点击这里

.completion([cmd], [description], [fn])

此命令用户命令行补全(切记执行 chmod u+x 文件 改为可执行文件再进行补全尝试)

cmd 定义参与命令补全的命令。第一次使用会有提示,如果用的 zsh,那么将提示中.bashrc改成.zshrc,然后按照提示操作(切记将你的 js 文件设置为可执行文件,然后再操作)

description 描述命令的使用方法

fn: 提供待补全的参数

如果实现的时候没有携带参数,那么.completion()会让补全命令输出补全脚本

1
2
3
4
5
6
var argv = require("yargs").completion("completion", function(current, argv) {
// 'current' is the current command being completed.
// 'argv' is the parsed arguments so far.
// simply return an array of completions.
return ["foo", "bar"];
}).argv;

还可以提供异步补全

1
2
3
4
5
6
7
8
9
var argv = require("yargs").completion("completion", function(
current,
argv,
done
) {
setTimeout(function() {
done(["apple", "banana"]);
}, 500);
}).argv;

还可以使用异步的 promise

1
2
3
4
5
6
7
8
9
10
11
var argv = require("yargs").completion("completion", function(
current,
argv,
done
) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(["apple", "banana"]);
}, 10);
});
}).argv;

.config([key], [description], [parseFn]) .config(object)

此方法使得传入 key 的值被认为是一个 JSON 配置文件的路径。文件中的 JSON 属性被设置为对应的 key 和 value(挂在 argv 上)。文件使用 nodejs 的 require api 加载的,文件名最好为.js, .json。

如果此方法没有携带任何参数,.config()将会使用--config选项传入 JSON 配置文件(此时只能传入以.json 结尾文件)

description同其他方法,用于描述命令

可选项 parseFn 可以用来定制转换器。转换函数必须是同步的,并且应当返回一个带有 key,value 键值对的对象或者一个 error。

1
2
3
var argv = require("yargs").config("settings", function(configPath) {
return JSON.parse(fs.readFileSync(configPath, "utf-8"));
}).argv;

你还可以传一个明确的 object,同样的,它的键值对会转化为argv的键值对。

1
var argv = require("yargs").config({ foo: 1, bar: 2 }).argv;

config和pkgConf可以提供extends关键词,用来表明配置应该从别处继承。

extends参数可以是绝对路径也可以是相对路径

1
2
3
4
yargs.config({
extends: "./configs/a.json",
logLevel: "verbose"
}).argv;

或者,还可以是一个模块

1
2
# my-library.js
yargs.pkgConf('nyc')
1
2
3
4
5
6
# package.json
{
"nyc": {
"extends": "nyc-babel-config"
}
}

nyc-babel-config 是一个提供配置的包

.conflicts(x, y)

如果 x 被设置了,那么 y 一定不能被设置。y 可以是字符串也可以是数组

当然,此方法也可以接受 Object 对象

.count(key)

此命令用来对命令计数,并转化为命令的参数。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env node
var argv = require("yargs")
.count("verbose")
.alias("v", "verbose").argv;

VERBOSE_LEVEL = argv.verbose;

function WARN() {
VERBOSE_LEVEL >= 0 && console.log.apply(console, arguments);
}
function INFO() {
VERBOSE_LEVEL >= 1 && console.log.apply(console, arguments);
}
function DEBUG() {
VERBOSE_LEVEL >= 2 && console.log.apply(console, arguments);
}

WARN("Showing only important stuff");
INFO("Showing semi-important stuff too");
DEBUG("Extra chatty mode");

.default(key, value, [description]) .defaults(key, value, [description])

注意:这个命令已经弃用。将在将来的主版本中移除

如果没有选项传入的话,为 key 设置默认值

当然,同样此命令可以接受一个 object 为参数,设置 key 的默认值

而且,默认值还可以是一个函数,函数名会被写到 help 里面的用法说明中

1
2
3
var argv = require("yargs").default("random", function randomValue() {
return Math.random() * 256;
}).argv;

而且,description参数可以优先提供用法说明

.demandOption(key, [msg | boolean]) .demandOption(key, msg)

此命令用来强制用户输入某些参数

如果 key 是一个字符串,且 key 没有出现在命令行参数中,展示使用说明并退出。

如果 key 是数组,限制每一个数组中的参数

如果提供了 msg,而且没有相应参数,那么 msg 将会展示,替代原有的标准错误信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// demand an array of keys to be provided
require("yargs")
.option("run", {
alias: "r",
describe: "run your program"
})
.option("path", {
alias: "p",
describe: "provide a path to file"
})
.option("spec", {
alias: "s",
describe: "program specifications"
})
.demandOption(
["run", "path"],
"Please provide both run and path arguments to work with this tool"
)
.help().argv;

当第二个参数为布尔值的时候,布尔值决定了这个选项是不是必须的。当使用 options 方法的时候,这个选项很有用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// demand individual options within the option constructor
require("yargs")
.options({
run: {
alias: "r",
describe: "run your program",
demandOption: true
},
path: {
alias: "p",
describe: "provide a path to file",
demandOption: true
},
spec: {
alias: "s",
describe: "program specifications"
}
})
.help().argv;

.demandCommand([min=1], [minMsg]) .demandCommand([min=1], [max], [minMsg], [maxMsg])

此命令用于限定用户在程序中使用的命令次数。如果命令没有传进来,使用 msg 提供标准的错误提示

1
2
3
4
5
6
7
8
9
10
11
12
13
require("yargs")
.command({
command: "configure <key> [value]",
aliases: ["config", "cfg"],
desc: "Set a config variable",
builder: yargs => yargs.default("value", "true"),
handler: argv => {
console.log(`setting ${argv.key} to ${argv.value}`);
}
})
// provide a minimum demand and a minimum demand message
.demandCommand(1, "You need at least one command before moving on")
.help().argv;

.describe(key, desc)

描述 key 的使用方法,可以使用 object

.detectLocale(boolean)

yargs 是否检查系统的所在地,默认是 true

.env([prefix])

定义环境变量的值,使用”_“来表明嵌套的选项(nested__foo => nested.foo)

程序参数定义优先的次序:

  1. 命令行参数
  2. env 参数
  3. 配置文件或者 object
  4. 默认选项
1
2
3
4
5
6
7
var argv = require("yargs")
.env("MY_PROGRAM")
.option("f", {
alias: "fruit-thing",
default: "apple"
}).argv;
console.log(argv);
1
2
3
4
5
6
$ node fruity.js
{ _: [],
f: 'apple',
'fruit-thing': 'apple',
fruitThing: 'apple',
'$0': 'fruity.js' }
1
2
3
4
5
6
$ MY_PROGRAM_FRUIT_THING=banana node fruity.js
{ _: [],
fruitThing: 'banana',
f: 'banana',
'fruit-thing': 'banana',
'$0': 'fruity.js' }
1
2
3
4
5
6
$ MY_PROGRAM_FRUIT_THING=banana node fruity.js -f cat
{ _: [],
f: 'cat',
'fruit-thing': 'cat',
fruitThing: 'cat',
'$0': 'fruity.js' }

默认情况下不读取 env 参数(没有传啊!!!),但是可以用.env(false)让环境变量失效。

.epilog(str) .epilogue(str)

使用说明之后的收场白

1
2
3
var argv = require("yargs").epilogue(
"for more information, find our manual at http://example.com"
);

.example(cmd, desc)

增加示例,第一个参数cmd中,$0代表命令行中的第一个参数。例子会随着帮助信息打印出来。

.exitProcess(enable)

暂时没发现有什么卵用

.fail(fn)

当失败发生的时候,此函数调用,而不是打印错误信息。

fn 参数有三个,msg: ‘本来要打印的信息’;err:最开始抛出来的Error实例;’yargs’,参数对象

1
2
3
4
5
6
7
var argv = require("yargs").fail(function(msg, err, yargs) {
if (err) throw err; // preserve stack
console.error("You broke it!");
console.error(msg);
console.error("You should be doing", yargs.help());
process.exit(1);
}).argv;

.getCompletion(args, done);

原文是可以程序地补全任何行的选项

args: 命令行要补全的参数

done: 回调函数,参数为补全的结果

示例:

1
2
3
4
5
6
7
require("yargs")
.option("foobar")
.option("foobaz")
.completion()
.getCompletion(["./test.js", "--foo"], function(completions) {
console.log(completions);
});

输入的补全选项:./test.js --foo (按 tab 键):–foobar 和 –foobaz

此方法我没有实际测试通过,特此备注

.global(globals, [global=true])

默认 option 都是全局的,但是此命令可以恢复设置为 false 的选项重新为全局的。

全局的 option 在定义的命令执行之后不会清除,非全局的会被清除。默认所有选项都是全局的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var argv = require("yargs")
.option("a", {
alias: "all",
default: true,
global: false
})
.option("n", {
alias: "none",
default: true,
global: false
})
.command("foo", "foo command", function(yargs) {
return yargs.option("b", {
alias: "bar"
});
})
.help("help")
.global("a").argv;

.group(key(s), groupName)

 这个就是在显示使用说明的时候,为同一组 option 增加一个头标题

1
2
3
4
5
var yargs = require("yargs")(["--help"])
.help()
.group("batman", "Heroes:")
.describe("batman", "world's greatest detective")
.wrap(null).argv;

.help() .help([option | boolean]) .help([option, [description]])

展示和配置帮助信息,yargs 默认支持--help选项

option 参数代表可以使用其他选项或命令调出帮助信息。

description 可以修改默认帮助信息的文案

1
2
3
var yargs = require("yargs")(["--info"])
.usage("$0 -operand1 number -operand2 number -operation [add|subtract]")
.help("info").argv;

.implies(x, y)

此命令意味着 y 对 x 有依赖,y 可以是数组,可以是参数名,甚至可以是数字(参数位置)

同样地,这个方法可以接受一个对象参数

1
var yargs = require("yargs").implies("a", "b").argv;

.locale()

开启本地模式,默认 yargs 会自动检测系统位置,然后使用当地的语言

实用一个静态的 locale 可以覆盖掉默认的行为,如下所示

.locale(locale)

覆盖默认检测到的 locale

1
2
3
4
5
6
7
8
9
10
11
12
var argv = require("yargs")
.usage("./$0 - follow ye instructions true")
.option("option", {
alias: "o",
describe: "'tis a mighty fine option",
demandOption: true
})
.command("run", "Arrr, ya best be knowin' what yer doin'")
.example("$0 run foo", "shiver me timbers, here's an example for ye")
.help("help")
.wrap(70)
.locale("pirate").argv;

1
2
3
4
5
6
7
8
9
10
11
12
13
./test.js - follow ye instructions true

Choose yer command:
run Arrr, ya best be knowin' what yer doin'

Options for me hearties!
--option, -o 'tis a mighty fine option [requi-yar-ed]
--help Parlay this here code of conduct [boolean]

Ex. marks the spot:
test.js run foo shiver me timbers, here's an example for ye

Ye be havin' to set the followin' argument land lubber: option

一般用不到这个东东

.nargs(key, count)

此方法用于限制 key 后面跟的参数长度

1
var argv = require("yargs").nargs("token", 1).argv;

当然,也可以传 object 参数

.normalize(key)

据说是为了传入 path 的时候,便于调用 path.normalize()

number(key)

告诉 parser,一直将这个key当作数字转换

参数可以是数组

选项如果并没有值,默认为undefined

不能转化为数字,会被转换为NaN

小数,16 进制数,科学计数法都是合法的

1
2
3
var argv = require("yargs")
.number("n")
.number(["width", "height"]).argv;

.option(key, [opt]) .options(key, [opt])

为key配置各种选项的命令

1
2
3
4
5
6
7
var argv = require("yargs").option("f", {
alias: "file",
demandOption: true,
default: "/etc/passwd",
describe: "x marks the spot",
type: "string"
}).argv;

同

1
2
3
4
5
6
var argv = require("yargs")
.alias("f", "file")
.demandOption("f")
.default("f", "/etc/passwd")
.describe("f", "x marks the spot")
.string("f").argv;

还可以这样

1
2
3
4
5
6
7
8
9
var argv = require("yargs").options({
f: {
alias: "file",
demandOption: true,
default: "/etc/passwd",
describe: "x marks the spot",
type: "string"
}
}).argv;

可用的 key 有以下这些

  • alias
  • array
  • boolean
  • choices
  • coerce
  • config
  • configParser
  • conflicts
  • count
  • default
  • defaultDescription
  • demandOption
  • desc/describe/description
  • global
  • group
  • hidden
  • implies
  • nargs
  • normalize
  • number
  • requiresArg
  • skipValidation
  • string
  • type: ‘array’,’boolean’,’count’,’number’,’string’

.parse([args], [context], [parseCallback])

可以替代从process.argv传参,返回 argv 对象。args 可以是数组或者原生参数字符串。

context:可以同时携带的一个对象参数,可以为命令提供状态信息,是很实用的技术。

1
2
3
4
5
6
7
8
9
10
const parser = yargs
.command(
"lunch-train <restaurant>",
"start lunch train",
function() {},
function(argv) {
console.log(argv.restaurant, argv.time);
}
)
.parse("lunch-train rudy's", { time: "12:15" });

parseCallback: 此方法的回调函数,会携带三个参数

  1. err: 转化中出现的验证错误
  2. argv: 转化的 argv 对象
  3. output: 将要在终端输出的文本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// providing the `fn` argument to `parse()` runs yargs in headless mode, this
// makes it easy to use yargs in contexts other than the CLI, e.g., writing
// a chat-bot.
const parser = yargs
.command(
"lunch-train <restaurant> <time>",
"start lunch train",
function() {},
function(argv) {
api.scheduleLunch(argv.restaurant, moment(argv.time));
}
)
.help();

parser.parse(bot.userText, function(err, argv, output) {
if (output) bot.respond(output);
});

提醒: 给 parse 函数回调参数会导致 exitProcess 设置失效,直至回调调用

.pkgConf(key, [cwd])

类似于 .config(),这表明 yargs 从 package.json 中寻找特定的配置对象

cwd可以选择性地提供,package.json 将从这里读取

.positional(key, opt)

这个我尝试了,但是没泡通

对命令的参数进行配置,类似于 .option(),但是不能作用于顶层 yargs 实例

1
2
3
4
5
6
7
8
9
10
11
const argv = require("yargs")("run --help").command(
"run <port> <guid>",
"run the server",
yargs => {
yargs.positional("guid", {
describe: "a unique identifier for the server",
type: "string"
});
}
).argv;
console.log(argv);

可选的参数有:

  • alias
  • choices
  • coerce
  • confilicts
  • default
  • desc/describe/description
  • implies
  • normalize
  • type: ‘boolean’,’number’,’string’

.recommendCommands()

决定 yargs 是否在没有匹配命令的时候,提示相关的类似命令

.require(key, [msg | boolean]) .required(key, [msg | boolean])

同 .demand()

.requiresArg(key)

可以接收数组或者字符串

规定所有的 key 后面必须要跟 value,否则,现实用法信心并退出

默认如果 key 后面不跟 value,key 赋值为 true

.reset() [已废弃]

重置所有已经构建的参数。对于嵌套命令行接口特别有用。使用 global 避免不想要重置的 keys 被重置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var yargs = require("yargs")
.usage("$0 command")
.command("hello", "hello command")
.command("world", "world command")
.demandCommand(1, "must provide a valid command"),
argv = yargs.argv,
command = argv._[0];

if (command === "hello") {
yargs
.reset()
.usage("$0 hello")
.help("h")
.example("$0 hello", "print the hello message!").argv;

console.log("hello!");
} else if (command === "world") {
yargs
.reset()
.usage("$0 world")
.help("h")
.example("$0 world", "print the world message!").argv;

console.log("world!");
} else {
yargs.showHelp();
}

.showCompletionScript()

生成一个补全脚本。应用的使用者可以在他们的.bashrc中安装,yargs 会提供命令和参数补全的快捷方式

.showHelp(consoleLevel=’error’)

实用 console 的consoleLevel打印使用数据

Example:

1
2
3
4
var yargs = require("yargs").usage(
"$0 -operand1 number -operand2 number -operation [add|subtract]"
);
yargs.showHelp(); //prints to stderr using console.error()

或者,使用标准输出打印使用信息,可以选择console.log:

1
yargs.showHelp("log"); //prints to stdout using console.log()

.showHelpOnFail(enable, [message])

默认,yargs 检测到错误会输出使用信息。我们可以使用这个方法定制行为。enable 为 false 的时候,使用信息不输出。如果 message 参数存在,这个信息会在错误信息之后输出。

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env node
var argv = require("yargs")
.usage("Count the lines in a file.\nUsage: $0 -f <file>")
.demandOption("f")
.alias("f", "file")
.describe("f", "Load a file")
.string("f")
.showHelpOnFail(false, "Specify --help for available options")
.help("help").argv;

// etc.
1
2
3
4
$ node line_count.js
Missing argument value: f

Specify --help for available options

.skipValidation(key)

指定一些选项,跳过验证

.strict([enabled=true])

如果所有的参数都没有被demand, 或者都没有一个正确的描述,这将会被当成错误报告出来

不被认可的命令依然会被当作错误报告出来

.string(key)

告诉 parser 不要将 key 当成数字或布尔值来转换

.updateLocale(obj) .updateStrings(obj)

没有测试通过

覆盖默认的字符串

1
2
3
4
5
6
7
var argv = require("yargs")
.command("run", "the run command")
.help("help")
.updateStrings({
"Commands:": "My Commands -->\n"
})
.wrap(null).argv;

1
2
3
4
5
6
My Commands -->

run the run command

Options:
--help Show help [boolean]

如果特定了一个locale(), 应该在updateStrings()之前调用

.usage(<message|command>, [desc], [builder], [handler])

设置显示哪一条命令的使用信息。在 message 中,$0会被转译成脚本名字,node 命令等。

如果 desc/builder/handler 等参数提供了,此方法相当于 .command。

1
2
3
4
5
6
7
8
9
10
const argv = require("yargs").usage(
"$0 <port>",
"start the application server",
yargs => {
yargs.positional("port", {
describe: "the port that your application should bind to",
type: "number"
});
}
).argv;

.version() .version([version|boolean]) .version([option], [description], [version])

设置显示的版本号并退出程序。默认支持 –version。

如果没有参数传入,yargs 会从 package.json 中寻找 version 值

如果传入布尔值 false, 将会禁掉 –version

.wrap(columns)

格式化使用信息的展示 – 多少列

默认的 wrap 是Math.min(80, windowWidth), 使用.wrap(null)去掉列限制。使用.wrap(yargs.terminalWidth())控制显示信息为最大宽度。

thingking-in-react

发表于 2017-08-30

引子

所谓齐其家在修其身者,人之其所亲爱而辟焉,之其所贱恶而辟焉,之其所畏敬而辟焉,之其所哀矜而辟焉。故好而知其恶,恶而知其美者,天下鲜矣。故谚有之曰:“人莫知其子之恶,莫知其苗之硕。”此谓身不修不可以齐其家。

–《大学》

思想

单一功能原则:此规则规定每个类都应该有一个单一的功能,并且该功能应该由这个类完全封装起来。所有它的服务都应该严密的和该功能平行(功能平行,意味着没有依赖)

相应react组件:理论上一个组件应该只做一件事,如果要扩展,应该被拆分到更小的组件。

根据ui拆分组件是没有必要的,根据json数据拆分数据是合理的

DRY:Don’t Repeat Yourself

辨别什么是一个state:

  • 是否从父组件props传递,如果是,那不是state
  • 是否一直不变,如果是,那不是state
  • 是否能从其他state计算得到,如果是,那不是state

单向数据流:优势是数据流很清晰,缺点是交互的动态实现需要更多一点代码

使用ref的场景

  • 处理焦点,区域选择,媒体播放
  • 触发动画
  • 配合第三方库

react diff 算法

普通树变动为什么是o(n3)的算法复杂度

react算法的两个设想

  • 两个不同类型的tree会生成不同的树
  • 通过不同的key可以得知在不同的渲染过程中哪个元素是不变的

diff 算法

不同类型的元素

根元素的不同类型会导致整体重绘

相同类型的dom元素

react会检查它们的属性是否相同,如果不相同,则仅仅更新它的属性,之后递归的对子元素进行操作

子代的递归操作
react按顺序比较

1
2
3
4
5
6
7
8
9
10
11
<ul>
<li>first</li>
<li>second</li>
</ul>

<ul>
<li>first</li>
<li>second</li>
<li>third</li>
</ul>
这种情况,react只会在末尾插入<li>third</li>

1
2
3
4
5
6
7
8
9
10
11
<ul>
<li>Duke</li>
<li>Villanova</li>
</ul>

<ul>
<li>Connecticut</li>
<li>Duke</li>
<li>Villanova</li>
</ul>
这种情况,react会更新所有元素

keys

keys可以解决上述的低效操作

1
2
3
4
5
6
7
8
9
10
11
<ul>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>

<ul>
<li key="2014">Connecticut</li>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
这种情况,react会认为带有'2014'的key的元素是新的,其他元素仅仅是移动了

所以可以给数组元素加上等于下标顺序的key,但如果重排顺序的话,将会很慢

假定情形不使用的状况,算法就很吃力了

  • 算法会忽略掉不同类型的组件,即使他们有相似的输出。不过在实践中,没有相关issue
  • keys应该稳定,可预知,并且是独特的,不稳定的key会导致dom节点没有必要的重绘,并且容易丢失子组件的状态。

高阶组件

定义:高阶组件就是一个函数,接收一个组件,返回一个新组件

1
const EnhancedComponent = higherOrderComponent(WrappedComponent);

高阶组件普遍存在于react第三方库中,例如:redux的connect和relay的createcontainer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
class CommentList extends React.Component {
constructor() {
super();
this.handleChange = this.handleChange.bind(this);
this.state = {
// "DataSource" is some global data source
comments: DataSource.getComments()
};
}

componentDidMount() {
// Subscribe to changes
DataSource.addChangeListener(this.handleChange);
}

componentWillUnmount() {
// Clean up listener
DataSource.removeChangeListener(this.handleChange);
}

handleChange() {
// Update component state whenever the data source changes
this.setState({
comments: DataSource.getComments()
});
}

render() {
return (
<div>
{this.state.comments.map((comment) => (
<Comment comment={comment} key={comment.id} />
))}
</div>
);
}
}

class BlogPost extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {
blogPost: DataSource.getBlogPost(props.id)
};
}

componentDidMount() {
DataSource.addChangeListener(this.handleChange);
}

componentWillUnmount() {
DataSource.removeChangeListener(this.handleChange);
}

handleChange() {
this.setState({
blogPost: DataSource.getBlogPost(this.props.id)
});
}

render() {
return <TextBlock text={this.state.blogPost} />;
}
}

const CommentListWithSubscription = withSubscription(
CommentList,
(DataSource) => DataSource.getComments()
);

const BlogPostWithSubscription = withSubscription(
BlogPost,
(DataSource, props) => DataSource.getBlogPost(props.id)
);

// This function takes a component...
function withSubscription(WrappedComponent, selectData) {
// ...and returns another component...
return class extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {
data: selectData(DataSource, props)
};
}

componentDidMount() {
// ... that takes care of the subscription...
DataSource.addChangeListener(this.handleChange);
}

componentWillUnmount() {
DataSource.removeChangeListener(this.handleChange);
}

handleChange() {
this.setState({
data: selectData(DataSource, this.props)
});
}

render() {
// ... and renders the wrapped component with the fresh data!
// Notice that we pass through any additional props
return <WrappedComponent data={this.state.data} {...this.props} />;
}
};
}

不要改变原始组件,使用合成手段,不要在render方法中使用高阶组件

合成事件

合成事件的属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
boolean bubbles
boolean cancelable
DOMEventTarget currentTarget
boolean defaultPrevented
number eventPhase
boolean isTrusted
DOMEvent nativeEvent
void preventDefault()
boolean isDefaultPrevented()
void stopPropagation()
boolean isPropagationStopped()
DOMEventTarget target
number timeStamp
string type

java_note_01

发表于 2017-08-23

引子

所谓修身在正其心者,身有所忿懥,则不得其正,有所恐惧,则不得其正,有所好乐,则不得其正,有所忧患,则不得其正。心不在焉,视而不见,听而不闻,食而不知其味。此谓修身在正其心。

–《大学》

基本语法

  • 大小写敏感
  • 类名:首写字母应该大写,驼峰命名
  • 方法名:所有方法名都应该小写开头,驼峰命名
  • 源文件名:源文件名必须和类名相同。当保存文件的时候,你应该使用类名作为文件保存(文件名和类名不同会导致编译错误!)
  • 主方法入口:所有的java程序由public static void main(String []args)方法开始执行。

java标识符

  • 字母,美元符号,下划线开头
  • 首字符之后可以是字母,美元符号,下划线或数字的任何字符组合
  • 关键字不能用作标志符

java修饰符

  • 访问控制修饰符: default,public,protected,private
  • 非访问控制修饰符:final,abstract,strictfp

java变量

  • 局部变量
  • 类变量
  • 成员变量

java数组

数组是储存在堆上的对象,可以保存多个同类型变量

java枚举

枚举类型限制变量只能是预先设定好的值。使用枚举可以减少代码中的bug。

java关键字

abstract, assert, boolean, break, byte, case, catch, char, class, const, continue, default, do, double, else, enum, extends, final, finally, float, for, goto, if, implements, import, instanceof, int, interface, long, native, new, package, private, protected, public, return, short, static, strictfp, super, switch, synchronized, this, throw, throws, transient, try, void, volatile, while

java注释

同时支持单行和多行注释

继承和接口

继承:一个类可以由其他类派神。如果你要创建一个类,而且已经存在一个类具有你所需要的属性或方法,那么你可以将新创建的类继承该类。

接口:接口可以理解为对象间相互通信的协议。接口在继承中扮演很重要的角色。接口只定义派生要用到的方法,但是方法的具体实现完全取决于派生类。

moment

发表于 2017-08-17
1…4567

乱世天狼

乱世天狼 | 前端 | html | css | html5 | css3 | react | redux | webpack | 哲学 | 精神 | 生活

67 日志
48 标签
© 2020 乱世天狼
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.4