1.巧用判断:

在js中,NaN,undefined,Null,0,"" 在转换为bool的时候,是false,所以,可以这样写。

  1. if(!obj) {}

表示一个对象如果为false的时候所做的事情,因为如果obj为以上任何一个,那么就是false,!false即是true,这样,就不需要 if(obj==null || obj == NaN ....)。

2.巧用运算符:

有一个很经典的技巧,得到时间戳。

  1. var dataspan = new Date()*1;

我们知道,js是弱类型语言,Date()会返回一个表示时间的字符串,用这个字符串进行算术运算,将得到转换,也就是结果的时间戳。

3.巧用正则表达式:

  1. /.a/ig.exec('xsas')

//相当于创建一个reg对象,调用了exec方法,当然也能调用其他的方法,如:test(),match()等。

4.取数组最大值和最小值:

  1. var values = [1,2,3,40,23];
  2. var max = Math.Max.apply(Math,values);

调用Max.apply,设置对象的为Math,然后传递一个Values,就能确定最大值。

5.内存优化:

  1. function p(){this.p='moersing'}; var p1 = new p();
  2.  
  3. p1.xx
  4.  
  5. p1.xx
  6.  
  7. .......
  1. p1=null; //执行完操作之后,最后手动解除对p1的引用。

6.最受欢迎的创建对象方式(原型模式):

  1. function c(){
  2.  
  3. this.name ='moersing';
  4.  
  5. this.age=18;
  6.  
  7. this.books=['javascript develop','C# develop'];
  8.  
  9. }
  10.  
  11. c.prototype={
  12. displayBookName:function (){
  13. foreach(var t in this.books)
  14. {
  15. document.write(this.books[t]);
  16. }
  17. }
  18. }

原型构造模式的最大缺点在于引用类型的共享,所以,将引用类型定义在构造函数中,而将通用方法定义在原型中,使用this引用。

7.块级作用域和私有变量

在javascript中,没有块级作用域和私有变量这一说,但是,利用一些特性,则能模仿这些效果。

7.1块级作用域:

  1. (function(){
  2.  
  3. //块级作用域
  1. }
  2. )();

匿名函数外面加上一个括号,我管它叫"函数标准化",也就是说,可以像标准函数那样调用,如:

  1. var name =function(){};
  2. (name)();//一般不会这么写;</P>

这么做的好处就是,在()外部无法访问到函数中变量,也就成了块级作用域,这种方式一般用在编写插件的时候,不会再全局 (global)中添加额外的变量,而且,在函数执行完毕之后,其内部定义的变量就被销毁了,所以,也不会有闭包特性存在的问题。

7.2私有变量:

  1. function private()
  2. {
  3. var name = 'moersing';
  4. this.getName = function(){
  5. return this.name;
  1. }
  2. }

私有变量实际上就是利用函数的作用域作为限制(外部无法访问),然后定义一个方法,这个方法返回相应的变量,仅此而已。

8.DOM之NodeList:

nodeList是一个动态的元素,这意味着,在文档中添加任何元素,nodeList都会实时更新,如:

  1. var alldiv = document.getElementsByTagName('div');
  2.  
  3. for(var i=0;i<alldiv.length;i++)
  4. {
  5. var div = document.createElement('div');
  6.  
  7. div.innerHTML= i.toString();
  8.  
  9. document.body.appendChild(div);
  10. }

这段代码会造成无限循环,在循环里面创建了一个div,然后appendChild方法将其添加到body中,那么,所有alldiv会立即就更新,所以,i<alldiv.length永远无法成立,要解决这个问题,可以使用下面方式:

  1. var alldiv = document.getElementsByTagName('div');
  2.  
  3. var len,i;
  4.  
  5. for(i=0,len=alldiv.length;i<len;i++)
  6. {
  7. var div = document.createElement('div');
  8.  
  9. div.innerHTML= i.toString();
  10.  
  11. document.body.appendChild(div);
  12.  
  13. }

这里建议:最好不要频繁的对NodeList操作,因为每次操作都会执行一次DOM树的查询。

除了以上介绍的方法外,HTML5 新加入的API(selector API Level1)也能解决这个问题,它类似C#的linq及时查询,至于什么是linq及时查询,以后我会更新blog,敬请关注:

  1. var allDiv= document.querySelectorAll('div');
  2.  
  3. for(var i=0;i<alldiv.length;i++)
  4. {
  5. var div = document.createElement('div');
  6.  
  7. div.innerHTML= i.toString();
  8.  
  9. document.body.appendChild(div);
  10.  
  11. }

