JavaScript 轮回

JavaScript中直接供应的轮回,主要有以下几种

while 轮回

和其他言语一样,JavaScript中的while轮回有两种情势:

while (condition) {
    // 轮回内容
}

do {
    // 轮回内容
} while (condition)

个中两种情势的差别在于,对condition推断的位置差别,前者先推断,再实行轮回体;而后者先实行轮回体一次,再举行前提推断。所以效果的差别就是后者能将轮回内容最少实行一次。

for 轮回

for轮回的语法:

for (init; condition; step) {
    // 轮回体代码块
}
  • init 语句 中的内容,会在轮回代码最先前实行一次,一般用来声明一些变量。

  • condition 语句 会在每次轮回最先时,举行推断。假如第一次就不满足,则不会进入轮回。

  • step 语句 会在每次轮回完毕时实行,一般是递增或递减condition中的某个变量。

var arr = [0, 10, 20, 30];

for (var j = 0; j < arr.length; j++) {
    console.log(arr[j]);
}

// 假如在轮回体中不会转变数组的长度,用一个变量存储数组长度是个更高效的挑选
for (var i = 0, l = arr.length; i < l; i++) {
    console.log(arr[i]);
}

var k = 0,
    length = arr.length;
for (; k < length; k++) {
    console.log(arr[k]);
}

for轮回中的init语句,一般用来声明初始变量,其能够有多个,用,分开即可。而且因为此语句是在轮回最先前实行,且只用实行一次,所以假如在外部已声明过要用的变量了,for轮回中的这个语句能够直接省略,如上例中的第三个for轮回所示。

for轮回的前提语句是在每次轮回体最先前举行推断,假如为true,则实行轮回体内容,不然完毕轮回。当此语句省略时,示意不举行前提推断,轮回将一向实行,只要在轮回中运用break来跳出轮回。

for轮回的step语句,最常见的就是运用++也许-- 运算符的表达式,不过也能够运用其他恣意值的,而且也能够省略,换到轮回体中举行转变赋值。

for-in 轮回

for-in轮回是JavaScript中特地供应用来遍历对象属性的。

var zs = {
    name: 'zhang san',
    gender: 'male',
    age: 26
};

for (var key in zs) {
    console.log('%s : %s', key, zs[key]);
}
// name : zhang san
// gender : male
// age : 26

不过须要注重一点题目,请看以下示例:

function Person(name, gender) {
    this.name = name;
    this.gender = gender;
}
Person.prototype.sayHello = function() {
    console.log('Hello,I am', this.name, '. I\'m a', this.gender);
};

var zs = new Person('zhang san', 'male');

for (var key in zs) {
    console.log('%s : %s',key, zs[key]);
}
// name : zhang san
// gender : male
// sayHello : function () {
//    console.log('Hello,I am', this.name, '. I\'m a', this.gender);
// }

此次轮回遍历中,它还输出了zs原型链上的属性sayHello。这反应出一个题目,for - in 轮回会遍历全部原型链,虽然能够运用hasOwnProperty要领举行过滤仅猎取自身属性,但其接见的还是全部原型链,遍历局限较广,所以其效力比较低,一般来讲,其效力仅为一般for轮回的1/7。

JavaScript中,因为数组也是对象,所以此要领也能够用来遍历数组。

var arr = [1, 2, 3, 4];
for (var i in arr) {
    console.log(typeof i);
    if (arr.hasOwnProperty(i))
        console.log('arr[%s] : %d', i, arr[i]);
    else
        console.log('arr.%s : ', i, arr.[i]);
}
// string
// arr[0] : 1
// string
// arr[1] : 2
// string
// arr[2] : 3
// string
// arr[3] : 4
// string
// arr.where : function ...
// string
// arr.groupBy : function ...
// string
// arr.has : function ...

这个输出的效果也许不是你设想的模样,然则他就是如许。我们以为的索引,现实是对象的键名,所以其是String范例。关于数组来讲,和对象一样,在其原型上扩大的要领wheregroupByhas也都被输出了。 也许会有疑问,数组不是有length属性吗,为何没有输出呢?缘由在于数组的length属性是不可罗列属性,for - in轮回不会接见这些属性。关于此的更多学问可参考MDN – 属性的可罗列性和所有权

Array Javascript 中是一个对象, Array 的索引是属性名。事实上, Javascript 中的 “array” 有些误导性, Javascript 中的 Array 并不像大部分其他言语的数组。起首, Javascript 中的 Array 在内存上并不一连,其次, Array 的索引并非指偏移量。现实上, Array 的索引也不是 Number 范例,而是 String 范例的。我们能够正确运用如 arr[0] 的写法的缘由是言语能够自动将 Number 范例的 0 转换成 String 范例的 “0” 。所以,在 Javascript 中从来就没有 Array 的索引,而只要相似 “0” 、 “1” 等等的属性。

for - in 轮回底本就是用来遍历对象的,用其来遍历数组并不适宜,不过也有破例的状况,比方希罕数组:

var arr = new Array(1000);

