JavaScript基础Javascript中的循环(003)
1.普通循环
JavaScript中一般的循环写法是这样的:
// sub-optimal loop
for (var i = 0; i < myarray.length; i++) {
// do something with myarray[i]
}
这种写法的问题是,每循环一次,都需要从myarray对象中读取length属性,这对于JavaScript来说,可能会导致较大的性能问题。如果myarray是一些大型的对象,或是DOM对象更犹是如此,因为DOM对象的这些方法都是在执行时才进行查询的。比如:
document.getElementsByName()
document.getElementsByClassName()
document.getElementsByTagName()
因此我们应该写成这样:
for (var i = 0, max = myarray.length; i < max; i++) {
// do something with myarray[i]
}
这样我们就在循环一开始把max读取出来,以后就不再从myarray对象中查询了。当然,如果应用唯一var模式,我们应该把声明提高到函数的开头:
function looper() {
var i = 0,
max,
myarray = [];
// ...
for (i = 0, max = myarray.length; i < max; i++) {
// do something with myarray[i]
}
}
这样做我们能得到唯一var模式的好处,但缺点是循环体代码不容易被复用。如果我们进一步缩短这段代码,可以改写成以下两种形式:
var i, myarray = []; //精减后去掉max变量
for (i = myarray.length; i--;) {
// do something with myarray[i]
}
var myarray = [],
i = myarray.length;
while (i--) { //使用while循环
// do something with myarray[i]
}
2. for-in循环
for-
in循环可以有效的遍历对象中的属性,但for-in一般不用在array对象中。一般来说,对于array对象,应该用普通的循环,因为for-in使用在array对象上的意义和遍历array中的元素并不一致。我们在对普通对象使用for-in时,要注意过滤掉对象中的方法,不然也会出现意想不到的问题。比如下面的代码使用Object.prototype,把clone方法加到了所有的对象中去:
// the object
var man = {
hands: 2,
legs: 2,
heads: 1
}; // somewhere else in the code
// a method was added to all objects
if (typeof Object.prototype.clone === "undefined") {
Object.prototype.clone = function () {};
}
这时如果使用for-in循环,就必须使用hasOwnProperty()方法来过滤掉对象中的方法:
// 1.
// for-in loop
for (var i in man) {
if (man.hasOwnProperty(i)) { // filter
console.log(i, ":", man[i]);
}
}
/*
result in the console
hands : 2
legs : 2
heads : 1
*/
如果不这么做,可能就会象下面的代码这样:
// 2.
// antipattern:
// for-in loop without checking hasOwnProperty()
for (var i in man) {
console.log(i, ":", man[i]);
}
/*
result in the console
hands : 2
legs : 2
heads : 1
clone: function()
*/
hasOwnProperty()方法适用于所有的JavaScript对象,不过如果程序员手动的重定义了这个方法,上面的代码就不起效果了。这时就要使用下面的改进的写法:
for (var i in man) {
if (Object.prototype.hasOwnProperty.call(man, i)) { // filter
console.log(i, ":", man[i]);
}
}
这种改进的写法不用man来调用hasOwnproperty()方法,而是用Object的原型来调用。如果你觉得Object.prototype.hasOwnProperty太长,看起来有点啰嗦,也可以采用唯一var模式,把它定义在函数的前头:
var i,
hasOwn = Object.prototype.hasOwnProperty;
for (i in man) {
if (hasOwn.call(man, i)) { // filter
console.log(i, ":", man[i]);
}
}
在上面的例子中,我们使用对象原型(Object.prototype)来为所有的对象加入了方法,这种做法是十分便利的,但也可能会导致代码维护上的问题。因为其它的程序员不一定知道你对所有的对象都动了手脚。所以这种做法是不被鼓励的。如果你非要这样做,建议在此之前检查一下:
if (typeof Object.protoype.myMethod !== "function") {
Object.protoype.myMethod = function () {
// implementation...
};
}
JavaScript基础Javascript中的循环(003)的更多相关文章
- JavaScript基础——JavaScript入门(笔记)
JavaScript入门(笔记) JavaScript是一种轻量级.解释型的Web开发语言,该语言系统不是很庞杂,简单易学.由于所有现代浏览器都已嵌入JavaScript引擎,JavaScript源代 ...
- (译文)JavaScript基础——JavaScript中的深拷贝
在JavaScript中如何拷贝一个对象? 通过引用调用 function mutate(obj) { obj.a = true; } const obj = {a: false}; mutate(o ...
- Javascript基础 - js中曾经忽略的知识点
深入那些曾经忽略的Javascript知识 1. parseInt(string, [radix]),parseFloat(string) 一般我们省略第二个参数,parseInt(‘100’) == ...
- JavaScript基础内容中的函数详解
函数 函数:即方法 函数就是一段预先设置的功能代码块,可以反复调用,根据输入参数的不同,返回不同的值. 为什么使用函数: 1.方便调用 2.代码重用,利于维护 3.便于修改,便于重构 4.简化逻辑,利 ...
- JavaScript基础函数体中的唯一var模式(002)
全局变量是不好的.所以在声名变量的时候,应该采用函数体中的唯一var模式(Single var Pattern).这个模式有不少好处: 提供了一个唯一的地方来查看函数体中声名的变量 在使用一个变量之前 ...
- JavaScript基础——JavaScript语法基础(笔记)
JavaScript语法基础(笔记) 1.语言编码 JavaScript语言建立在Unicode字符集基础之上,因此脚本中,用户可以使用双字节的字符命名常量.变量或函数等. [示例] var 我=&q ...
- JavaScript基础JavaScript的常用编码惯例(007)
采用一定的编码惯例,可以使得项目中的代码提到较高的一致性,可读性和可预测性. 1.缩进缩 进可以提高代码的可读性.不过错误的缩进也可能导致代码的误读.有人认为缩进应该使用tab,另外的一些人主张采用4 ...
- JavaScript基础——JavaScript函数(笔记)
avaScript 函数(笔记) JavaScript 是函数式编程语言,在JavaScript脚本中可以随处看到函数,函数构成了JavaScript源代码的主体. 一.定义函数 定义函数的方法有两种 ...
- JavaScript基础——JavaScript常量和变量(笔记)
JavaScript常量和变量(笔记) Javascript代码严格区分大小写. javascript暂不支持constant关键字,不允许用户自定义常量. javascript使用var关键字声明变 ...
随机推荐
- java实现 历届试题 蓝桥杯 打印十字图
历届试题 打印十字图 题目描述 小明为某机构设计了一个十字型的徽标(并非红十字会啊),如下所示(可参见p1.jpg) 对方同时也需要在电脑dos窗口中以字符的形式输出该标志,并能任意控制层数. 为了能 ...
- Java实现 蓝桥杯 算法训练 Bit Compressor(暴力)
试题 算法训练 Bit Compressor 问题描述 数据压缩的目的是为了减少存储和交换数据时出现的冗余.这增加了有效数据的比重并提高了传输速率.有一种压缩二进制串的方法是这样的: 将连续的n个1替 ...
- Java实现 LeetCode 710 黑名单中的随机数(黑白名单)
710. 黑名单中的随机数 给定一个包含 [0,n ) 中独特的整数的黑名单 B,写一个函数从 [ 0,n ) 中返回一个不在 B 中的随机整数. 对它进行优化使其尽量少调用系统方法 Math.ran ...
- Java实现 LeetCode 52 N皇后 II
52. N皇后 II n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 上图为 8 皇后问题的一种解法. 给定一个整数 n,返回 n 皇后不同的解决方案 ...
- 关于Synchronized的偏向锁,轻量级锁,重量级锁,锁升级过程,自旋优化,你该了解这些
前言 相信大部分开发人员,或多或少都看过或写过并发编程的代码.并发关键字除了Synchronized(如有不懂请移至传送门,关于Synchronized的偏向锁,轻量级锁,重量级锁,锁升级过程,自旋优 ...
- Linux笔记(第一天)
一.命令 lscpu -- 查看cpu free -- 内存查看 -m 以M ...
- 面试官突然问我MySQL存储过程,我竟然连基础都不会!(详细)
所有知识体系文章,GitHub已收录,欢迎Star!再次感谢,愿你早日进入大厂! GitHub地址: https://github.com/Ziphtracks/JavaLearningmanual ...
- ubuntu12.04 qtcreate支持中文输入
1.sudo apt-get install ibus-qt4 2.重启电脑 reboot
- workbench中如何导入.sql文件
在做电商管理系统的时候,需要使用 mysql 中的数据,在执行 app.js 文件时出现错误 于是将 mydb.sql 导入到workbench中,步骤如下: 1. 打开 workbench 软件,选 ...
- Supervisor操作相关的进程
Supervisor是用Python开发的一个客户机/服务器系统,允许用户监视和控制UNIX类操作系统上的多个进程. 功能:用于监听.启动.停止.重启一个或多个进程. 当Supervisor管理的进程 ...