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实现 LeetCode 306 累加数
306. 累加数 累加数是一个字符串,组成它的数字可以形成累加序列. 一个有效的累加序列必须至少包含 3 个数.除了最开始的两个数以外,字符串中的其他数都等于它之前两个数相加的和. 给定一个只包含数字 ...
- Java实现蓝桥杯VIP算法训练 相邻字母
试题 算法训练 相邻字母 资源限制 时间限制:1.0s 内存限制:256.0MB [问题描述] 从键盘输入一个英文字母,要求按字母的顺序打印出3个相邻的字母,指定的字母在中间.若指定的字母为Z,则打印 ...
- java实现黄金队列
** 黄金队列** 黄金分割数0.618与美学有重要的关系.舞台上报幕员所站的位置大约就是舞台宽度的0.618处,墙上的画像一般也挂在房间高度的0.618处,甚至股票的波动据说也能找到0.618的影子 ...
- Java实现第十届蓝桥杯迷宫
试题 E: 迷宫 本题总分:15 分 [问题描述] 下图给出了一个迷宫的平面图,其中标记为 1 的为障碍,标记为 0 的为可 以通行的地方. 010000 000100 001001 110000 迷 ...
- java实现第六届蓝桥杯灾后重建
灾后重建 题目描述 Pear市一共有N(<=50000)个居民点,居民点之间有M(<=200000)条双向道路相连.这些居民点两两之间都可以通过双向道路到达.这种情况一直持续到最近,一次严 ...
- opencl(5)缓存对象
//创建的内存对象由内核访问,将缓冲区作为参数传递给内核 1:创建缓存对象 cl_mem clCreateBuffer( cl_context context, //上下文 cl_mem_flags ...
- 彻底搞懂 etcd 系列文章(二):etcd 的多种安装姿势
0 专辑概述 etcd 是云原生架构中重要的基础组件,由 CNCF 孵化托管.etcd 在微服务和 Kubernates 集群中不仅可以作为服务注册与发现,还可以作为 key-value 存储的中间件 ...
- 教科书级讲解,秒懂最详细Java的注解
所有知识体系文章,GitHub已收录,欢迎Star!再次感谢,愿你早日进入大厂! GitHub地址: https://github.com/Ziphtracks/JavaLearningmanual ...
- 第03组 Alpha(2/4)
队名:不等式方程组 组长博客 作业博客 团队项目进度 组员一:张逸杰(组长) 过去两天完成的任务: 文字/口头描述: 制定了初步的项目计划,并开始学习一些推荐.搜索类算法 GitHub签入纪录: 暂无 ...
- jdbc+mysql常见报错总结
1.The server time zone value '�й���ʱ��' is unrecognized or represents more than one time zone. You ...