js基础笔记,数组

JavaScript break 和 continue 语句

break 语句用于跳出循环。

continue 用于跳过循环中的一个迭代。

break 语句

我们已经在本教程之前的章节中见到过 break 语句。它用于跳出 switch() 语句。

break 语句可用于跳出循环。

break 语句跳出循环后,会继续执行该循环之后的代码(如果有的话):

实例

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title></title>

</head>

<body>

<p>点击按钮,测试带有 break 语句的循环。</p>

<button οnclick="myFunction()">点击这里</button>

<p id="demo"></p>

<script>

function myFunction(){

var x="",i=0;

for (i=0;i<10;i++){

if (i==3){

     break;

}

     x=x + "该数字为 " + i + "<br>";

    }

document.getElementById("demo").innerHTML=x;

}

</script>

</body>

</html>

点击按钮,测试带有 break 语句的循环。

点击这里

由于这个 if 语句只有一行代码,所以可以省略花括号:

for (i=0;i<10;i++) { if (i==3) break; x=x + "The number is " + i + "<br>"; }

continue 语句

continue 语句中断循环中的迭代,如果出现了指定的条件,然后继续循环中的下一个迭代。 以下例子在值为 3 时,直接跳过:

for 实例

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>菜鸟教程(runoob.com)</title>

</head>

<body>

<p>点击下面的按钮来执行循环,该循环会跳过 i=3 的数字。</p>

<button οnclick="myFunction()">点击这里</button>

<p id="demo"></p>

<script>

function myFunction(){

var x="",i=0;

for (i=0;i<10;i++){

   if (i==3){

     continue;

     }

x=x + "该数字为 " + i + "<br>";

   }

document.getElementById("demo").innerHTML=x;

}

</script>

</body>

</html>

点击下面的按钮来执行循环,该循环会跳过 i=3 的数字。

点击这里

while 实例

