Redux

发布redux-optimistic-thunk

近期因为一些外部的因素,不得不开始尝试使用React + Redux的组合,在学习并使用了一周之后,我实现并发布了这个用于解决Optimistic UI问题的redux-optimistic-thunk中间件: GitHub地址:https://github.com/ecomfe/redux-optimistic-thunk npm地址:https://www.npmjs.com/package/redux-optimistic-thunk 本文中所有“Optimistic”翻译为“乐观”,大致指在涉及到外部服务的用户交互产生时,通过一定的技术手段在短时间内向用户提供操作的反馈,而不等待外部服务的响应,Cola Chan的文章比较详细地论述了这一模式。 先通过动画展示一下这个中间件工作时的效果(图片4.4MB,请耐心等待): 从图中可以看到一个10s延迟和一个5s延迟的项目在提交时会立刻被添加到列表的顶端,

ECMAScript6

强迫症的模块化

在ES2015发布后,JavaScript最终也有了一个标准的模块化方案,而同时从webpack开始,也带来了一波“一切皆模块”的潮流。整个2015-2016的前端发展中,除去在UI层不断的努力和突破外,几乎每一件事都和模块化脱不开关系。 本文也试图从几个方面简单地说一下模块化,并分析一些在模块化实施中产生的误区。 模块的本质 模块化顾名思义,指的必然是将程序拆分为多个“模块”,使用模块间通信的方式进行交互。这和其它对程序逻辑进行拆分的手段是一样的,无论是拆成类、拆成对象还是拆成啥,其目的无非是隔离内部的实现以及声明对外的接口。 事实上自远古时代起,JavaScript就在努力进行实现封装的尝试,无论是通过IIFE避免全局变量,还是基于Namespace进行管理,以至后期的AMD、CJS社区模块化方案,直到现在的ES Module标准模块化,无不以上为目的。 在模块化的思想里,一个模块应该是: 需要一系列的依赖。 涉及一个内部的实现。

JavaScript

使用高阶函数实现类的扩展设计

