知识共享许可协议

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

在不少框架中,都会对“扩展”这一概念有需求。所谓扩展,即一个可组合的组件,用于嵌入到目标的生命周期中,对目标的行为进行额外的处理使得目标拥有不同的表现。

一个非常简单的案例即日志的记录。通常框架自身并不会有业务相关的日志记录的功能,而业务代码也不希望混入并非业务逻辑的日志记录部分。那么使用一个扩展,在合适的点进行日志的收集和存储是很合适的设计。

在以往,比较流行的扩展通常有几种形式:

阅读全部

化解使用 Promise 时的竞态条件

原文:Defusing Race Conditions when Using Promises

网络时代,创建现代软件时其中一个很大的限制是所需要的数据往往在远程服务器上。应用程序在等待网络请求时简单地锁死是不现实(甚至不可能)的。相反,我们必须让应用程序在等待时保持响应。。

为此,我们需要写出并发的代码。当应用的某一部分正在等待网络请求的响应时,其他部分必须继续运行。 Promise 对于编写非阻塞型的代码是很不错的工具,而且你的浏览器就支持这个。

Promise 能让潜在可怕的异步代码变得非常友好。下面假设一个博客的文章视图这样从远程服务器加载一篇文章并显示它:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Called from `componentWillMount` and `componentWillReceiveProps`:
ArticleView.prototype.updateArticle = function (props) {
this.setState({
error: null,
title: null,
body: null
});
ArticleStore.fetch(props.articleID).then(article => {
this.setState({
title: article.title,
body: article.body
});
}).catch(err => {
this.setState({ error: 'Oh Noes!' });
});
};

注意:这个例子使用了 React,但是这个概念适用于绝大多数前端视图系统。

这样的代码是很优雅的。许多复杂的异步调用消失了,取而代之的是直接明了的代码。然而,使用 promise 并不能保证代码是正确的。

注意到我例子中引入的不易察觉的竞态条件了吗?

提示:竞态条件出现的原因是无法保证异步操作的完成会按照他们开始时同样的顺序。

阅读全部

前端代码风格检查套件 FECS

All code in any code-base should look like a single person typed it, no matter how many people contributed. — idiomatic.js

fecs

fecs 是以百度前端代码规范为目标的前端代码风格套件,套件包括 htmlcscsshintlesslintjformatter,此外还有社区的相关开源模块 cssbeautify、csscomb、fixmyjs 和 esformatter:

HTML CSS Less JavaScript
Linter htmlcs csshint lesslint eslint+
Fixer htmlcs cssbeautify csscomb cssbeautify csscomb fixmyjs jformatter esformatter

显而易见,fecs 不仅能检查 HTML/CSS/LESS/JavaScript 代码的规范问题,而且还能修复代码的规范问题。

代码检查

fecs-check

fecs-check

代码的检查,目前主要是以百度前端代码规范(JS/CSS/HTML) 的检查为首要目标,同时根据 EFE 的技术规划,为 Less 代码规范 的检查带来了 lesslint。

阅读全部

前端MVC变形记

背景:

MVC是一种架构设计模式,它通过关注点分离鼓励改进应用程序组织。在过去,MVC被大量用于构建桌面和服务器端应用程序,如今Web应用程序的开发已经越来越向传统应用软件开发靠拢,Web和应用之间的界限也进一步模糊。传统编程语言中的设计模式也在慢慢地融入Web前端开发。由于前端开发的环境特性,在经典MVC模式上也引申出了诸多MV*模式,被实现到各个Javascript框架中都有多少的衍变。在研究MV*模式和各框架的过程中,却是“剪不断、理还乱”:

  1. 为什么每个地方讲的MVC都不太一样?
  2. MVP、MVVM的出现是要解决什么问题?
  3. 为什么有人义正言辞的说“MVC在Web前端开发中根本无法使用”?

带着十万个为什么去翻阅很多资料,但是看起来像view、model、controller、解耦、监听、通知、主动、被动、注册、绑定、渲染等各种术语的排列组合,像汪峰的歌词似的。本篇希望用通俗易懂的方式阐述清楚一些关系,由于接触时间有限,英文阅读能力有限,可能会存在误解,欢迎讨论和纠正。

阅读全部

在 JavaScript 中实现私有成员的语法特性

前言

在面向对象的编程范式中,封装都是必不可少的一个概念,而在诸如 Java,C++等传统的面向对象的语言中, 私有成员是实现封装的一个重要途径。但在 JavaScript 中,确没有在语法特性上对私有成员提供支持, 这也使得开发人员使出了各种奇技淫巧去实现 JS 中的私有成员,以下将介绍下目前实现 JS 私有成员特性的几个方案以及它们之间的优缺点对比。

阅读全部

避免使用 forEach

原文:http://aeflash.com/2014-11/avoid-foreach.html

遍历集合,会产生副作用。——如 mori.each 文档所说

首先声明,本文和性能无关。执行 for 循环总是比执行 Array.forEach 快。如果性能测试显示迭代的开销足够显著并且性能优先,那么你绝对应该使用 for 循环而不是 forEach(总是使用 for 循环是典型的过早优化。forEach 仍然可以在 1 微秒内遍历长度为 50 的数组)。本文和编码风格有关,是我对 forEach 和其它 Array.prototype 方法的思考,与性能无关。

阅读全部