querySelectorAll需要一个参数,一个CSS选择器,类似jquery中的$(),它返回的NodeList是一个及时的,非动态的DOM集合。

另外还有一个querySelector,返回匹配的第一个元素,有关HTML5 API 详 见

http://www.w3.org/standards/techs/dom#w3c_all

或者

https://developer.mozilla.org/zh-CN/docs/Web/API

另外,本人也在酝酿一篇blog,专门讲HTML5 API的,敬请关注。

9.DOM性能:

不要做这种傻事(我做过。。。)

  1. for(var i=0;i<10;i++)
  2. {
  3. document.querySelector('ul').innerHTML="<li>"+i+"</li>";
  4. }

给对象的innerHTML赋值,会调用内置的C++解析器解析这个字符串,虽然速度很快,但是最好不要这样操作,会有一定的性能流失。

最好这样做:

  1. var ih=null;
  2.  
  3. for(var i=0;i<10;i++)
  4. {
  5. ih+="<li>"+i+"</li>";
  6. }
  7.  
  8. document.querySelector('ul').innerHTML=ih;

10.DOM性能 ———— 委托处理技术: 

  好几天没写blog了,今天写下个人认为很不错的技巧。

在讲这个技术之前,我认为应该补充下基础知识,以免初学者感到很迷糊:

1.事件冒泡和事件捕获

假设有这样一张网页:

  1. <body>
  2.  
  3. <div>
  4.  
  5. <span>
  6.  
  7. <button></button>
  8.  
  9. </span>
  10.  
  11. </div>
  12.  
  13. <body>

当我们点击页面的button按钮的时候,那么,根据冒泡规则,首先触发button的click(不提mousedown和mouseup),然后事件会依次向上冒泡,也就是:

  1. buttonspandivbodyhtmldocument

也就是说,你如果在div和button定义了click事件,如:

  1. document.querySelector('button').addEventListenner('click',function(){
  2.  
  3. alert('button');
  4.  
  5. },!1);
  6.  
  7. document.querySelector('div').addEventListenner('click',function(){
  8.  
  9. alert('div');
  10.  
  11. },!1);

那么,当你单击了button之后,会先弹出'button',然后接着是'div',span不会受到处理,因为没有事件监听它的click。

在IE6以下的版本冒泡会跳过html,从body直接到document,但这不是我们关心的,没人有会去处理IE5.5了。

好了,回到正题, "事件捕获":

在IE8及其之前的版本中,不支持事件捕获机制。

那么,什么是事件捕获呢?它的机制很简单,"目标元素最后接收到事件",还是根据上面的网页来做个例子,当我们单击button的时候,根据事件捕获机制,得出的结果就是:

  1. documenthtmlbodydivspanbutton

到这里,有很多人可能会郁闷了,这两个机制有什么用??我单击了button就是button,管其他元素干什么?这就是这一节要讨论的主题 "委托处理技术":

抛开IE8及其以下的版本不说,标准的事件处理过程应该是这样的:

  1. documenthtmlbodydivspanbutton //捕获阶段
  2.  
  3. buttonspandivbodyhtmldocument //冒泡阶段

尽管浏览器会透明化其他过程,但是,利用这两种机制,可以做到 "万法归一"。既然能够冒泡到父元素上面,那如果我们直接在document上绑定一个click事件,然后单击button,那么理论

上这个事件会被得到处理,当然,你单击span,div,都会的得到相同的结果,如:

  1. document.addEventListenner('click',function(){
  2.  
  3. alert('document'); //不管单击单个元素,都会弹出,因为所有click事件都会冒泡document
  4.  
  5. },!1);

我们知道,每个function都是一个对象,如果在处理table之类的元素,你要为它的每一个td都加上click事件........,你得确认你的客户不会拍桌子,扯远了。

在冒泡阶段和捕获阶段,我们都能依次得到所有对象。HTML5 新增的addEventListenner方法接受三个参数,分别是:'事件类型'和处理函数以及是否在捕获阶段获取对象

类似这个样子:

  1. element.addEventListenner('event type',handle,bool);

在冒泡阶段,你能获取任何你想要的元素:

  1. document.addEventListenner('click',function(e){
  2.  
  3. if(e.targer.nodeName==='button')//是否冒泡到了button
  4. {
  5.  
  6. alert('my button');
  7.  
  8. }
  9.  
  10. },!1);
  1.  