在不少框架中,都会对“扩展”这一概念有需求。所谓扩展,即一个可组合的组件,用于嵌入到目标的生命周期中,对目标的行为进行额外的处理使得目标拥有不同的表现。 一个非常简单的案例即日志的记录。通常框架自身并不会有业务相关的日志记录的功能,而业务代码也不希望混入并非业务逻辑的日志记录部分。那么使用一个扩展,在合适的点进行日志的收集和存储是很合适的设计。 在以往,比较流行的扩展通常有几种形式: Mixin形式。这种形式下扩展与目标形成完全的覆盖关系,属于暴力而简单的方法。 class Component { constructor({mixins}) { mixins.forEach(mixin => Object.assign(this, mixin)); } doWork() { // ... } } let logMixin

JavaScript

ES Decorators简介

我跟你说,我最讨厌“简介”这种文章了,要不是语文是体育老师教的,早就换标题了! Decorators是ECMAScript现在处于Stage 1的一个提案。当然ECMAScript会有很多新的特性,特地介绍这一个是因为它能够在实际的编程中提供很大的帮助,甚至于改变不少功能的设计。 先说说怎么回事 如果光从概念上来介绍的话,官方是这么说的: Decorators make it possible to annotate and modify classes and properties at design time. 我翻译一下: 装饰器让你可以在设计时对类和类的属性进行注解和修改。 什么鬼,说人话! 所以我们还是用一段代码来看一下好了:

使用ES6进行开发的思考

ECMAScript6已经于近日进入了RC阶段,而早在其处于社区讨论时,我就开始一直在尝试使用ES6进行开发的方案。在Babel推出后,基于ES6的开发也有了具体可执行的解决方案,无论是Build还是Debug都能得到很好的支持。 而在有了充足的环境、工具之后,我们面临的是对ES6众多新特性的选择和分析,以便选取一个最佳的子集,让我们可以享受ES6带来的便利(减少代码量、提高可读性等)的同时,也可以顺利运行于当前以ES3-ES5为主的浏览器环境中。 整体结论 以下是在经过分析后得出的一个初步结论,ES6的特性列表选自es6features。 在本文中,会将这些特性分为几个类型,并一一解释其使用场景。 ★★★ 推荐使用 ★★ 有考虑地使用 ★ 慎重地使用 ☆ 不使用 特性推荐程度 arrows★★★ classes★★★ enhanced object literals★★★ template strings★

JavaScript

PC端大型单页式商业内容管理系统的JS模块化构建探索

前提 为了不被喷得太惨,给标题加了这么多的限制定语也是相当不容易的了。此文讨论的是我所处的环境下对JavaScript构建的一些简单探索,因此有相当多的前提限制。 首先,何为大型。从我们的系统来看,20多个业务模块,近100个页面组成的单页系统,对应的业务源码代码量如下: 对应的依赖库,除underscore和moment外均为公司内部库,代码量为: 其次,所谓的“模块化”指我们使用AMD进行构建,使用符合社区AMD标准的Loader进行模块的加载。 而“PC端单页式商业内容管理系统”则代表着系统的不少特性: 使用是相对强制的,对用户来说这是一项工作,而不是爱用不用的用户产品。 商业公司通常拥有较好的网络环境,面向PC设计更使得带宽不是一个需要着重考虑的因素。 单页系统使得所有功能被包含在一个HTML页面内,不存在页间的跳转,因此资源不以页面为单位进行切分。 为何要构建 第一个问题是,AMD有自然的按需加载的属性,

设计

聊一聊复用

复用是每一个工程师的追求,无论是设计还是编码我们最常说的除了“产品是SB”、“进度赶不上”外,恐怕就是“要好好复用”了吧。当一个应用或者一个系统日趋复杂的时候,我们总是希望其维护性不会线性地降低,而解决这一问题的方法上,就往往归结为简单的“复用”二字。 在与不少同学的沟通中,我发现有一部分工程师对“复用”的理解是有失偏颇的,在此针对比较容易出现的几类曲解进行一下解说。 复用的目的 我的论断很简单: 复用有很多的目的,但少写代码不应是其中一个。 注意这边说的是,少“写”代码不应该是复用的目的之一。所谓的“写”,是一个人所做出的行为,复用作为一种工程手段,其应该解决的是工程的问题,而不是人的问题。

JavaScript

博客单页化实践

这个单页化的博客现在也没在用了,Ghost平台挺好的……如果需要看代码的话,请参考GitHub上的仓库 半年前,因为VPS未续费导致所有数据丢失,直至今日终于重新恢复了所有的文章数据(虽然丢失了全部的评论),并且借此机会对所有文章进行了一次重新审视,修改了部分问题,并将所有示例迁移到jsfiddle和jsperf上,总算造一段落。 新的博客完全独立建设,不使用任何第三方的CMS系统,后端使用ASP.NET MVC实现,数据库使用MySQL,通过Mono部署于Ubuntu Server之上,前端使用nginx作为静态服务器。 也正因为完全独立构建,不受任何系统出于安全、简便等奇怪理由而附加的限制,这个博客系统也成了自己练手的娱乐场。就比如本篇要介绍的OPOA化实践。 概念 OPOA,全称One Page One Application,中文可以称之为单页应用。

JavaScript

浅谈eval的影响

听闻最近由于老赵在其Wind.js关于eval这一函数使用上与BYVoid进行了一系列的争论,甚至为此写了一篇博客来证明eval对性能的影响可以忽略这一观点。 而不幸由于在这一次讨论中,起于Ericpoon_智对eval性能影响的疑问,也不知不觉参与了一些讨论,随后_Franky提出要有数据上的事实来说明这一问题,于是在好久没有新的博客出产的时候,决定对这一问题进行一下非常浅薄的挖掘,提供一些客观的数据。 首先在此文中,需要声明的是: 个人倾向于不要计较eval产生的影响。 此文会从**eval有负面影响**这一角度进行表述和举例,与老赵的博客属于完全相反的观点,但并不是一种对其的驳斥或者反对,仅仅是希望可以提供一些客观的理论依据。 本文只谈V8引擎,由于这一问题是不同引擎的表现会大不相同,不可能完全覆盖,因此数据不可作为权威参考。 本人不懂C或C++,看不懂V8,因此完全是黑盒的推断,各结论也不具权威意义,完全可能是臆测,当然数据保证真实。 以下是本次测试使用的Chrome版本详细信息: Google

JavaScript

所谓闭包的PPT

这是近期一次内部分享的PPT,从函数的相关概念上,主要内容有: 变量的概念。 闭包的表象。 核心概念,包括可执行代码、执行环境、词法环境、变量环境、环境数据、绑定对象等。 函数的相关过程,包括创建函数、进入函数、定义绑定初始化、变量查找等。 闭包对垃圾回收的影响的探究。 PPT权当对新事物的一种普及性展示,不会有深入的内容,也不会有详细的例子,如果有任何疑问,欢迎随时交流。 如需观看或下载,请点击此处。

JavaScript

关于闭包及变量回收问题

本文的诞生,源自近期打算做的一个关于javascript中的闭包的专题,由于需要解析闭包对垃圾回收的影响,特此针对不同的javascript引擎,做了相关的测试。 为了能从本文中得到需要的知识,看本文前,请明确自己知道闭包的概念,并对垃圾回收的常用算法有一定的了解。 问题的提出 假设有如下的代码: function outer() { var largeObject = LargeObject.fromSize('100MB'); return function() { console.log('inner'); }; } var inner = outer(); 在这一段代码中,outer函数和inner函数间会形成一个闭包,致使inner函数能够访问到largeObject,但是显然inner并没有访问largeObject,那么在闭包中的largeObject对象是否能被回收呢? 如果引入更复杂的情况: function

杂想

另类MVC模式 - 优势及实现

继续大逆不道系列…… 在上一篇中,提出了一个另类的MVC模型,与经典MVC模型有一些不同,那么自然需要描述这样的另类模型有什么优势,又能在怎么样的场景中使用。 逻辑划分 正如上一篇所说,这种模式下,最大的优势莫过于逻辑的清晰划分。在该模式的作用下,每一个Action都只要处理真正与自己有关的逻辑及数据,而不需要关心一些“通用”的内容,因为这些通用内容也成了独立的Action。 例如,继续引用上一篇中的页面设计,根据经典的MVC模式,我们不得不在一个Action中准备所有数据: public ActionResult ViewPost(int id) { ViewBag.Friends = FriendsRepository.ByUser(CurrentUser); ViewBag.RecentVisitors = VisitorsRepository.

杂想

另类MVC模式 - 思考和雏形

这是一篇大逆不道的文章,其作用就是供大家娱乐以及批斗,因为此文所提及的思想,试图改变现有的著名模式MVC的结构,因此如果认为MVC优秀甚至完美的话,还请直接忽略此文,以免影响心情。 本文将提出一种类似MVC但又不完全是现有的经典MVC的模式,该模式仅基于HTTP的Web系统中对经典的MVC模式进行改造,其特点是将View前置,通过View的切分来切分逻辑,形成多次M-V-C交互,最终生成响应。 经典MVC模式 对于经典的MVC模式,虽然从表面上看完全是个“不需要解释”的问题,但是每个人的理解又不尽相同。在我的理解中,MVC模式可以用下面这张图来表达: 基于HTTP的Web系统里,在经典的MVC模式中,一个请求的处理过程大致分为: Controller处理原始请求,根据请求的数据与系统的配置,寻找到真正处理该请求的逻辑,称之为Action。 Action处理请求提交的数据,与Model进行交互,获取需要反馈的数据,并将这些数据按View的要求组装后交给View。 View根据Action递交的数据,

JavaScript

不完美沙箱 - 变量定义及查找

时隔N久,继续生产,年底实在忙…… 在上一篇发表之后,有网友指出这个沙箱过于复杂,事实上一些更简单的代码也能完成同样的效果,例如: var proxy = { document: new DocumentProxy() }; function(window) { // 开发者提交的代码 }.call(proxy, proxy); 通过call和函数参数来劫持this及window这两个指向全局对象的变量,以达到屏蔽全局对象的目的。 但是这个方式虽然简单易懂,却有一个非常重要的环节无法照顾到,即全局环境下LexicalEnvironment和VariableEnvironment和ThisBinding均是全局对象,这一特性意味着在全局环境下执行的代码将同时满足以下4个条件: 通过var x = 3;定义的变量,可以使用console.log(x);输出。 通过this.

JavaScript

不完美沙箱 - 模拟全局对象

上一章中,经过对标准的查询、翻阅、解析,终于在绕了一个大圈之后,明白了全局对象的特征,并明确了模拟一个全局对象需要的内容,还为此编写了简单的测试用例。本文将从第1个测试用例着手,放眼与全局作用域的VariableEnvironment、ThisBinding以及window别名这三者的一致性,来推导出一个沙箱的原型。 所谓纰漏 在开始这一章以前,首先不得在这里道个歉,原因很简单,我对标准进行了误读,且在没有测试的情况下就开始了这一系列的博客。事实上,以我的思路,是无法制作出一个理想中的沙箱的,虽然可以控制住第三方代码的作用区域,但是无法做到完全的透明,其主要问题出在这里: var x = 3; console.log(this.x); // 打印出3 事实上,

JavaScript

不完美沙箱 - 劫持全局对象

上一章中对需求进行了分析,并对实现方案有了一定的探讨,最终得出从劫持全局对象这一环节入手的结论,而本文将讨论如何劫持这个全局对象。 全局对象,多数会进行Javascript编程的工程师都知道,在浏览器的执行环境中,叫做window,虽然事实上window和全局对象并不严格意义上是一个东西,不过这对我们的实现并不会造成什么障碍。 剖析全局对象 既然要去做劫持全局对象这样不人道的事,自然先要知道全局对象是个什么东西,有什么样的特点,以便针对目标,一刀致命。这个时候,标准就会成为我们最好的参考,首先打开ECMAScript 5的HTML版本,此后几乎所有的标准引用都会从这里产生。 所谓擒贼先擒王,经典理论告诉我们,不可以把整个洋洋洒洒数万字的标准给全看了,必须以快、狠、准的手段找到我们需要的东西。如果是纸质的书籍,对于一个不熟悉文档结构的人而言自然是无处下手,但好在现在是数字化的时代,我们有一个名为“搜索”的强大功能。

JavaScript

不完美沙箱 - 目的、背景及分析

目的 这将是一个系列的文章,大致由4篇博文组成,内容应该会是这样的: 目的、背景及分析 劫持全局对象 劫持全局对象属性 存在的问题及漏洞 起草这一系列博文的原因有两点,第一自然是因为最近突然有这样的需求,而群里正好也在某个深夜(技术宅基本深夜活动)讨论到了一个类似的话题,给了我一些灵感,所以决定将近期“研究”的成果展示一下。 而第二个目的,也是我想将这么一个简单的东西(其中最终就10几行代码)用整整5个博文的篇幅来说的原因,是因为近期有不少朋友向我强烈地表达了标准的存在意义极其微弱,我能把代码写好就足够的想法,而且现在更是催生了一种叫做jQuery工程师的职位,大有星星之火的样子。 对于这样的态度,作为一个只会理论不懂实践的2B工程师,个人自然是坚持地抱以反击态度的,因此,这一系列的博文,将会从“构建一个沙箱”

JavaScript

ECMAScript5小试PPT

这是近期一次内部分享的PPT,其中内容主要来自于Franky教主的相关材料,并加入了一些对ECMAScript Harmony的补充资料。同时可以在这里下载到教主的原版PPT。 对于ECMAScript,由于本人也不甚了解,其中一些诡异的问题和隐隐的矛盾(在Harmony中会体现得特别明显)暂时也没有精力去一一追究,PPT权当对新事物的一种普及性展示,不会有深入的内容,也不会有详细的例子。 如需观看或下载,请点击此处。

性能

浏览器渲染原理PPT

这是今天一次内部分享的PPT,其中内容主要来自于Winter大大分享的相关材料,和How Browser Work这一文的一些内容。 由于内部分享是以讲为主,因此PPT并不包含所有内容,仅仅是一个摘要的形式,另有以下几点: 配合PPT中的注解,可以有更好的效果。 相关的DEMO均链接到了jsfiddle的地址,由于仅为演示使用,因此DEMO页面没有经过严密的处理,仅支持Chrome和Firefox查看,且“运行”按钮需按顺序点击,第一个示例未完成前运行第二个可能造成悲剧性后果。 绝对不要使用IE9以下浏览器打开特别是“布局”章节中的示例,否则造成任何实物及精神上的操作概不负责。使用Chrome等高级浏览器打开该示例会造成一定程度的假死现象,请耐心等待。 PPT仅说明了整个分享的主要内容点,由于涉及的内容较多,也无法在其中对每个细节进行详细的阐述,如果对任何细节有所疑问,可以回复本篇博客,我会在时间宽裕的时候努力回复(最近忙得想去撞动车,回复不及时请勿见怪)

CSS

CSS语法简单学习

有这个博文的原因是,最近想做一个CSS的工具,至于工具的作用,先暂时不公开了,有兴趣的朋友可以邮件单独和我联系讨论下。为了这个工具,首先需要有一个CSS解析器,我称之为CSSParser,同时这个解释器和普通的基于Lex的词法分解+LR1的语法分析不同,他并不按标准给定的语法进行严格的检查,而仅仅分解出CSS中的各个元素。 为此,第一步自然是对CSS的语法有一个简单的了解,无论我的解释器是否按标准的语法进行解释,至少CSS语言的组成部分是必须明确的。此文也谨作总结之用。 整体组成 在CSS中,顶层元素被称为Rule,而CSS中的Rule又分为2类:CSSStyleRule和CSSAtKeywordRule。 CSSStyleRule是最基本的,即我们最常见的,由选择器+属性+值组成的部分,以下就是一个简单的示例: #nav>li~li { float:

JavaScript

JavaScript中的对象查找

近期群里常有人提一些简单的问题,比如发一段代码乱七八糟的代码,然后说里面某个变量是什么,比如这里就有个很好的例子: function fn(arg) { console.log(this.arg); console.log(this); } fn(123); var o = { fn: fn }; o.fn(123); 然后就可能有这样的问题: 为什么this.arg是undefined?为什么2次调用fn的this是不一样的? 为此,我觉得自己作为一个虽然不成熟的前端,对于一些自己力所能及的事情,还是应该传道授业解惑的。所以,这篇文章,

HTML

HTML5标准学习 – 编码

相信每一个前端工程师都或多或少遇上过“乱码”这位仁兄,无论你的基础有多么扎实,在生产的过程中都免不了偶尔和“乱码”兄弟喝上几杯茶吧。作为一个前端工程师,你是如何指定一个页面的编码的呢?你知道浏览器是怎么识别编码的吗? 首先,一个很简单的例子,用遇简的HTML页面来看看各浏览器下有什么不同: <!DOCTYPE html> 最简HTML,<head>和<body>都没有内容,服务器也不给出具体的编码声明,直接从本地打开,各个浏览器下查看页面的编码: 浏览器 显示编码 备注 IE6

HTML

HTML5标准学习 – DOCTYPE

上一篇文章主要讲述了HTML文档的构成,同时肤浅地接触了“标签省略”这一概念,本文会从概念上介绍HTML文档中第一个出现的重要元素 – DOCTYPE。 所谓DOCTYPE,最初是XML的概念,即通过一种特定的语法,作为一种元数据,来描述XML文档中允许出现的元素,以及各元素的组成、嵌套规则等。具体的概念可以在WIKI中得到一个更详细的结果。 但是在HTML中,DOCTYPE又有着一些不同的效果,其中之一就是著名的触发浏览器标准模式的功能。即如果没有DOCTYPE,浏览器会进入一种被称为Quirks模式的怪异状态,在该模式下,浏览器的盒模型、样式解析、布局等都与标准规定的存在差异。 需要注意的是,所谓的HTML标准、DOM标准等,只规定了在标准模式下的概念和行为,正如文档构成中提到的,DOCTYPE是一个HTML文档绝对不可以省略的部分,因此就根本不存在“Quirks模式”这样的概念。也正是因为标准中没有对Quirks模式做出任何的规定,