首页 web前端 js教程 45个JavaScript编程注意事项、技巧大全_javascript技巧

45个JavaScript编程注意事项、技巧大全_javascript技巧

May 16, 2016 pm 04:14 PM
javascript 技巧 注意事项 编程

JavaScript是一个绝冠全球的编程语言,可用于Web开发、移动应用开发(PhoneGap、Appcelerator)、服务器端开发(Node.js和Wakanda)等等。JavaScript还是很多新手踏入编程世界的第一个语言。既可以用来显示浏览器中的简单提示框,也可以通过nodebot或nodruino来控制机器人。能够编写结构清晰、性能高效的JavaScript代码的开发人员,现如今已成了招聘市场最受追捧的人。

在这篇文章里,我将分享一些JavaScript的技巧、秘诀和最佳实践,除了少数几个外,不管是浏览器的JavaScript引擎,还是服务器端JavaScript解释器,均适用。

本文中的示例代码,通过了在Google Chrome 30最新版(V8 3.20.17.15)上的测试。

1、首次为变量赋值时务必使用var关键字

变量没有声明而直接赋值得话,默认会作为一个新的全局变量,要尽量避免使用全局变量。

2、使用===取代==

==和!=操作符会在需要的情况下自动转换数据类型。但===和!==不会,它们会同时比较值和数据类型,这也使得它们要比==和!=快。

复制代码 代码如下:

[10] === 10    // is false
[10]  == 10    // is true
'10' == 10     // is true
'10' === 10    // is false
[]   == 0     // is true
[] ===  0     // is false
'' == false   // is true but true == "a" is false
'' === false  // is false

3、underfined、null、0、false、NaN、空字符串的逻辑结果均为false
4、行尾使用分号

实践中最好还是使用分号,忘了写也没事,大部分情况下JavaScript解释器都会自动添加。对于为何要使用分号,可参考文章JavaScript中关于分号的真相。

5、使用对象构造器

复制代码 代码如下:

  function Person(firstName, lastName){
    this.firstName =  firstName;
    this.lastName = lastName;
}
var Saad = new Person("Saad", "Mousliki");

6、小心使用typeof、instanceof和contructor
typeof:JavaScript一元操作符,用于以字符串的形式返回变量的原始类型,注意,typeof null也会返回object,大多数的对象类型(数组Array、时间Date等)也会返回object
contructor:内部原型属性,可以通过代码重写
instanceof:JavaScript操作符,会在原型链中的构造器中搜索,找到则返回true,否则返回false
复制代码 代码如下:

var arr = ["a", "b", "c"];
typeof arr;   // 返回 "object"
arr instanceof Array // true
arr.constructor();  //[]

7、使用自调用函数
函数在创建之后直接自动执行,通常称之为自调用匿名函数(Self-Invoked Anonymous Function)或直接调用函数表达式(Immediately Invoked Function Expression )。格式如下:
复制代码 代码如下:

(function(){
    // 置于此处的代码将自动执行
})(); 
(function(a,b){
    var result = a+b;
    return result;
})(10,20)

8、从数组中随机获取成员

复制代码 代码如下:

var items = [12, 548 , 'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' , 2145 , 119];
var  randomItem = items[Math.floor(Math.random() * items.length)];

9、获取指定范围内的随机数
这个功能在生成测试用的假数据时特别有数,比如介与指定范围内的工资数。
复制代码 代码如下:

var x = Math.floor(Math.random() * (max - min + 1)) + min;

10、生成从0到指定值的数字数组
复制代码 代码如下:

var numbersArray = [] , max = 100;
for( var i=1; numbersArray.push(i++)

11、生成随机的字母数字字符串
复制代码 代码如下:

  function generateRandomAlphaNum(len) {
    var rdmString = "";
    for( ; rdmString.length     return  rdmString.substr(0, len);

12、打乱数字数组的顺序

复制代码 代码如下:

var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];
numbers = numbers.sort(function(){ return Math.random() - 0.5});
/* numbers 数组将类似于 [120, 5, 228, -215, 400, 458, -85411, 122205]  */

这里使用了JavaScript内置的数组排序函数,更好的办法是用专门的代码来实现(如Fisher-Yates算法),可以参见StackOverFlow上的这个讨论。

13、字符串去空格

Java、C#和PHP等语言都实现了专门的字符串去空格函数,但JavaScript中是没有的,可以通过下面的代码来为String对象函数一个trim函数:

复制代码 代码如下:

String.prototype.trim = function(){return this.replace(/^\s+|\s+$/g, "");};

新的JavaScript引擎已经有了trim()的原生实现。

14、数组之间追加

复制代码 代码如下:

var array1 = [12 , "foo" , {name "Joe"} , -2458];
var array2 = ["Doe" , 555 , 100];
Array.prototype.push.apply(array1, array2);
/* array1 值为  [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */

15、对象转换为数组
复制代码 代码如下:

  var argArray = Array.prototype.slice.call(arguments);

16、验证是否是数字
复制代码 代码如下:

  function isNumber(n){
    return !isNaN(parseFloat(n)) && isFinite(n);
}

17、验证是否是数组
复制代码 代码如下:

  function isArray(obj){
    return Object.prototype.toString.call(obj) === '[object Array]' ;
}

但如果toString()方法被重写过得话,就行不通了。也可以使用下面的方法:
复制代码 代码如下:

  Array.isArray(obj); // its a new Array method

如果在浏览器中没有使用frame,还可以用instanceof,但如果上下文太复杂,也有可能出错。
复制代码 代码如下:

  var myFrame = document.createElement('iframe');
document.body.appendChild(myFrame);
var myArray = window.frames[window.frames.length-1].Array;
var arr = new myArray(a,b,10); // [a,b,10] 
// myArray 的构造器已经丢失,instanceof 的结果将不正常
// 构造器是不能跨 frame 共享的
arr instanceof Array; // false

18、获取数组中的最大值和最小值
复制代码 代码如下:

var  numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];
var maxInNumbers = Math.max.apply(Math, numbers);
var minInNumbers = Math.min.apply(Math, numbers);

19、清空数组
复制代码 代码如下:

  var myArray = [12 , 222 , 1000 ]; 
myArray.length = 0; // myArray will be equal to [].

20、不要直接从数组中delete或remove元素
如果对数组元素直接使用delete,其实并没有删除,只是将元素置为了undefined。数组元素删除应使用splice。

切忌:

复制代码 代码如下:

var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ];
items.length; // return 11
delete items[3]; // return true
items.length; // return 11
/* items 结果为 [12, 548, "a", undefined × 1, 5478, "foo", 8852, undefined × 1, "Doe", 2154, 119] */

而应:

复制代码 代码如下:

  var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ];
