JavaScript 编程实战技巧:从类型转换到 DOM 性能优化

作者:巡夜人

时间:2026-10-29

浏览:191

本文总结了 9 个实用的 JavaScript 编程技巧,涵盖类型转换、运算符使用、正则表达式、数组处理、内存管理、对象创建、作用域模拟以及 DOM 操作性能优化。重点解析了 NodeList 动态更新导致的无限循环问题及解决方案,并提供了避免频繁 DOM 重绘的性能建议,帮助开发者写出更高效、规范的代码。

文章目录

JavaScript 基础技巧:判断、运算符与正则

1. 巧妙利用条件判断:

在 JavaScript 中,NaN、undefined、Null、0 和空字符串("")在转换为布尔值时均为 false。因此,可以利用这一特性简化代码。

代码如下:

if(!obj) {}

上述代码表示当对象为假值时执行的操作。由于 obj 若为上述任一假值,其布尔值为 false,取反后即为 true,从而无需编写冗长的 if(obj==null || obj == NaN ...) 判断。

2. 巧妙利用运算符:

这里介绍一个获取时间戳的经典技巧。

代码如下:

var dataspan = new Date()*1;

JavaScript 是弱类型语言,Date() 返回表示时间的字符串。通过算术运算(乘以 1),字符串会被隐式转换为数字,即得到时间戳。

3. 巧妙利用正则表达式:

代码如下:

/.a/ig.exec('xsas')
这相当于创建了一个 RegExp 对象并调用 exec 方法。当然,也可以调用其他方法,如 test()、match() 等。

数组处理与内存管理

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

代码如下:

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

调用 Max.apply,将上下文对象设置为 Math,并传入 values 数组,即可确定最大值。

5. 内存优化:

代码如下:

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

对象创建与作用域模拟

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

代码如下:

function c(){
this.name ='moersing';
this.age=18;
this.books=['javascript develop','C# develop'];
  }
c.prototype={
displayBookName:function (){
foreach(var t in this.books)
        {
document.write(this.books[t]);
        }
    }
}

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

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

在 JavaScript 中,没有块级作用域和私有变量的概念,但可以利用某些特性模拟这些效果。

7.1 块级作用域:

代码如下:

(function(){
//块级作用域
}
)();

在匿名函数外加上括号,可称为“函数标准化”,即可以像标准函数那样调用,例如:

代码如下:

var name =function(){};
(name)();//一般不会这么写;

这样做的好处是,在 () 外部无法访问到函数中的变量,从而形成块级作用域。这种方式通常用于编写插件,避免在全局(global)中添加额外变量。此外,函数执行完毕后,其内部定义的变量会被销毁,因此也不存在闭包特性带来的问题。

7.2 私有变量:

代码如下:

function private()
 { 
var name = 'moersing';
this.getName = function(){
return this.name;
   }
}

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

DOM 操作与性能优化

8. DOM 之 NodeList:

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

代码如下:

var alldiv = document.getElementsByTagName('div');
for(var i=0;i<alldiv.length;i++)
    {
var div = document.createElement('div');
div.innerHTML= i.toString();
document.body.appendChild(div);
    }

这段代码会造成无限循环。在循环内部创建了一个 div,然后通过 appendChild 方法将其添加到 body 中,导致 alldiv 立即更新,因此 i<alldiv.length 永远无法成立。要解决这个问题,可以使用以下方式:

代码如下:

var alldiv = document.getElementsByTagName('div');
var len,i;
for(i=0,len=alldiv.length;i<len;i++)
    {
var div = document.createElement('div');
div.innerHTML= i.toString();
document.body.appendChild(div);
    }

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

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

代码如下:

var allDiv= document.querySelectorAll('div');
for(var i=0;i<alldiv.length;i++)
    {
var div = document.createElement('div');
div.innerHTML= i.toString();
document.body.appendChild(div);
    }

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

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

9. DOM 性能:

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

代码如下:

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

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

最好这样做:

代码如下:

var ih=null;
for(var i=0;i<10;i++)
 { 
 ih+="<li>"+i+"</li>";
 }
 document.querySelector('ul').innerHTML=ih;

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

以上所述就是本文的全部内容了,希望大家能够喜欢。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章