arr[0] = 1;
arr[99] = 3;
arr[999] = 5;
// for轮回
for (var i = 0, l = arr.length; i < l; i++) {
    console.log('arr[%s]', i, arr[i]);
}
console.log('i :' , i);
// ...
// arr[0] 1
// ...
// arr[99] 3
// ...
// arr[999] 5
// i : 1000


// for - in 轮回
var count = 0;
for(var j in arr){
    count ++ ;
    if(arr.hasOwnProperty(j)){
        console.log('arr[%s]', j, arr[j]);
    }
}
console.log('count : ', count);
// arr[0] 1
// arr[99] 3
// arr[999] 5
// i : 1000

直接运用一般的for轮回,轮回次数为数组长度1000次,而运用for - in轮回,仅仅轮回了3次。

上面看起来轮回的效力是高了不少,然则在前面已说过了,for - in 的专职是对象的遍历(相似的另有Object.keys()),因而上面的计划并非是一个圆满的计划,更好的做法是用是数组自身的遍历要领forEach(forEachES5中新增,须要IE9+)。

var arr = new Array(1000);
arr[0] = 1;
arr[99] = 3;
arr[999] = 5;

var count = 0;
arr.forEach(function(value, index) {
    count++;
    console.log(typeof index);
    console.log(index, value);
});
console.log('count', count);
// number
// 0 1
// number
// 99 3 
// number
// 999 5
// count 3

如许就高效地举行了轮回遍历,而且数组的索引index也被正确地辨认为了number范例。

也许你会想到jQuery中供应的东西要领$.each()$.map()也许实例jQuery对象的eachmap要领,然则效果会让你扫兴的,照旧会是轮回1000次,以下是示例:

var count1 = 0;
$.each(arr, function(index, value) {
    count1++;
    console.log(index, value);
});
console.log('count1',count1);
// count1 1000

var count2 = 0;
$.map(arr,function(value,index){
    count2++;
    console.log(index, value);
});
console.log('count2',count2);
// count2 1000

从上面临比来看Array.prototype.forEach要领好像不错,但其轮回效力依然不如一般的for轮回,不过上风在于在希罕数组的处置惩罚。

不过forEach要领,严厉来算并不算是轮回,缘由在于,它并不能相应轮回应有的breakcontinue语句。正确地讲,它是一个遍历函数,对每一个元素实行指定的回调函数。

for-of轮回

ES6中又新增了for - of 轮回,它与for - in轮回相似,但又有所差别。

  • for - of 支撑对数组类数组对象举行轮回,不支撑一般对象的轮回。

  • for - of 支撑对字符串举行轮回遍历。

  • for - of 支撑对MapSet (ES6 中新增的范例)对象遍历。

  • for - of 不支撑一般对象的轮回遍历。

// 数组
var arr = [0, 1, 2, 3, 4, 5];

for (let index of arr) {
    if (index === 1) continue;
    if (index === 4) break;
    console.log(typeof index);
    console.log(index, arr[index]);
}
// number
// 0 0
// number
// 2 2
// number
// 3 3

当索引为1时直接举行下一次轮回,而当索引为4时,直接退出轮回,因而输出如上效果,也一样正确辨认索引为number范例。

// 类数组
// 类数组
var divs = document.querySelectorAll('div');

for (let i of divs) {
    console.log(i.classList);
}
// ["container", "md-doc", value: "container md-doc"]
// ["doc-cata", value: "doc-cata"]
// ["nicescroll-rails", "nicescroll-rails-vr", value: "nicescroll-rails nicescroll-rails-vr"]
// ["nicescroll-cursors", value: "nicescroll-cursors"]
// ["nicescroll-rails", "nicescroll-rails-hr", value: "nicescroll-rails nicescroll-rails-hr"]
// ["nicescroll-cursors", value: "nicescroll-cursors"]

for (let k in divs) {
    console.log(k, divs[k].classList);
}
// "0" ["container", "md-doc", value: "container md-doc"]
// "1" ["doc-cata", value: "doc-cata"]
// "2" ["nicescroll-rails", "nicescroll-rails-vr", value: "nicescroll-rails nicescroll-rails-vr"]
// "3" ["nicescroll-cursors", value: "nicescroll-cursors"]
// "4" ["nicescroll-rails", "nicescroll-rails-hr", value: "nicescroll-rails nicescroll-rails-hr"]
// "5" ["nicescroll-cursors", value: "nicescroll-cursors"]
// length undefined
// item undefined
// keys undefined
// values undefined
// entries undefined
// forEach undefined

for - of轮回用于类数组对象的处置惩罚时,须要注重,of症结字前面的变量即为类数组对象中的键值,如上例所示,在for - of轮回中i即代表着DOM nodelist 中的每一个对象,而在for - in 轮回中k代表的仅仅是对象的键名。

参考链接

原文宣布在我的博客JavaScript 轮回,迎接接见!

    原文作者:依韵_宵音
    原文地址: https://segmentfault.com/a/1190000008810827
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