items.length; // return 11
items.splice(3,1) ;
items.length; // return 10
/* items 结果为 [12, 548, "a", 5478, "foo", 8852, undefined × 1, "Doe", 2154, 119]

删除对象的属性时可以使用delete。

21、使用length属性截断数组

前面的例子中用length属性清空数组,同样还可用它来截断数组:

复制代码 代码如下:

  var myArray = [12 , 222 , 1000 , 124 , 98 , 10 ]; 
myArray.length = 4; // myArray will be equal to [12 , 222 , 1000 , 124].

与此同时,如果把length属性变大,数组的长度值变会增加,会使用undefined来作为新的元素填充。length是一个可写的属性。
复制代码 代码如下:

  myArray.length = 10; // the new array length is 10
myArray[myArray.length - 1] ; // undefined

22、在条件中使用逻辑与或

复制代码 代码如下:

var foo = 10; 
foo == 10 && doSomething(); // is the same thing as if (foo == 10) doSomething();
foo == 5 || doSomething(); // is the same thing as if (foo != 5) doSomething();

逻辑或还可用来设置默认值,比如函数参数的默认值。
复制代码 代码如下:

function doSomething(arg1){
    arg1 = arg1 || 10; // arg1 will have 10 as a default value if it's not already set
}

23、使得map()函数方法对数据循环
复制代码 代码如下:

  var squares = [1,2,3,4].map(function (val) { 
    return val * val; 
});
// squares will be equal to [1, 4, 9, 16]

24、保留指定小数位数
复制代码 代码如下:

  var num =2.443242342;
num = num.toFixed(4);  // num will be equal to 2.4432

注意,toFixec()返回的是字符串,不是数字。

25、浮点计算的问题

复制代码 代码如下:

  0.1 + 0.2 === 0.3 // is false
9007199254740992 + 1 // is equal to 9007199254740992
9007199254740992 + 2 // is equal to 9007199254740994

为什么呢?因为0.1+0.2等于0.30000000000000004。JavaScript的数字都遵循IEEE 754标准构建,在内部都是64位浮点小数表示,具体可以参见JavaScript中的数字是如何编码的.

可以通过使用toFixed()和toPrecision()来解决这个问题。

26、通过for-in循环检查对象的属性
下面这样的用法,可以防止迭代的时候进入到对象的原型属性中。

复制代码 代码如下:

  for (var name in object) { 
    if (object.hasOwnProperty(name)) {
        // do something with name
    } 
}

27、逗号操作符
复制代码 代码如下:

  var a = 0;
var b = ( a++, 99 );
console.log(a);  // a will be equal to 1
console.log(b);  // b is equal to 99

28、临时存储用于计算和查询的变量
在jQuery选择器中,可以临时存储整个DOM元素。
复制代码 代码如下:

  var navright = document.querySelector('#right');
var navleft = document.querySelector('#left');
var navup = document.querySelector('#up');
var navdown = document.querySelector('#down');

29、提前检查传入isFinite()的参数
复制代码 代码如下:

  isFinite(0/0) ; // false
isFinite("foo"); // false
isFinite("10"); // true
isFinite(10);   // true
isFinite(undefined);  // false
isFinite();   // false
isFinite(null);  // true,这点当特别注意

30、避免在数组中使用负数做索引
复制代码 代码如下:

  var numbersArray = [1,2,3,4,5];
var from = numbersArray.indexOf("foo") ;  // from is equal to -1
numbersArray.splice(from,2);    // will return [5]

注意传给splice的索引参数不要是负数,当是负数时,会从数组结尾处删除元素。

31、用JSON来序列化与反序列化

复制代码 代码如下:

  var person = {name :'Saad', age : 26, department : {ID : 15, name : "R&D"} };
var stringFromPerson = JSON.stringify(person);
/* stringFromPerson 结果为 "{"name":"Saad","age":26,"department":{"ID":15,"name":"R&D"}}"   */
var personFromString = JSON.parse(stringFromPerson);
/* personFromString 的值与 person 对象相同  */

32、不要使用eval()或者函数构造器
eval()和函数构造器(Function consturctor)的开销较大,每次调用,JavaScript引擎都要将源代码转换为可执行的代码。
复制代码 代码如下:

  var func1 = new Function(functionCode);
var func2 = eval(functionCode);

33、避免使用with()
使用with()可以把变量加入到全局作用域中,因此,如果有其它的同名变量,一来容易混淆,二来值也会被覆盖。

34、不要对数组使用for-in
避免:

复制代码 代码如下:

  var sum = 0; 
for (var i in arrayNumbers) { 
    sum += arrayNumbers[i]; 
}

而是:
复制代码 代码如下:

  var sum = 0; 
for (var i = 0, len = arrayNumbers.length; i     sum += arrayNumbers[i]; 
}