while (i < 10){ if (i == 3){ i++; //加入i++不会进入死循环 continue; } x= x + "该数字为 " + i + "<br>"; i++; }

JavaScript 标签

正如您在 switch 语句那一章中看到的,可以对 JavaScript 语句进行标记。

如需标记 JavaScript 语句,请在语句之前加上冒号:

label: statements

break 和 continue 语句仅仅是能够跳出代码块的语句。

语法:

break labelname; continue labelname;

continue 语句(带有或不带标签引用)只能用在循环中。

break 语句(不带标签引用),只能用在循环或 switch 中。

通过标签引用,break 语句可用于跳出任何 JavaScript 代码块:

实例

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title></title>

</head>

<body>

<script>

cars=["BMW","Volvo","Saab","Ford"];

list:{

document.write(cars[0] + "<br>");

document.write(cars[1] + "<br>");

document.write(cars[2] + "<br>");

break list;

document.write(cars[3] + "<br>");

document.write(cars[4] + "<br>");

document.write(cars[5] + "<br>");

}

</script>

</body>

</html>

结果:BMW
Volvo
Saab

关于 JavaScript 标签与 break 和 continue 一起使用的理解。

break 的作用是跳出代码块, 所以 break 可以使用于循环和 switch 等

continue 的作用是进入下一个迭代, 所以 continue 只能用于循环的代码块。

代码块: 基本上是{}大括号之间

然后:

1. 默认标签的情况(除了默认标签情况,其他时候必须要有名标签,否则会有惊喜)

当 break 和 continue 同时用于循环时,没有加标签,此时默认标签为当前"循环"的代码块。

当 break 用于 switch 时,默认标签为当前的 switch 代码块:

有名标签的情况

cars=["BMW","Volvo","Saab","Ford"];

list:{

    document.write(cars[0] + "");

    document.write(cars[1] + "");

    document.write(cars[2] + "");

    break list;

    document.write(cars[3] + "");

    document.write(cars[4] + "");

    document.write(cars[5] + "");}

上述break list;会跳出list的代码块。如果将break换成continue会有惊喜,违反了明确中的第二点,因为list只是个普通代码块,而不是循环。除非list写成如下形式 list:

for(var i=0; i<10; ++i){

    continue list;}

有了标签,可以使用break和continue在多层循环的时候控制外层循环。

例如下面:

outerloop:for (var i = 0; i < 10; i++){

    innerloop:

    for (var j = 0; j < 10; j++)

    {

        if (j > 3)

        {

            break;

        }

        if (i == 2)

        {

            break innerloop;

        }

        if (i == 4)

        {

            break outerloop;

        }

        document.write("i=" + i + " j=" + j + "");

    }}

JavaScript Array(数组) 对象

数组对象的作用是:使用单独的变量名来存储一系列的值。

var mycars = new Array();
mycars[0] = "Saab";
mycars[1] = "Volvo";
mycars[2] = "BMW";

什么是数组?

数组对象是使用单独的变量名来存储一系列的值。

如果你有一组数据(例如:车名字),存在单独变量如下所示:

var car1="Saab";
var car2="Volvo";
var car3="BMW";

然而,如果你想从中找出某一辆车?并且不是3辆,而是300辆呢?这将不是一件容易的事!

最好的方法就是用数组。

数组可以用一个变量名存储所有的值,并且可以用变量名访问任何一个值。

数组中的每个元素都有自己的的ID,以便它可以很容易地被访问到。

创建一个数组

创建一个数组,有三种方法。

下面的代码定义了一个名为 myCars的数组对象:

1: 常规方式:

var myCars=new Array();
myCars[0]="Saab";      
myCars[1]="Volvo";
myCars[2]="BMW";

2: 简洁方式:

var myCars=new Array("Saab","Volvo","BMW");

3: 字面:

var myCars=["Saab","Volvo","BMW"];

访问数组

通过指定数组名以及索引号码,你可以访问某个特定的元素。

以下实例可以访问myCars数组的第一个值:

var name=myCars[0];

以下实例修改了数组 myCars 的第一个元素:

myCars[0]="Opel";

[0] 是数组的第一个元素。[1] 是数组的第二个元素。

在一个数组中你可以有不同的对象

所有的JavaScript变量都是对象。数组元素是对象。函数是对象。

因此,你可以在数组中有不同的变量类型。

你可以在一个数组中包含对象元素、函数、数组:

myArray[0]=Date.now;
myArray[1]=myFunction;
myArray[2]=myCars;

数组方法和属性

使用数组对象预定义属性和方法:

var x=myCars.length             // myCars 中元素的数量
var y=myCars.indexOf("Volvo")   // "Volvo" 值的索引值

完整的数组对象参考手册

你可以参考本站关于数组的所有属性和方法的完整参考手册。

参考手册包含了所有属性和方法的描述(和更多的例子)。

完整数组对象参考手册

创建新方法

原型是JavaScript全局构造函数。它可以构建新Javascript对象的属性和方法。

实例:创建一个新的方法。

Array.prototype.myUcase=function(){
    for (i=0;i<this.length;i++){
        this[i]=this[i].toUpperCase();
    }
}

数组去重                                                                                                                                                                                                      

第一种:遍历数组法

这种方法最简单最直观,也最容易理解,代码如下:

1  var arr = [2, 8, 5, 0, 5, 2, 6, 7, 2]2   var newArr = []3   for (var i = 0; i < arr.length; i++) {4     if (newArr.indexOf(arr[i]) === -1) {5       newArr.push(arr[i])6     }7   }8   console.log(newArr) // 结果:[2, 8, 5, 0, 6, 7]

这种方法很好理解,利用了indexOf()方法(indexOf()方法如果查询到则返回查询到的第一个结果在数组中的索引,如果查询不到则返回-1)。先创建一个新的空数组用来存储新的去重的数组,然后遍历arr数组,在遍历过程中,分别判断newArr数组里面是不是有遍历到的arr中的元素,如果没有,直接添加进newArr中,如果已经有了(重复),那么不操作,那么从头到尾遍历一遍,正好达到了去重的目的。

第二种:数组下标判断法

这种方法也比较好理解,代码如下:

1 var arr = [2, 8, 5, 0, 5, 2, 6, 7, 2]2   var newArr = []3   for (var i = 0; i < arr.length; i++) {4     if (arr.indexOf(arr[i]) === i) {5       newArr.push(arr[i])6     }7   }8   console.log(newArr) // 结果:[2, 8, 5, 0, 6, 7]

这和第一种方法有重叠,不说多余的,直接看if这里,在遍历arr的过程中,如果在arr数组里面找当前的值,返回的索引等于当前的循环里面的i的话,那么证明这个值是第一次出现,所以推入到新数组里面,如果后面又遍历到了一个出现过的值,那也不会返回它的索引,indexof()方法只返回找到的第一个值的索引,所以重复的都会被pass掉,只出现一次的值都被存入新数组中,也达到了去重的目的。

第三种:排序后相邻去除法

这种方法用到了sort()方法,代码如下:

1 var arr = [2, 8, 5, 0, 5, 2, 6, 7, 2]2   arr.sort()3   var newArr = [arr[0]]4   for (var i = 1; i < arr.length; i++) {5     if (arr[i] !== newArr[newArr.length - 1]) {6       newArr.push(arr[i])7     }8   }9   console.log(newArr) // 结果:[0, 2, 5, 6, 7, 8]

这种方法的思路是:先用sort()方法把arr排序,那么排完序后,相同的一定是挨在一起的,把它去掉就好了,首先给新数组初始化一个arr[0],因为我们要用它和arr数组进行比较,所以,for循环里面i也是从1开始了,我们让遍历到的arr中的值和新数组最后一位进行比较,如果相等,则pass掉,不相等的,push进来,因为数组重新排序了,重复的都挨在一起,那么这就保证了重复的这几个值只有第一个会被push进来,其余的都和新数组的被push进来的这个元素相等,会被pass掉,也达到了去重的效果。

第四种:优化的遍历数组法

 1  var arr = [2, 8, 5, 0, 5, 2, 6, 7, 2, 8]

 2   var newArr = []

 3   for (var i = 0; i < arr.length; i++) {

 4     for (var j = i + 1; j < arr.length; j++) {

 5       if (arr[i] === arr[j]) {

 6         i++

 7         j = i

 8       }

 9     }10     newArr.push(arr[i])11   }12   console.log(newArr) // 结果:[0, 5, 6, 7, 2, 8]

思路:两层for循环,外面一层是控制遍历到的前一个arr中的元素,里面一层控制的是第一层访问到的元素后面的元素,不断的从第0个开始,让第0个和他后面的元素比较,如果没有和这个元素相等的,则证明没有重复,推入到新数组中存储起来,如果有和这个元素相等的,则pass掉它,直接进入下一次循环。从第1个开始,继续和它后面的元素进行比较,同上进行,一直循环到最后就是:不重复的都被推入新数组里面了,而重复的前面的元素被pass掉了,只留下了最后面的一个元素,这个时候也就不重复了,则推入新数组,过滤掉了所有重复的元素,达到了去重的目的。

第五种:数组遍历法

 1 var arr = ['a', 'a', 'b', 'c', 'b', 'd', 'e', 'a']

 2   var newArr = []

 3   for (var i = 0; i < arr.length; i++) {

 4     var bl = true

 5     for (var j = 0; j < newArr.length; j++) {

 6       if (arr[i] === newArr[j]) {

 7         bl = false

 8         break

 9       }10     }11     if (bl) {12       newArr.push(arr[i])13     }14   }15   console.log(newArr) // 结果:["a", "b", "c", "d", "e"]

思路:也是两层for循环,外层for循环控制的是arr数组的遍历,内层for循环控制的是新数组的遍历,从第0位开始,如果新数组中没有这个arr数组中遍历到的这个元素,那么状态变量bl的值还是true,那么自然进入到了if中把这个值推入到新数组中,如果有这个元素,那么代表重复,则把状态变量bl取值改为false,并且跳出当前循环,不会进入到if内部,而进入下一次外层开始的循环。这样循环往复,最后也达到了去重的效果。

比较数组中数值的大小是比较常见的操作,比较大小的方法有多种,比如可以使用自带的sort()函数,下面来介绍如下几种方法,代码如下:

方法一:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

//最小值

Array.prototype.min = function() {

var min = this[0];

var len = this.length;

for (var i = 1; i < len; i++){

if (this[i] < min){

min = this[i];

}

}

return min;

}

//最大值

Array.prototype.max = function() {

var max = this[0];

var len = this.length;

for (var i = 1; i < len; i++){

if (this[i] > max) {

max = this[i];

}

}

return max;

}

如果你是引入类库进行开发,害怕类库也实现了同名的原型方法,可以在生成函数之前进行重名判断:

1

2

3

4

5

if (typeof Array.prototype['max'] == 'undefined') {

Array.prototype.max = function() {

... ...

}

}

方法二:

用Math.max和Math.min方法可以迅速得到结果。apply能让一个方法指定调用对象与传入参数,并且传入参数是以数组形式组织的。恰恰现在有一个方法叫Math.max,调用对象为Math,与多个参数

1

2

3

4

5

6

Array.max = function( array ){

return Math.max.apply( Math, array );

};

Array.min = function( array ){

return Math.min.apply( Math, array );

};

但是,John Resig是把它们做成Math对象的静态方法,不能使用大神最爱用的链式调用了。但这方法还能更精简一些,不要忘记,Math对象也是一个对象,我们用对象的字面量来写,又可以省几个比特了。

1

2

3

4

5

6

7

8

Array.prototype.max = function(){

return Math.max.apply({},this)

}

Array.prototype.min = function(){

return Math.min.apply({},this)

}

[1,2,3].max()// => 3

[1,2,3].min()// => 1

方法三:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

function getMaximin(arr,maximin)

{

if(maximin=="max")

{

return Math.max.apply(Math,arr);

}

else if(maximin=="min")

{

return Math.min.apply(Math, arr);

}

}

var a=[3,2,4,2,10];

var b=[12,4,45,786,9,78];

console.log(getMaximin(a,"max"));//10

console.log(getMaximin(b,"min"));//04

方法四:

1

2

3

var a=[1,2,3,5];

alert(Math.max.apply(null, a));//最大值

alert(Math.min.apply(null, a));//最小值

多维数组可以这么修改:

1

2

3

4

var a=[1,2,3,[5,6],[1,4,8]];

var ta=a.join(",").split(",");//转化为一维数组

alert(Math.max.apply(null,ta));//最大值

alert(Math.min.apply(null,ta));//最小值

函数的定义

JavaScript三种定义函数方法:

*第一种 使用function语句定义函数

myFunction(5);function myFunction(y) {

    return y * y;}

第二种 使用Function()构造函数来定义函数(不常用)

var 函数名 = new Function(“参数1”,”参数2”,”参数3”……”函数体”);

如:var 函数名 = new Function("x","y","var z=x+y;return z;");

*第三种 函数表达式

JavaScript 函数可以通过一个表达式定义。

函数表达式可以存储在变量中:

var 函数名 = function(参数1,参数2,…){函数体};//例如://定义

    var add = function(a,b){

        return a+b;

    }

    //调用函数

    document.write(add(50,20));

第四种 自调用函数

函数表达式可以 "自调用"。

自调用表达式会自动调用。

如果表达式后面紧跟 () ,则会自动调用。

不能自调用声明的函数。

通过添加括号,来说明它是一个函数表达式:

实例:

(function () {

    var x = "Hello!!";      // 我将调用自己})();

注意:

arguments 对象

在函数代码中,使用特殊对象 arguments,开发者无需明确指出参数名,就能访问它们。
例如,在函数 sayHi() 中,第一个参数是 message。用 arguments[0]
也可以访问这个值,即第一个参数的值(第一个参数位于位置 0,
第二个参数位于位置 1,依此类推)。

例如:arguments

x = sumAll(1, 123, 500, 115, 44, 88);

function sumAll() {

    var i, sum = 0;

    for (i = 0; i < arguments.length; i++) {

        sum += arguments[i];

    }

    return sum;}

关于变量和参数问题:

1. 函数外面定义的变量是全局变量,函数内可以直接使用

2. 在函数内部没有使用var定义的=变量则为全局变量

3. 在函数内使用var关键字定义的变量是局部变量,即出了函数外边无法获取。

函数支持默认值

4. 在函数内部定义的函数为局部函数 在函数外部不能获取到

二 JavaScript 闭包

JavaScript 变量可以是局部变量或全局变量。

私有变量可以用到闭包。

函数内部可以修改函数外部的全局变量

计数器困境

设想下如果你想统计一些数值,且该计数器在所有函数中都是可用的。

你可以使用全局变量,函数设置计数器递增:

var counter = 0;

function add() {

   return counter += 1;}

 add();add();add();

 // 计数器现在为 3

但问题来了,页面上的任何脚本都能改变计数器,即便没有调用 add() 函数。

如果我在函数内声明计数器,如果没有调用函数将无法修改计数器的值:

function add() {

    var counter = 0;

    return counter += 1;}

 add();add();add();// 本意是想输出 3, 但事与愿违,输出的都是 1 !

JavaScript 内嵌函数

所有函数都能访问全局变量。

实际上,在 JavaScript 中,所有函数都能访问它们上一层的作用域。

JavaScript 支持嵌套函数。嵌套函数可以访问上一层的函数变量。

该实例中,内嵌函数 plus() 可以访问父函数的 counter 变量:

实例:

function add() {

    var counter = 0;

    function plus() {counter += 1;}

    plus();    

    return counter; }

JavaScript 闭包

var add = (function () {

    var counter = 0;

    return function () {return counter += 1;}})();

 add();add();add();

 // 计数器为 3

实例解析

变量 add 指定了函数自我调用的返回字值。

自我调用函数只执行一次。设置计数器为 0。并返回函数表达式。

add变量可以作为一个函数使用。非常棒的部分是它可以访问函数上一层作用域的计数器。

这个叫作 JavaScript 闭包。它使得函数拥有私有变量变成可能。

计数器受匿名函数的作用域保护,只能通过 add 方法修改

JavaScript 函数参数

JavaScript 函数对参数的值没有进行任何的检查。

函数显式参数(Parameters)与隐式参数(Arguments)

在先前的教程中,我们已经学习了函数的显式参数:

functionName(parameter1, parameter2, parameter3) { // 要执行的代码…… }

函数显式参数在函数定义时列出。

函数隐式参数在函数调用时传递给函数真正的值。

参数规则

JavaScript 函数定义显式参数时没有指定数据类型。

JavaScript 函数对隐式参数没有进行类型检测。

JavaScript 函数对隐式参数的个数没有进行检测。

默认

ES5 中如果函数在调用时未提供隐式参数,参数会默认设置为: undefined

有时这是可以接受的,但是建议最好为参数设置一个默认值:

实例(ES5)

function myFunction(x, y) { if (y === undefined) { y = 0; } }

或者,更简单的方式:

实例(ES5)

function myFunction(x, y) { y = y || 0; }

如果y已经定义 , y || 返回 y, 因为 y 是 true, 否则返回 0, 因为 undefined 为 false。

如果函数调用时设置了过多的参数,参数将无法被引用,因为无法找到对应的参数名。 只能使用 arguments 对象来调用。

ES6 函数可以自带参数

ES6 支持函数带有默认参数,就判断 undefined 和 || 的操作:

实例(ES6)

function myFunction(x, y = 10) { // y is 10 if not passed or undefined return x + y; } myFunction(0, 2) // 输出 2 myFunction(5); // 输出 15, y 参数的默认值

arguments 对象

JavaScript 函数有个内置的对象 arguments 对象。

argument 对象包含了函数调用的参数数组。

通过这种方式你可以很方便的找到最大的一个参数的值:

实例

x = findMax(1, 123, 500, 115, 44, 88); function findMax() { var i, max = arguments[0]; if(arguments.length < 2) return max; for (i = 0; i < arguments.length; i++) { if (arguments[i] > max) { max = arguments[i]; } } return max; }

或者创建一个函数用来统计所有数值的和:

实例

x = sumAll(1, 123, 500, 115, 44, 88); function sumAll() { var i, sum = 0; for (i = 0; i < arguments.length; i++) { sum += arguments[i]; } return sum; }

通过值传递参数

在函数中调用的参数是函数的隐式参数。

JavaScript 隐式参数通过值来传递:函数仅仅只是获取值。

如果函数修改参数的值,不会修改显式参数的初始值(在函数外定义)。

隐式参数的改变在函数外是不可见的。

通过对象传递参数

在JavaScript中,可以引用对象的值。

因此我们在函数内部修改对象的属性就会修改其初始的值。

修改对象属性可作用于函数外部(全局变量)。

修改对象属性在函数外是可见的。

JS冒泡排序

原理

依次比较相邻的两个值,如果后面的比前面的小,则将小的元素排到前面。依照这个规则进行多次并且递减的迭代,直到顺序正确。

时间复杂度,空间复杂度,稳定性

  • 平均时间复杂度O(n*n)
  • 最好情况O(n)
  • 最差情况O(n*n)
  • 空间复杂度O(1)
  • 稳定性:稳定

冒泡排序的写法

var examplearr=[8,94,15,88,55,76,21,39];function sortarr(arr){

    for(i=0;i<arr.length-1;i++){

        for(j=0;j<arr.length-1-i;j++){

            if(arr[j]>arr[j+1]){

                var temp=arr[j];

                arr[j]=arr[j+1];

                arr[j+1]=temp;

            }

        }

    }

    return arr;

}

sortarr(examplearr);

console.log(examplearr);

解析

两个循环

当i=0的时候,里面的循环完整执行,从j=0执行到j=6,这也就是第一遍排序,结果是将最大的数排到了最后,这一遍循环结束后的结果应该是[8,15,88,55,76,21,39,94]

当i=1的时候,里面的循环再次完整执行,由于最大的数已经在最后了,没有必要去比较数组的最后两项,这也是j<arr.length-1-i的巧妙之处,结果是[8,15,55,76,21,39,88,94]

说到这里,规律就清楚了,每次将剩下数组里面最大的一个数排到最后面,当第一个循环执行到最后的时候,也就是i=6,此时,j=0,只需要比较数组的第一和第二项,比较完毕,返回。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值