当我们谈代码编译转换时我们在谈论什么?
通过工具对原代码进行一定的加工处理,最后生成目标代码。一些典型场景:ES6 -> ES5,不大典型,但实用的场景:Vue 组件转换成 React 组件。
通过工具对原代码进行一定的加工处理,最后生成目标代码。一些典型场景:ES6 -> ES5,不大典型,但实用的场景:Vue 组件转换成 React 组件。
在前端的 JavaScript 开发中,发现开发者对于错误异常的处理普遍都比较简单粗暴,如果应用程序中缺少有效的错误处理和容错机制,代码的健壮性就无从谈起。
本文整理出了一些常见的错误异常处理的场景,旨在为前端的 JavaScript 错误异常处理提供一些基础的指导。
先来简单介绍一下 JavaScript 中的 Error 对象,通常 Error 对象由重要的两部分组成,包含了 error.message
错误信息和 error.stack
错误追溯栈。
产生一个错误很简单,比如在 foo.js
中直接调用一个不存在的 callback
函数。
// foo.js
function foo () {
callback();
}
foo();
此时通过 Chrome 浏览器的控制台会展示如下的信息。
模块化在前端日新月异的工程化工具的推动下已经摆脱了前端模块加载器(SeaJS、RequireJS)的束缚,现在通常的方案是使用 browserify 或 webpack 来将模块化的文件打包,然后直接在浏览器端使用。
但是通常的打包策略是将整个项目打包成一个文件 bundle.js,默认情况下 bundle.js 中囊括了所有的依赖,包括第三方的从 node_modules 中加载的文件,这会造成 bundle.js 非常臃肿,而且在生产环境中不能很好的利用静态资源的缓存策略。这些打包技术在国外非常火,生产环境提供一个 bundle.js 的做法在国外的网络环境下毫无压力,但是国内的网络环境和国外的没法比,为了下载的性能还是建议分开打包。
分开打包还有一个好处就是,目前的前端开发环境现在都流行使用监测文件的变化而使用 livereload 技术,这也意味着会存在实时动态打包的需求,分开打包对于实时打包的速度有质的影响,对于基本不会变化的第三方模块没有必要每次做实时动态打包的时候都包含进去。
在 JavaScript 中,对象是引用类型的数据,其优点在于频繁的修改对象时都是在原对象的基础上修改,并不需要重新创建,这样可以有效的利用内存,不会造成内存空间的浪费,对象的这种特性可以称之为 Mutable,中文的字面意思是「可变」。
对于 Mutable 的对象,其灵活多变的优点有时可能会成为其缺点,越是灵活多变的数据越是不好控制,对于一个复杂结构的对象来说,一不小心就在某个不经意间修改了数据,假如该对象又在多个作用域中用到,此时很难预见到数据是否改变以及何时改变的。
var obj = { /* 一个复杂结构的对象 */ }; doSomething(obj); // 上面的函数之行完后,此时的 obj 还是最初的那个 obj 吗?
针对这种问题,常规的解决办法可以通过将对象进行深拷贝的形式复制出一个新的对象,再在新对象上做修改的操作,这样能确保数据的可控性,但是频繁的复制会造成内存空间的大量浪费。
var obj = { /* 一个复杂结构的对象 */ }; // copy 出一个新的 obj2 // 但是 copy 操作会浪费内存空间 var obj2 = deepClone(obj); doSomething(obj2); // 上面的函数之行完后,无论 obj2 是否变化,obj 肯定还是原来那个 obj
由于 React 的单向数据流的设计,衍生出了单向数据流的架构模式 Flux。
在 MVC 的分层架构中,Flux 属于 M 层,也就是 Model,而在 Flux 中,Store 是关键部分,Action 和 Dispatcher 都是围绕着 Store 来设计的,所以 Flux 架构模式的目标就是基于单向数据流如何更好的管理数据,在 Views
或 Controller-views
与数据之间进行解耦。
我在之前的 React 应用的架构模式 Flux 有详细的介绍过 Flux 架构模式及其应用。
"Flux is more of a pattern than a framework."
这是 Flux 在其 github 主页上截取的一句话,翻译成中文就是:Flux 更像是一种架构模式,而不是一个单纯的框架。