首先解释下,addEventListenner会给handle都会传递一个event对象,利用这个对象,我们能获取很多的信息,下面列出常用的:

  1. 1. currentTarget element 绑定的元素
  2. 2. eventPhase int 目前整处于什么阶段:1为捕获阶段,2为目标阶段,3为冒泡阶段
  3. 3. preventDefault() Function 取消默认行为,如果form提交,a标签跳转。
  4. 4. stopPropagation() Function 阻止事件冒泡
  5. 5. target element 目标元素,这个元素是你单击的元素
  6. 6. type string 监听的事件类型,这里是click
  1.  

这些属性和方法在IE9+都能用,IE8及其以下的有些不同:

IE8不支持事件捕获,使用attachEvent来监听事件,只有两个参数。如:

  1. element.attachEvent('onclick',function(){});//IE8的evnet type 需要加上 on。

另外IE8中的event也有所不同:

  1. 1. returnValue string stopPropagation()方法作用相同,不过它是属性。
  2. 2. srcElement COM target一样,不过它是IE出的COM对象。
  3. 3. type string 事件类型。

这里我们只讨论标准下的委托技术,非标准的处理也是类似的:

设想以下情景:

一个ul,里面N多li,li还有可能包含ul,这是一个大家非常熟悉的树状结构:

我们要做的就是单击每个li的时候,显示其下的ul元素(我相信很多人都做过),类似下面这样:

  1. <ul class="parent-ul">
  2.  
  3. <li>
  4.  
  5. <span class="one">1</span>
  6.  
  7. <ul>
  8.  
  9. <li>1.1</li>
  10.  
  11. <li>1.2</li>
  12.  
  13. </ul>
  14.  
  15. </li>
  16.  
  17. <li>
  18.  
  19. <span class="two">2</span>
  20.  
  21. <ul>
  22.  
  23. <li>2.1</li>
  24.  
  25. <li>2.2</li>
  26.  
  27. </ul>
  28.  
  29. </li>
  30.  
  31. </ul>

按照一般处理的方式,你可能想变量parent-ul中的每个span,然后注册事件,这样做的后果前面我已经提及了,现在,我们用冒泡机制来处理。

  1. document.querySelector('.parent-ul').addEventListenner('click',function(e){
  2.  
  3. var curTarget = e.target;
  4.  
  5. if(curTarget.className==='one')
  6.  
  7. {
  8.  
  9. //执行操作,curTarget就是你单击的span元素,不要指望小墨给你做完.
  10.  
  11. }
  12.  
  13. },!1);

在这个demo中,我们看到,我们只是在 'parent-ul' 中注册了click事件,然后根据event对象来执行相应的操作,这样,所有的子元素都不需要注册事件,你只管在parent-ul中写判断就OK了,所以,在性能上有一定的提升,操作也简单,假设你的数据库很多数据需要显示到parent-ul中,那你只需要加上一个class或者id就能处理这个操作了,另外一个很容易让人忽视的就是,DOM元素是能够被移除的,当我们用removeChild或者replaceChild(特别是innerHTML)操作DOM的时候,元素是被移除/替换了,但是事件处理程序并不一定就被删除了,这个问题特别在IE8的GC计数回收显得特别明显。如果我们像上面那样操作,就能避免这种情况,因为li根本没有事件注册在上面。

目前为止,事件冒泡总算差不多了,小墨只是根据自己的知识写了点皮毛,不值一提。

上面还提到了事件捕获,呵呵,无非就是:

  1. document.addEventListenner('click',function(){
  2.  
  3. if(e.target.nodeName==='button')
  4.  
  5. {
  6.  
  7. //捕获阶段执行的处理
  8.  
  9. }
  10.  
  11. },!!1); //!!1是true,也就是启用事件捕获。

一般来说,没有必要在捕获阶段处理事件,除非特殊情况。

顺便说一下:并不是所有事件都支持冒泡,还有,对于mouseMove,mouseEnter来说,要处理冒泡并不简单,所以,在处理这两个事件的时候,要格外小心。

另外的一些性能优化话题,等有时间再更新。

本人纯属菜鸟,如果有什么不对的地方,还请指正,原创文章,转载请注明地址。QQ:1261870167

