- 5种类型:undefined, boolean, string, number, object
- 使用typeof结果新增:null, function
- ECMAScript5中为数组提供五种迭代方法
- every(), filter(), forEach(), map(), some()
- every和some:数组中数据是否满足条件,return true/false
- 使用函数的值取代函数名
- 如下错误
function(){ //这里是块级作用域 }(); //出错
- 可修改为如下:
(function(){ //这里是块级作用域 })(); //正确
- DOM1没有规定事件处理
- DOM0级,绑定click方法,只能单个事件
- DOM2级,addEventListener(),可以多个事件
- 包含三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段
- DOM3级,包括以下及部分内容
- UI事件
- load, unload, select, resize
- 焦点事件
- focus
- 鼠标事件
- mousedown
- mouseup
- click
- mousedown
- mouseup
- click
- dbclick
- 滚轮事件
- mousewheel
- 键盘事件
- keydown
- keypress
- keyup
- 文本事件
- textInput
- 复合事件
- 仅有IE9+支持
- 变动事件
- DOM中的某一部分发生变化时给出提示
- UI事件
- JavaScript最佳实践
- 可维护性
- 可维护的代码
- 可理解性
- 直观性
- 可适应性
- 可扩展性
- 可调试性
- 代码约定
- 可读性
- 变量和函数命名
- 变量类型透明
- 使用合适的命名方式
- 匈牙利标记法
- o:对象
- s:字符串
- i:整数
- f:浮点数
- b:布尔型
- 类型注释
- 松散耦合
- 解耦HTML/JavaScript
- 解耦CSS/JavaScript
- 解耦应用逻辑/事件处理程序
- 编程实践
- 尊正对象所有权
- 简单的说:如果不负责创建或维护某个对象,就不能对它们进行修改
- 具体地说:
- 不要为实例或原型添加属性
- 不要为实例或原型添加方法
- 不要重定义已存在的方法
- 避免全局量
//两个全局量——避免!! var name = "Nicholas"' function sayName(){ Alert(name); } //一个全局量——推荐 var MyApplication = { name : "Nicholas", sayName : function(){ alert(this.name); } };
- 避免与null进行比较
- 如果值应为一个引用类型,使用instanceof操作符检查其构造函数
- 如果值应为一个基本类型,使用typeof检查其类型
- 如果是希望对象包含某个特定的方法名,则使用typeof操作符确保指定名字的方法存在于对象上。
- 代码中的null比较越少,就越容易确定代码的目的,并消除不必要的错误
- 使用常量
- z定义Constants类,编写常量key/value值
- 重复值
- 用户界面字符串
- URLs
- 任意可能会更改的值
- 尊正对象所有权
- 可维护的代码
- 性能
- 注意作用域
- 避免全局查找(涉及作用域链上的查找)
- 避免with语句
- 选择正确方法
- 避免不必要的属性查找(一次查找复杂度O(n))
- 一旦多次用到对象属性,应该将其存储在局部变量中
- 优化循环
- 减值迭代(很多情况下更高效)
- 简化终止条件
- 简化循环体
- 使用后测试循环(避免第一次的判断)
- 展开循环
- 当循环次数是确定的,消除循环并使用多次函数调用往往更快
- 可以消除建立循环和处理终止条件的额外开销
- 若迭代次数不能事先确定,可以考虑使用一种叫Duff装置的技术
- 当循环次数是确定的,消除循环并使用多次函数调用往往更快
- 避免不必要的属性查找(一次查找复杂度O(n))
// Jeff Greenberg for JS implementation of Duff's Device // 假设:values.length 0 function process(v) { alert(v); } var values = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]; var iterations = Math.ceil(values.length / 8); var startAt = values.length % 8; var i = 0; do { switch(startAt) { case 0 : process(values[i++]); case 7 : process(values[i++]); case 6 : process(values[i++]); case 5 : process(values[i++]); case 4 : process(values[i++]); case 3 : process(values[i++]); case 2 : process(values[i++]); case 1 : process(values[i++]); } startAt = 0; }while(--iterations 0);
- 达夫设备背后的基本理念是:
- 每次循环中最多可8次调用process()函数,循环迭代次数为元素总数除以8
- 因为总数不一定是8的整数倍,所以startAt变量存放余数,指出第一次循环中应当执行多少次process()。
- 比方说现在有12个元素,那么第一次循环将调用process()4次,第二次循环调用process()8次,用2次循环代替了12次循环。
- tips: case语句找到第一个匹配的语句之后,未遇见break语句时,后面的语句将会依次执行。
- 03年改进版本,先处理余数部分,几乎增速40%
// Speed Up Your Site(New Riders, 2003) function process(v) { alert(v); } var values = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]; var iterations = Math.floor(values.length / 8); var leftover = values.length % 8; var i = 0; if(leftover 0) { do { process(values[i++]); }while(--leftover 0); } do { process(values[i++]); process(values[i++]); process(values[i++]); process(values[i++]); process(values[i++]); process(values[i++]); process(values[i++]); process(values[i++]); }while(--iterations 0);
- 注意作用域
- 避免双重解释
- 在以下例子中,都要解析包含JavaScript代码的字符串
- 这是不能再初始的解析过程中完成的,因为代码是包含字符串中的。
- 必须在代码运行的同时新启动一个解析器来解析
- 实例化一个新的解析器有不容忽视的开销
//某些代码求值——避免!! eval("alert('Hello world!')"); //某些代码求值——已修正 alert('Hello world!'); //创建新函数——避免!! var sayHi = new Function("alert('Hello world!')"); //创建新函数——已修正 var sayHi = function(){ alert('Hello world!'); }; //设置超时——避免!! setTimeout("alert('Hello world!')", 500); //设置超时——已修正 setTimeout(function(){ alert('Hello world!'); }, 500);
- 性能的其他注意事项
- 原生方法较快
- Switch语句较快
- 位运算符较快
- 可维护性
- 最小化语句数
- JavaScript代码中语句数量也影响所执行的操作的速度
- 完成多个操作的单个语句要比完成单个操作的多个语句快
- 多个变量声明
//4个语句——很浪费 var count = 5; var color = "blue"; var values = [1, 2, 3]; var now = new Date(); //一个语句 var count = 5, color = "blue"; values = [1, 2, 3]; now = new Date();
- 插入迭代值
var name = values[i++];
- 使用数组和对象字面量
//用4个语句创建和初始化数组——浪费 var values = new Array(); values[0] = 123; values[1] = 456; values[2] = 789; //用1个语句创建和初始化数组 var values = [123, 456, 789]; //用4个语句创建和初始化对象——浪费 var person = new Object(); person.name = "nicholas"; person.age = 29; person.sayName = function(){ alert(this.name); } //用1个语句创建和初始化对象 var person = { name = "nicholas", age = 29, sayName = function(){ alert(this.name); } }
- 优化DOM交互
- 最小化现场更新(部分更新)
- 使用innerHTML
使用时构建好一个字符串然后一次性调用innerHTML要比调用innerHTML多次快得多 - 使用事件代理
可以将事件处理程序附加到更高层的地方(祖先节点)负责多个目标的事件处理。 - 减少调用HTMLCollection次数
《JavaScript高级编程》事件及最佳实践简记
猜你喜欢
转载自blog.csdn.net/weixin_43236610/article/details/82782437
今日推荐
周排行