《编写可维护的 JavaScript》笔记三

返回列表

读书笔记 | 小叉 | 2013年08月30日

【第5章 UI层的松耦合】

在 Web 开发中,用户界面(User Interfaoe, UI)是由三个彼此隔离又相互作用的层定义的。

  • HTML 用来定义页面的数据和语义。

  • CSS 用来给页面添加样式,创建视觉特征。

  • JavaScript 用来给页面添加行为,使其更具交互性。


5.1 将 JavaScript 从 CSS 中抽离

避免使用 CSS 表达式(CSS Expression)

※ IE9 不再支持 CSS 表达式


5.2 将 CSS 从JavaScript 中抽离

修改 DOM 元素的 className,而不是修改 DOM 元素的 style

// 原生方法
element.className += "newclass";

// HTML5
element.classList.add("newclass");

// YUI
Y.one(element).addClass("newclass");

// jQuery
$(element).addClass("newclass");

// Dojo
dojo.addClass(element, "newclass");

※ 在重新给元素定位时,可以直接修改 style 的 top、left、bottom、right 属性,因为在 CSS 中无法完成。可以在 CSS 中定义元素的默认属性,而在 JavaScript 中修改这些默认属性。


5.3 将 JavaScript 从 HTML 中抽离

避免使用 on 属性(例如 onclick)来绑定事件处理程序:

// 不好的写法
<button onclick="doSomething()" id="action-btn">Click Me</button>

使用 JavaScript 方法来添加事件处理程序,更好的方法:

function addListener(target, type, handler) {
    if (target.addEventListener) {
        target.addEventListener(target, type, handler);
    } else if (target.attachEvent) {
        target.attachEvent("on" + type, handler);
    } else {
        target["on" + type] = handler;
    }
}

function doSomething(){
    // 代码
}
var btn = document.getElementById("action-btn");
addListener(btn, "click", doSomething);

一些常见类库的方法:

// YUI
Y.one("#action-btn").on("click", doSomething);

// jQuery
$("#action-btn").on("click", doSomething);

// Dojo
var btn = dojo.byId("action-btn");
dojo.connect(btn, "click", doSomething);)


5.4 将 HTML 从 JavaScript 中抽离

方法 1:从服务器加载

将模板放在服务器,通过 Ajax 方法从服务器读取模板。


方法 2:简单客户端模板

通过一些标识,通过 JavaScript 替换内容。


方法 3:复杂客户端模板

使用模板引擎,如:Handlebars(http://handlebarsjs.com)。



【第6章 避免使用全局变量】

在浏览器中, window 对象往往重载并等同于全局对象,因此任何在全局作用域中声明的变量和函数都是 window 对象的属性。

  • 始终使用 var 声明变量

  • 使用命名空间

  • 使用模块


“异步模块定义”(AMD)

AMD 规范:https://github.com/amdjs/amdjs-api/wiki/AMD


零全局变量(匿名函数)

(function(win) {
    var doc = win.document;
    // 在这里定义其他的变量
    // 其他相关代码
})(window);



【第7章 事件处理】

当事件触发时,事件对象(event 对象)会作为回调参数传入事件处理程序中。event 对象包含所有和事件相关的信息,包括事件的宿主(target)以及其他和事件类型相关的数据。

  • 鼠标事件会将其位置信息暴露在 event 对象上;

  • 键盘事件会将按键的信息暴露在 event 对象上;

  • 触屏事件会将触摸位置和持续时间(duration)暴露在 event 对象上。


规则:

  1. 隔离应用逻辑

  2. 不要分发事件对象



【第8章 避免“空比较”】

8.1 检测原始值

检测字符串、数字、布尔值或 undefine,最佳选择是使用 typeof 运算符。

  • 对于字符串,typeof 返回“string”

  • 对于数字,typeof 返回“number”

  • 对于布尔值,typeof 返回“boolean”

  • 对于 undefined,typeof 返回“undefined”


8.2 检测引用值

引用值也称作对象(object)。

在 JavaScript 中除了原始值之外的值都是引用。

内置的引用类型:Object、Array、Date 和 Error。

typeof 运算符在判断这些引用类型时都会返回“object”。

检测某个引用值的类型的最好方法是使用 instanceof 运算符。instanceof 的基本语法是:

value instanceof constructor

// 例子:检测日期
if (value instanceof Date) { // 代码 }

// 例子:检测正则表达式
if (value instanceof RegExp) { // 代码 }

// 例子:检测 Error
if (value instanceof Error) { // 代码 }

instanceof 不仅检测对象的构造器,还检测原型链。默认情况下,每个对象都继承自 Object,因此每个对象的 value instanceof Object 都会返回 true。

※ instanceof 不支持跨 frame


8.2.1 检测函数

检测函数最好的方法是使用 typeof 运算符。

对于函数,typeof 返回“function”。

※ 在 IE 8 及以下的 IE 中,使用 typeof 来检测 DOM 节点(比如:document.getElementById())中的函数都会返回“object”而不是“function”。


8.2.2 检测数组

ECMAScript5 将 Array.isArray() 正式引入 JavaScript。

// 兼容旧浏览器的方法
function isArray(value) {
    if (typeof Array.isArray === "function") {
        return Array.isArray(value);
    } else {
        return Object.prototype.toString.call(value) === "[object Array]";
    }
}

※ IE 9+、Firefox 4+、Safari 5+、Opera 10.5+ 和 Chrome 都实现了 Array.isArray() 方法。


8.3 检测属性

判断属性是否存在的最好的方法是使用 in 运算符。

in 运算符仅仅会简单的判断属性是否存在,而不会去读属性的值。如果对象的属性存在,或者继承自对线的原型,in 运算符都会返回 true。


如果你只想检查实例对象的某个属性是否存在,则使用 hasOwnProperty() 方法。如果实例中存在这个属性则返回 true(如果这属性值存在于原型里,则返回 false)。

※ 在 IE 8 及以下的 IE 中,DOM 对象并非继承自 Object。

  1. cereus'@
    赞!
    2014-12-23 16:04:58
  2. 游客
    柏小白:“口头表扬2次 ”
    2015-11-25 15:06:14

这里是小叉试验场的简版,请到正式版参与评论

下一篇:教你怎么把图标字体(IconFont)转为 PNG

上一篇:《编写可维护的 JavaScript》笔记二

返回列表