javascript 编程技巧的更多相关文章

  1. 15个提高编程技巧的JavaScript工具

    原文地址:http://www.imooc.com/wenda/detail/243523 JavaScript脚本库是一个预先用JavaScript语言写好的库,它方便了我们开发基于JavaScri ...

  2. javascript实用技巧、javascript高级技巧

    字号+作者:H5之家 来源:H5之家 2016-10-31 11:00 我要评论( ) 三零网提供网络编程. JavaScript 的技术文章javascript实用技巧.javascript高级技巧 ...

  3. JavaScript简写技巧总结

    在日常工作中,JavaScript一些常用的简写技巧,将直接影响到我们的开发效率,现将常用技巧整理如下: 1. 空(null, undefined)验证     当我们创建了一个新的变量,我们通常会去 ...

  4. javascript编程思想

    javascript编程开发修炼之道   提要文摘附注: 本文的核心内容是围绕javascript前端开发的编程技术要素,来深入地探讨编写高质量的javascript代码的方法.技巧.规范和最佳实践, ...

  5. 偏执却管用的10条Java编程技巧

    本文由 ImportNew - LynnShaw 翻译自 javacodegeeks.欢迎加入翻译小组.转载请见文末要求. 经过一段时间的编码(咦,我已经经历了将近20年的编程生涯,快乐的日子总是过得 ...

  6. [libgdx游戏开发教程]使用Libgdx进行游戏开发(11)-高级编程技巧 Box2d和Shader

    高级编程技巧只是相对的,其实主要是讲物理模拟和着色器程序的使用. 本章主要讲解利用Box2D并用它来实现萝卜雨,然后是使用单色着色器shader让画面呈现单色状态:http://files.cnblo ...

  7. 实用Javascript调试技巧

    摘要: 高效调试JS代码. 原文:实用Javascript调试技巧分享 作者:MudOnTire Fundebug经授权转载,版权归原作者所有. 见过太多同学调试Javascript只会用简单的con ...

  8. [技术翻译]您应该知道的13个有用的JavaScript数组技巧

    本次预计翻译三篇文章如下: 01.[译]9个可以让你在2020年成为前端专家的项目 02.[译]预加载响应式图像,从Chrome 73开始实现 03.[译]您应该知道的13个有用的JavaScript ...

  9. JavaScript的技巧45招

    JavaScript奇技淫巧45招 来自仲老师的分享: 原文地址[http://chensd.com/2015-01/45-useful-javascript-tips-tricks-and-best ...

随机推荐

  1. android 工具类之SharePreference

    /** * SharedPreferences的一个工具类,调用setParam就能保存String, Integer, Boolean, Float, Long类型的参数 * 同样调用getPara ...

  2. php 将字符串中的连续多个空格转换为一个空格

    转载自:http://www.phpernote.com/php-function/633.html /** * 多个连续空格只保留一个 * * @param string $string 待转换的字 ...

  3. 《Secrets of the JavaScript Ninja》:JavaScript 之运行时代码

    最近,在阅读 jQuery 之父 John Resig 力作:Secrets of the JavaScript Ninja(JavaScript忍者秘籍).关于第九章提及的 JavaScript 之 ...

  4. 常见的Unix指令

    ls -1 列出当前目录下的所有内容(文件/文件夹) pwd 显示当前操作的目录 cd   改变当前操作的目录 who 显示当前用户 clear 清屏 mkdir 新建一个目录 touch 新建一个文 ...

  5. ARM Compiler toolchain Compiler -- Supported ARM architectures

    --cpu=name This option enables code generation for the selected ARM processor or architecture. Synta ...

  6. Java学习笔记之接口

    一.接口的概念与定义 首先考虑一个简单的接口的定义: public interface Output { int MAX_LINE = 40; void out(); void getData(Str ...

  7. 将博CMS安全分析报告-橘皮书

    一.使用IBM的AppScan和Acunetix应用程序漏洞扫描将博CMS5.5,得出一些漏洞.         此番扫描大小共23种类型问题,其中高危漏洞有三个,中危漏洞9个,低级漏洞11个.注意这 ...

  8. Codeforces Round #215 (Div. 2) B. Sereja and Suffixes map

    B. Sereja and Suffixes Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset ...

  9. cocos2dx A*算法

    头文件和源文件拷贝到项目中就能用了! have fun 使用cocos2dx 3.2 原理都一样 淡蓝色的点是地图 深蓝色的点是障碍物 绿色的点是路径 暗绿色的点是搜寻过的点 红色的点是按路径行走的点 ...

  10. [Angular 2] Generate and Render Angular 2 Template Elements in a Component

    Angular 2 Components have templates, but you can also create templates inside of your templates usin ...