概述

first.png

上图是WebChat的连接示意图,图中的CM是指连接管理器(Connection Manager),服务器端与CM之间是XMPP协议的连接,CM与客户端之间是Http协议的连接。

Read More

作者:Wang Namelos
链接:https://www.zhihu.com/question/41312576/answer/90782136
来源:知乎
著作权归作者所有,转载请联系作者获得授权。

解答这个问题并不困难:唯一的要求是你熟悉React。
不要光听别人描述名词,理解起来是很困难的。
从需求出发,看看使用React需要什么:

  1. React有props和state: props意味着父级分发下来的属性,state意味着组件内部可以自行管理的状态,并且整个React没有数据向上回溯的能力,也就是说数据只能单向向下分发,或者自行内部消化。
    理解这个是理解React和Redux的前提。
  2. 一般构建的React组件内部可能是一个完整的应用,它自己工作良好,你可以通过属性作为API控制它。但是更多的时候发现React根本无法让两个组件互相交流,使用对方的数据。
    然后这时候不通过DOM沟通(也就是React体制内)解决的唯一办法就是提升state,将state放到共有的父组件中来管理,再作为props分发回子组件。
  3. 子组件改变父组件state的办法只能是通过onClick触发父组件声明好的回调,也就是父组件提前声明好函数或方法作为契约描述自己的state将如何变化,再将它同样作为属性交给子组件使用。
    这样就出现了一个模式:数据总是单向从顶层向下分发的,但是只有子组件回调在概念上可以回到state顶层影响数据。这样state一定程度上是响应式的。
  4. 为了面临所有可能的扩展问题,最容易想到的办法就是把所有state集中放到所有组件顶层,然后分发给所有组件。
  5. 为了有更好的state管理,就需要一个库来作为更专业的顶层state分发给所有React应用,这就是Redux。让我们回来看看重现上面结构的需求:
    a. 需要回调通知state (等同于回调参数) -> action
    b. 需要根据回调处理 (等同于父级方法) -> reducer
    c. 需要state (等同于总状态) -> store
    对Redux来说只有这三个要素:
    a. action是纯声明式的数据结构,只提供事件的所有要素,不提供逻辑。
    b. reducer是一个匹配函数,action的发送是全局的:所有的reducer都可以捕捉到并匹配与自己相关与否,相关就拿走action中的要素进行逻辑处理,修改store中的状态,不相关就不对state做处理原样返回。
    c. store负责存储状态并可以被react api回调,发布action.
    当然一般不会直接把两个库拿来用,还有一个binding叫react-redux, 提供一个Provider和connect。很多人其实看懂了redux卡在这里。
    a. Provider是一个普通组件,可以作为顶层app的分发点,它只需要store属性就可以了。它会将state分发给所有被connect的组件,不管它在哪里,被嵌套多少层。
    b. connect是真正的重点,它是一个科里化函数,意思是先接受两个参数(数据绑定mapStateToProps和事件绑定mapDispatchToProps),再接受一个参数(将要绑定的组件本身):
    mapStateToProps:构建好Redux系统的时候,它会被自动初始化,但是你的React组件并不知道它的存在,因此你需要分拣出你需要的Redux状态,所以你需要绑定一个函数,它的参数是state,简单返回你关心的几个值。
    mapDispatchToProps:声明好的action作为回调,也可以被注入到组件里,就是通过这个函数,它的参数是dispatch,通过redux的辅助方法bindActionCreator绑定所有action以及参数的dispatch,就可以作为属性在组件里面作为函数简单使用了,不需要手动dispatch。这个mapDispatchToProps是可选的,如果不传这个参数redux会简单把dispatch作为属性注入给组件,可以手动当做store.dispatch使用。这也是为什么要科里化的原因。

做好以上流程Redux和React就可以工作了。简单地说就是:
1.顶层分发状态,让React组件被动地渲染。
2.监听事件,事件有权利回到所有状态顶层影响状态。

模块化

时光回溯到2009年,CommonJS规范和NodeJS都还在襁褓之中,离Bower诞生还有三年时间,Ruby还统治着github,CoffeeScript在年末提交了第一个commit……
备受加载顺序,依赖关系折磨的前端开发,开始站起来试图解决日益复杂的前端开发的种种问题,RequireJS降临了。如果说NodeJS吹响了JS全栈革命的号角,那么同时发生的前端模块化革命便是RequireJS的历史使命。
五年过去了,RequireJS战胜了同级生LabJS,带起了中国小伙伴SeaJS。他完美地引领了前端模块化的革命,但今天看来,它有些过时了:它重浏览器端,轻打包编译,没有及时跟进包管理体系,almond没有成为标配而只是周边,配置晦涩……诞生太早的RequireJS,虽然一度成为了前端模块化的某种程度上的事实标准,但难掩其缺点。
为了解决这个问题,前端的模块管理器(package management)应运而生,五年间,NodeJS成为了服务端以及脚本工具的一代翘楚,NPM的成功让大家意识到一个集中式的依赖/包管理体系的重要性,Bower应运而生,还有试图将CMD和NPM包带到前端领域,统一前后端包格式的Browserify等等,大量的前端工具爆发式地出现,WebPack是其中的(又)一款模块打包工具。

Read More

模块化

随着网站逐渐变成”互联网应用程序”,嵌入网页的Javascript代码越来越庞大,越来越复杂。
网页越来越像桌面程序,需要一个团队分工协作、进度管理、单元测试等等……开发者不得不使用软件工程的方法,管理网页的业务逻辑。
Javascript模块化编程,已经成为一个迫切的需求。理想情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块。但是,Javascript不是一种模块化编程语言,它不支持”类”(class),更遑论”模块”module)了。(正在制定中的ECMAScript标准第六版,将正式支持”类”和”模块”,但还需要很长时间才能投入实用。)
Javascript社区做了很多努力,在现有的运行环境中,实现”模块”的效果。本文总结了当前"Javascript模块化编程"的最佳实践,说明如何投入实用。

Read More

编程风格

所谓”编程风格”(programming style),指的是编写代码的样式规则。不同的程序员,往往有不同的编程风格。

有人说,编译器的规范叫做”语法规则”(grammar),这是程序员必须遵守的;而编译器忽略的部分,就叫”编程风格”(programming style),这是程序员可以自由选择的。这种说法不完全正确,程序员固然可以自由选择编程风格,但是好的编程风格有助于写出质量更高、错误更少、更易于维护的程序。

所以,”编程风格”的选择不应该基于个人爱好、熟悉程度、打字量等因素,而要考虑如何尽量使代码清晰易读、减少出错。你选择的,不是你喜欢的风格,而是一种能够清晰表达你的意图的风格。这一点,对于JavaScript这种语法自由度很高的语言尤其重要。

必须牢记的一点是,如果你选定了一种“编程风格”,就应该坚持遵守,切忌多种风格混用。如果你加入他人的项目,就应该遵守现有的风格。

Read More

概述

函数就是一段可以反复调用的代码块。函数还能接受输入的参数,不同的参数会返回不同的值。

JavaScript有三种方法,可以声明一个函数。

Read More

思考

先想几个问题吧:

  1. JavaScript的数字为什么有0和-0?
  2. JavaScript中的NaN为什么互不相等?
  3. JavaScript中的数字真的只有一种类型吗?
  4. JavaScript中常被诟病的0.3 - 0.2 == 0.1原因是什么?
  5. 数组的最大长度是多少?为什么是这个值?

上述问题,只有在JavaScript中有吗?

Read More