JavaScript 编程实践
来源:互联网 发布:知其所以然 编辑:程序博客网 时间:2024/05/29 12:53
零、将javascript从HTML中抽离,
<script> function addListener(target, type, handler) { if (target.addEventListener) { target.addEventListener(type, handler, false); } 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);</script>
一、数组去重
思路:检测新数组newArr里有没有包含Arr里的i项,如果没有则向newArr里添加Aii[i]项,如果有则跳过;function unArray (Arr) {
var newArr = [];
for (var i = 0; i < Arr.length; i++) {
if (newArr.indexOf(Arr[i]) == -1){
//检测newArr数组里是否包含Arr数组的内容,==-1检索的字符串没有出现则为-1
newArr.push(Arr[i])//把Arr数组的第i项插入新数组
}
};
return newArr;
}
//console.log(unArray(Arr));
二、字面量对象的使用
var json = { username:"feng", age:22 };
修改属性:json.age = 22;
添加属性:json.address = "北京";
删除属性:delete json.age;
删除对象:json = null;
三、使用 console 来记录代码执行时间
console.time('aa')var str = 's'for(var i=0;i<1000;i++){ for(var j=0;j<1000;j++){ str +='b' }}console.timeEnd('aa')
四、合理利用二进制
如:对2取模,则偶数最低位是0,奇数最低位是1,与1进行位与操作的结果是0,奇数的最低位是1,与1进行位与操作的结果是1。
代码如下:
.odd{color:red}.even{color:yellow}<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li></ul>var i = 0;var lis = document.getElementsByTagName("li");var len = lis.length;for(;i<len;i++){if(i&1){ lis[i].className = "even";//奇数} else{ lis[i].className = "odd";//偶数}};
五、优化层叠的条件判断
运行以上代码,如果页面上有10个按钮的话,点击每一个按钮都会弹出 “This is element #10”! 。这和我们原先预期的并不一样。这是因为当点击事件被触发的时候,for循环早已执行完毕,i的值也已经从0变成了。
还有
由于变量i从来就没背locked住。相反,当循环执行以后,我们在点击的时候i获得数值,所以说无论点击哪个连接,最终显示的都是I am link #10(如果有10个a元素的话)
闭包直接可以引用传入的这些参数,利用这些被锁住的传入参数,自执行函数表达式可以有效地保存状态。下面是正确的使用:
由于在自执行函数表达式闭包内部i的值作为locked的索引存在,在循环执行结束以后,尽管最后i的值变成了a元素总数(例如10)但闭包内部的lockedInIndex值是没有改变,因为他已经执行完毕了所以当点击连接的时候,结果是正确的。
其实,前面两个例子里的lockedInIndex变量,也可以换成i,因为和外面的i不在一个作用于,所以不会出现问题,这也是匿名函数+闭包的威力。
我们都知道,数组是特殊的对象,所以数组的 typeof 结果也是 object,而因为 null 的结果也是 object,所以如需用 typeof 运算符来判断数组,需要这么写:
十、cookie使用
十二、方法的链式调用:方法内返回对象
十三、.短路求值
如果你看到这堆条件判断代码,你会如何优化它?
if(color) { if(color ==='black') { printBlackBackground(); }elseif(color ==='red') { printRedBackground(); }elseif(color ==='blue') { printBlueBackground(); }elseif(color ==='green') { printGreenBackground(); }else{ printYellowBackground(); }}
尽可能的避免使用switch,那么最高效的做法就是通过一个object了。
var colorObj = { 'black': printBlackBackground, 'red': printRedBackground, 'blue': printBlueBackground, 'green': printGreenBackground, 'yellow': printYellowBackground};if(color && colorObj.hasOwnProperty(color)) { colorObj[color]();}
六、使用同一个方法处理数组和单一元素
与其拆分成两个方法来处理,不如写一个方法能同时处理两种情况:只需要先将它们并成一个数组
下面用一个方法,实现对传入的所有参数转换成大写
function printUpperCase(words){ var elements = [].concat(words);//字符串转换成数组,数组使用此方法则不发生改变 for(vari =0; i < elements.length; i++) { console.log(elements[i].toUpperCase()); }}printUpperCase("cactus");// => CACTUSprintUpperCase(["cactus","bear","potato"]);// => CACTUS,BEAR,POTOCO
七、in and hasOwnProperty
任何继承自Object的对象都有in,hasOwnProperty两个方法,你知道它们的区别吗?
var myObject = { name:'feng'};myObject.hasOwnProperty('name');// true'name' in myObject;// truemyObject.hasOwnProperty('valueOf');// false, valueOf is inherited from the prototype chain'valueOf' in myObject;// true
只有属性是直接在对象上,hasOwnProperty 才会返回true,而 in 则是不三七二十一,把对象及其原型链都查找了一遍。
var myFunc =function(){ this.name = 'feng';};myFunc.prototype.age ='24';var user =new myFunc();user.hasOwnProperty('name');// trueuser.hasOwnProperty('age');// false, because age is from the prototype chain
八、用闭包保存状态
下面是一段常见的代码
var elements = document.getElementsByTagName('input');var n = elements.length;for (var i = 0; i < n; i++) { elements[i].onclick = function() { console.log("This is element #" + i);};}
运行以上代码,如果页面上有10个按钮的话,点击每一个按钮都会弹出 “This is element #10”! 。这和我们原先预期的并不一样。这是因为当点击事件被触发的时候,for循环早已执行完毕,i的值也已经从0变成了。
var elems = document.getElementsByTagName('a');
for (var i = 0; i < elems.length; i++) {
elems[i].addEventListener('click', function (e) {
e.preventDefault();
alert('I am link #' + i);
}, 'false');
}
var elems = document.getElementsByTagName('a');for (var i = 0; i < elems.length; i++) { (function (lockedInIndex) { elems[i].addEventListener('click', function (e) { e.preventDefault(); alert('I am link #' + lockedInIndex); }, 'false'); })(i);}
九、判断数组的正确姿势
var a = [0, 1, 2]; // 是 object 同时排除 null、排除纯对象console.log(typeof a === 'object' && a !== null && Object.prototype.toString.call(a) !== '[object Object]'); // true
<!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8"> <title></title></head><body><script> var cookie = { setCookie:function(name,value,iDay){ var cookieStr = ''; if(iDay == undefined){ cookieStr += name+'='+value+';'; }else{ var oDate = new Date(); oDate.setDate(oDate.getDate()+iDay); cookieStr += name+'='+value+';express='+oDate; } document.cookie = cookieStr; }, getCookie:function(name){ var arr = document.cookie.split(';'); for(var i=0;i<arr.length;i++){ var arr2 = arr[i].split('='); if(arr2[0] == name){ return arr2[1]; } } return ''; }, removeCookie:function(name){ this.setCookie(name,'1',-1); } } function ControlAlert(){ var flag = cookie.getCookie('flag'); if(!flag){ alert("我是第一次加载的哟!"); cookie.setCookie('flag',true); //cookie.setCookie('flag',true,1);//如果有第三个参数则保存cookie的天数,如果不设置,浏览器关闭时cookie过期 } } (function(){ ControlAlert(); }());</script></body></html>
十一、更快的取整(Math.floor())
一个位操作符 ~ 将输入的32位的数字(input)转换为 -(input+1) . 两个位操作符将输入(input)转变为 -(-(input + 1)+1) 是一个使结果趋向于0的取整好工具. 对于数字, 负数就像使用 Math.ceil() 方法而正数就像使用 Math.floor() 方法. 转换失败时,返回 0 ,这在 Math.floor() 方法转换失败返回 NaN 时或许会派上用场。
<pre name="code" class="javascript">// 单个 ~<pre name="code" class="javascript">console.log(~1337) // -1338// 数字输入console.log(~~47.11) // -> 47console.log(~~-12.88) // -> -12console.log(~~1.9999) // -> 1console.log(~~3) // -> 3 // 转换失败console.log(~~[]) // -> 0console.log(~~NaN) // -> 0console.log(~~null) // -> 0 // 大于32位整数时转换失败console.log(~~(2147483647 + 1) === (2147483647 + 1)) // -> 0
十二、方法的链式调用:方法内返回对象
function Person(name) {this.name = name;this.sayName = function() {console.log("Hello my name is: ", this.name); return this;};this.changeName = function(name) { this.name = name; return this;};} var person = new Person("John");person.sayName().changeName("Timmy").sayName();
十三、.短路求值
短路求值是说, 只有当第一个运算数的值无法确定逻辑运算的结果时,才对第二个运算数进行求值:当AND(
十四、!! 的使用,只输出false和true
&&
)的第一个运算数的值为false时,其结果必定为false;当OR( ||
)的第一个运算数为true时,最后结果必定为true。逻辑或可以用来给参数设置默认值。function theSameOldFoo(name){ name = name || 'Bar' ; console.log("My best friend's name is " + name); }theSameOldFoo(); // My best friend'name is BartheSameOldFoo('Bhaskar'); // My best friend's name is Bhaskar
var dog = { bark: function(){ console.log('Woof Woof');<span style="white-space:pre"></span>}};// 调用 dog.bark();dog.bark(); // Woof Woof.// 但是当dog未定义时,dog.bark() 将会抛出"Cannot read property 'bark' of undefined." 错误// 防止这种情况,我们可以使用 &&.dog&&dog.bark(); // This will only call dog.bark(), if dog is defined.
十四、!! 的使用,只输出false和true
!!"" // false!!0 // false!!null // false!!undefined // false!!NaN // false !!"hello" // true!!1 // true!!{} // true!![] // true
十五、
0 0
- Javascript编程实践
- Javascript 编程最佳实践
- JavaScript 编程实践
- JavaScript面向对象编程实践
- JavaScript面相对象编程实践
- JavaScript提高效率之编程实践
- [源码]JavaScript面向对象编程实践
- JavaScript中的函数式编程实践
- JavaScript中数组高级编程实践
- JavaScript中数组高级编程实践-2
- JavaScript 中的函数式编程实践
- JavaScript 中的函数式编程实践
- 深入解读JavaScript面向对象编程实践
- JavaScript Dom编程艺术-C5 最佳实践
- JavaScript 中的函数式编程实践
- 【JavaScript DOM编程艺术】- 最佳实践
- 《JAVASCRIPT语言精髓与编程实践》预读样章公开~
- JavaScript语言精髓与编程实践 - 勘误
- JSP页面跳转的几种实现方法
- 初识ucosii多任务
- android工程中资源模块划分
- iOS 设计模式 - 备忘录模式
- robotium注入和查找事件源码浅析
- JavaScript 编程实践
- va.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor
- 初到北上广打拼的外地人,生活状态是怎样的?
- XNA4.0 RPG游戏开发教程(一)
- CodeForces 612 B. HDD is Outdated Technology(水~)
- Java的参数是按值传递的还是按引用?
- JSON文件与XML文件的数据解析
- 使用计算机时出现的问题---多个本地连接
- 2015.09-2016.02 半年总结 项目多也别傻做