另外一个好处是,i和len两个变量是在for循环的第一个声明中,二者只会初始化一次,这要比下面这种写法快:
复制代码 代码如下:

  for (var i = 0; i

35、传给setInterval()和setTimeout()时使用函数而不是字符串
如果传给setTimeout()和setInterval()一个字符串,他们将会用类似于eval方式进行转换,这肯定会要慢些,因此不要使用:
复制代码 代码如下:

setInterval('doSomethingPeriodically()', 1000); 
setTimeout('doSomethingAfterFiveSeconds()', 5000);

而是用:
复制代码 代码如下:

setInterval(doSomethingPeriodically, 1000); 
setTimeout(doSomethingAfterFiveSeconds, 5000);

36、使用switch/case代替一大叠的if/else

当判断有超过两个分支的时候使用switch/case要更快一些,而且也更优雅,更利于代码的组织,当然,如果有超过10个分支,就不要使用switch/case了。

37、在switch/case中使用数字区间

其实,switch/case中的case条件,还可以这样写:

复制代码 代码如下:

  function getCategory(age) { 
    var category = ""; 
    switch (true) { 
        case isNaN(age): 
            category = "not an age"; 
            break; 
        case (age >= 50): 
            category = "Old"; 
            break; 
        case (age             category = "Baby"; 
            break; 
        default: 
            category = "Young"; 
            break; 
    }; 
    return category; 

getCategory(5);  // 将返回 "Baby"

38、使用对象作为对象的原型

下面这样,便可以给定对象作为参数,来创建以此为原型的新对象:

复制代码 代码如下:

  function clone(object) { 
    function OneShotConstructor(){};
    OneShotConstructor.prototype = object; 
    return new OneShotConstructor();
}
clone(Array).prototype ;  // []

39、HTML字段转换函数
复制代码 代码如下:

  function escapeHTML(text) { 
    var replacements= {"": ">","&": "&", "\"": """};                     
    return text.replace(/[&"]/g, function(character) { 
        return replacements[character]; 
    });
}

40、不要在循环内部使用try-catch-finally

try-catch-finally中catch部分在执行时会将异常赋给一个变量,这个变量会被构建成一个运行时作用域内的新的变量。

切忌:

复制代码 代码如下:

  var object = ['foo', 'bar'], i; 
for (i = 0, len = object.length; i     try { 
        // do something that throws an exception
    } 
    catch (e) {  
        // handle exception 
    }
}

而应该:
复制代码 代码如下:

  var object = ['foo', 'bar'], i; 
try {
    for (i = 0, len = object.length; i         // do something that throws an exception
    }
}
catch (e) {  
    // handle exception 
}

41、使用XMLHttpRequests时注意设置超时
XMLHttpRequests在执行时,当长时间没有响应(如出现网络问题等)时,应该中止掉连接,可以通过setTimeout()来完成这个工作:

复制代码 代码如下:

  var xhr = new XMLHttpRequest ();
xhr.onreadystatechange = function () { 
    if (this.readyState == 4) { 
        clearTimeout(timeout); 
        // do something with response data
    } 

var timeout = setTimeout( function () { 
    xhr.abort(); // call error callback 
}, 60*1000 /* timeout after a minute */ );
xhr.open('GET', url, true); 
xhr.send();

同时需要注意的是,不要同时发起多个XMLHttpRequests请求。

42、处理WebSocket的超时

通常情况下,WebSocket连接创建后,如果30秒内没有任何活动,服务器端会对连接进行超时处理,防火墙也可以对单位周期没有活动的连接进行超时处理。

为了防止这种情况的发生,可以每隔一定时间,往服务器发送一条空的消息。可以通过下面这两个函数来实现这个需求,一个用于使连接保持活动状态,另一个专门用于结束这个状态。

复制代码 代码如下:

  var timerID = 0;
function keepAlive() {
    var timeout = 15000; 
    if (webSocket.readyState == webSocket.OPEN) { 
        webSocket.send(''); 
    } 
    timerId = setTimeout(keepAlive, timeout); 

function cancelKeepAlive() { 
    if (timerId) { 
        cancelTimeout(timerId); 
    } 
}

keepAlive()函数可以放在WebSocket连接的onOpen()方法的最后面,cancelKeepAlive()放在onClose()方法的最末尾。

43、时间注意原始操作符比函数调用快,使用VanillaJS
比如,一般不要这样:

复制代码 代码如下:

  var min = Math.min(a,b);
A.push(v);

可以这样来代替:
复制代码 代码如下:

  var min = a A[A.length] = v;

44、开发时注意代码结构,上线前检查并压缩JavaScript代码
可以使用JSLint或JSMin等工具来检查并压缩代码。
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
2 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

使用正则表达式去除 PHP 数组中的重复值 使用正则表达式去除 PHP 数组中的重复值 Apr 26, 2024 pm 04:33 PM

使用正则表达式从PHP数组中去除重复值的方法:使用正则表达式/(.*)(.+)/i匹配并替换重复项。遍历数组元素,使用preg_match检查匹配情况。如果匹配,跳过值;否则,将其添加到无重复值的新数组中。

编程是干啥的,学了有什么用 编程是干啥的,学了有什么用 Apr 28, 2024 pm 01:34 PM

1、编程可以用于开发各种软件和应用程序,包括网站、手机应用、游戏和数据分析工具等。它的应用领域非常广泛,覆盖了几乎所有行业,包括科学研究、医疗保健、金融、教育、娱乐等。2、学习编程可以帮助我们提高问题解决能力和逻辑思维能力。编程过程中,我们需要分析和理解问题,找出解决方案,并将其转化为代码。这种思维方式能够培养我们的分析和抽象能力,提高我们解决实际问题的能力。

使用 C++ lambda 表达式有哪些注意事项? 使用 C++ lambda 表达式有哪些注意事项? Apr 17, 2024 pm 12:15 PM

使用C++lambda表达式时需注意:小心捕获变量,避免意外修改。可通过引用或值捕获变量,引用捕获用于修改外部变量。lambda表达式生命周期与捕获它的函数不同,可能导致内存泄漏。考虑使用函数指针或函数对象以优化性能。

编码的关键:为初学者释放 Python 的力量 编码的关键:为初学者释放 Python 的力量 Oct 11, 2024 pm 12:17 PM

Python通过其易学性和强大功能,是初学者的理想编程入门语言。其基础包括:变量:用于存储数据(数字、字符串、列表等)。数据类型:定义变量中数据的类型(整数、浮点数等)。运算符:用于数学运算和比较。控制流:控制代码执行流(条件语句、循环)。

使用 Python 解决问题:作为初学者,解锁强大的解决方案 使用 Python 解决问题:作为初学者,解锁强大的解决方案 Oct 11, 2024 pm 08:58 PM

Python 使初学者能够解决问题。其用户友好的语法、广泛的库以及变量、条件语句和循环等功能可实现高效的代码开发。从管理数据到控制程序流程和执行重复任务,Python 提供了

不打架改打球!《永劫无间》全新模式热血斗振球玩法介绍 不打架改打球!《永劫无间》全新模式热血斗振球玩法介绍 Apr 11, 2024 pm 01:52 PM

排位打累了?那就来打球吧!默契配合的队友,让对手尝一尝出其不意的滋味!瞬息万变的战场,试看如何巧用技能一招破局!《永劫无间》在4月11日的更新中上线了一个全新的团队对抗模式,下面就给大家带来永劫无间热血斗振球活动介绍。永劫无间热血斗振球玩法一览简介:通过各种手段反弹斗球,击败敌人。人数:单排9人,三排6人玩法说明:回合:1、游戏分为多个回合,每回合开始时,斗球会出生在场地中央随机选取一名玩家追击,玩家使用各种手段击球会使斗球提速,被斗球击中将会扣除体力。2、单排每人每回合拥有一点体力,三排每人每

揭秘 C:为新程序员提供一条清晰简单的道路 揭秘 C:为新程序员提供一条清晰简单的道路 Oct 11, 2024 pm 10:47 PM

C是一种初学者学习系统编程的理想选择,它包含以下组件:头文件、函数和主函数。一个简单的C程序可以打印“HelloWorld”,需要包含标准输入/输出函数声明的头文件,并在主函数中使用printf函数来打印。通过使用GCC编译器可以编译和运行C程序。掌握基础后,可以继续学习数据类型、函数、数组和文件处理等主题,以成为熟练的C程序员。

创造未来:面向零基础的 Java 编程 创造未来:面向零基础的 Java 编程 Oct 13, 2024 pm 01:32 PM

Java是热门编程语言,适合初学者和经验丰富的开发者学习。本教程从基础概念出发,逐步深入讲解高级主题。安装Java开发工具包后,可通过创建简单的“Hello,World!”程序实践编程。理解代码后,使用命令提示符编译并运行程序,控制台上将输出“Hello,World!”。学习Java开启了编程之旅,随着掌握程度加深,可创建更复杂的应用程序。

See all articles