简介:1. 初识JS1.1 什么是JS语言javascript是一种运行在客户端 的脚本语言客户端: 即接受服务的一端,与服务端相对应,在前端开发中,通常客户端指的就是浏览器。脚本语言: 也叫解释型语言,特点是执行一行,解释一行, ...
1. 初识JS1.1 什么是JS语言javascript是一种运行在客户端 的脚本语言客户端: 即接受服务的一端,与服务端相对应,在前端开发中,通常客户端指的就是浏览器。脚本语言: 也叫解释型语言,特点是执行一行,解释一行,如果发现报错,代码就停止执行。1.2 JS的三个组成部分 javascript的三个组成部分:ECMAScript、BOM、DOMECMAScript: 定义了javascript的语法规范。BOM: 一套操作浏览器功能的API。DOM: 一套操作页面元素的API。1.3 script 标签1、script标签的书写方式 书写Javascript代码有两种方式,第一种是直接在script标签中书写,第二种是将代码写在js文件中,通过script的src属性进行引入。直接在script中书写javascript代码: <!-- type="text/javascript" 可以省略 --><script type="text/javascript"> alert("今天天气真好呀");</script>通过script标签引入一个JS文件,需要指定src属性: <!-- 表示引用了test.js文件,并且script标签内不可以继续写代码 --><script src="test.js"></script>如果script标签指定了src属性,说明是想要引入一个js文件,这个时候不能继续在script标签中写js代码,即便写了,也不会执行。2、script标签的书写位置 script标签的书写位置,原则上来说,可以在页面中的任意位置书写。写在head标签中,style标签之后: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Document</title> <link rel="stylesheet" href="demo.css"> <!-- 写在这里 --> <script src="demo.js"></script></head><body></body></html>浏览器有一个特性,就是在遇到<body>标签时才开始呈现内容。如果在head里面引用js文件的话,意味着必须要等到全部的javascript代码都被下载、解析和执行完成之后,才能开始呈现页面的内容。如果文件数量一旦过多,将会影响页面加载速度,此时页面有可能会在加载完成前一片空白。写在</body>标签的前面: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Document</title> <link rel="stylesheet" href="demo.css"></head><body> <!-- 写在这里 --> <script src="demo.js"></script></body></html>在解析javascript代码之前,页面的内容已经完全呈现在浏览器当中了,用户会明显感觉页面加载变快了。1.4 js中输入输出语句
不被程序执行的代码。用于程序员标记代码,在后期的修改,以及他人的学习时有所帮助,在JS中,分为单行注释和多行注释以及文档注释。单行注释 //这是单行注释,只能注释一行多行注释 /* 这是多行注释,不能嵌套*/文档注释 /** * 求圆的面积 * @param r {number} 圆的半径 * @returns {number} 圆的面积 * 这是文档注释 */function getArea (r) { return Math.PI * r * r;}注释的作用
变量,可以变化的量,变量是在计算机中存储数据的一个标识符。可以把变量看成存储数据的容器。变量与字面量:
// 1- 同时声明并且赋值var num = 100;console.log(num); // 100// 2- 先声明了一个变量,再赋值var num1;num1 = 100;console.log(num1); // 100// 3- 没有声明变量,直接赋值(可以,但是不推荐)num2 = 200;console.log(num2); // 200// 4- 有变量声明,但是没有赋值(可以,没有赋值,变量的值默认是个undefined)var num9;console.log(num9); // undefined// 5- 既没有声明,也没有赋值,直接用。console.log(num3); //报错 num3// 6- 一个 var,逗号分隔 可以同时声明多个变量var name = "Levi丶", age = 18, gender = "男";2.2 变量的命名规则与规范命名规则(必须遵守):
// 交换 num1 和 num2的值var num1 = 11;var num2 = 22;var temp;temp = num1; // num1=11 temp=11num1 = num2; // num1=22 num2=22num2 = temp; // temp=11 num2=11方法二: 不通过声明变量的方式 // 不使用临时变量var num1 = 11;var num2 = 22;// num1 = 11 + 22num1 = num1 + num2; // num1=33 // num2 = 33 - 22num2 = num1 - num2; // num2=11// num1 = 33 - 11 num1 = num1 - num2; // num1=223. 数据类型 基本数据类型包括了:number、string、boolean、undefined、null3.1 如何查看数据类型 使用typeof关键字查看数据类型 typeof(name); // 括号可以省略typeof name;3.2 Number 类型进制
所谓浮点数,就是该数当中必须包含一个小数点,并且小数点后面至少有一位数字。科学计数法: //如何表示0.003和20000?var num = 3e-3; // 0.003var num2 = 2e+4; // 20000浮点数的精度问题: 0.1 + 0.2 = ? // 0.300000000000000040.07 * 100 = ? // 7.000000000000001浮点数在运算的时候会出现精度丢失的问题,因此在做比较运算的时候,尽量不要用小数进行比较。在第五章的时候会着重讲解这个问题数值范围 javascript不能表示世界上所有的数,因此在javascript中,数值大小是有一定限制的。
var str = "abc";console.log(isNaN(str)); // true 说明不是一个数字3.3 String 类型字面量 字符串的字面量:“abc” 、 ‘abc’ 字符串可以是双引号,也可以是单引号引起来。不管是双引号,还是单引号,都是成对出现的,假如打印的字符串里有引号怎么办呢?这里就要活学活用,如果只有一处有引号,就可以用单双引号混合使用: console.log("我是"帅哥""); // ==> 我是"帅哥"假如引号非常多的时候怎么办呢? 用转义字符:“”: console.log("我是"帅哥","哈哈哈""); // ==> 我是"帅哥","哈哈哈"字符串拼接 拼接字符串使用+号示例代码: console.log(11 + 11); // 22console.log("hello" + " world"); // "hello world"console.log("100" + "100"); // "100100"console.log("11" + 11); // "1111"总结:
length属性用来获取字符串的长度 var str = "abcdefghij";str.length;// 字符串的长度 103.4. boolean 类型 boolean类型只有两个字面量,true和false,区分大小写(True,False不是布尔类型,只是标识符)。所有类型的值都可以转化成true或者falseNaN、""、undefined、null、alse、0 这6个值可以转换成false,其余的都是true。3.5 undefined类型与null类型undefined表示一个声明了没有赋值的变量 var name ;console.log(name); // undefinednull表示一个空的对象 var name = null;console.log(typeof name); // Object如果定义的变量,将来是准备用于保存对象的话,最好将变量初始化为null var name = null;undefined 与 null 的关系 undefined == null; // trueundefined === null; // false实际上,undefiner值是派生自null值的,所以判断相等时为true,但是两种用途是完全不一样的。4. 简单数据类型转换 如何使用谷歌浏览器,快速的查看数据类型?
var num = 123;console.log(String(num)); // "123"2、toString() 转换不了undefined 和 null var num = 123;console.log(num.toString()); // "123"console.log(undefined.toString()); // 报错console.log(null.toString()); // 报错3、+ "" 加引号 var num = 123;console.log(num + ""); // "123"4.2 转数值类型1、Number
console.log(Number("-123")); // -123console.log(Number("")); // 0console.log(Number("123abc")); // NaN2、parseInt(取整)
console.log(parseInt("123.123")); // 123console.log(parseInt("123.123abc")); // 123console.log(parseInt("abc123.123")); // NaNconsole.log(parseInt("")); // NaNconsole.log(parseInt("abc")); // NaN3、parseFloat(取数)
console.log(parseFloat("123.123")); // 123.123console.log(parseFloat("123.123abc")); // 123.123console.log(parseFloat("abc123.123")); // NaNconsole.log(parseFloat("")); // NaNconsole.log(parseFloat("abc")); // NaN4、参与运算==> "+" or "-0" var str = "-123";console.log(+str); // -123console.log(str-0); // -1234.3 转布尔类型 布尔类型只有true和false,但是所有类型的值都可以转换成布尔类型1、能够转换成false的只有6种:
var str = "";// Boolean() 判断这个参数的布尔类型console.log(Boolean(str)); // falseconsole.log(!str); // true5. JS小数运算精度丢失5.1 JS数字精度丢失的一些典型问题js在使用小数进行计算的时候,会出现精度丢失的问题。不要用来跟其他的小数做比较。 0.1 + 0.2 != 0.3 //true 0.30000000000000004// 16位数 和 17位数相等9999999999999999 == 10000000000000001 // true9007199254740992 + 1 == 9007199254740992 // true5.2 JS数字丢失精度的原因计算机的二进制实现和位数限制有些数无法有限表示。就像一些无理数不能有限表示,如 圆周率 3.1415926...,1.3333... 等。JS 遵循 IEEE 754 规范,采用 双精度存储(double precision) ,占用 64 bit。如图
0.1 >> 0.0001 1001 1001 1001…(1001无限循环)0.2 >> 0.0011 0011 0011 0011…(0011无限循环)此时只能模仿十进制进行四舍五入了,但是二进制只有0和1两个,于是变为0舍1入。这即是计算机中部分浮点数运算时出现误差,丢失精度的根本原因。大整数的精度丢失和浮点数本质上是一样的,尾数位最大是 52 位,因此 JS 中能精准表示的最大整数是 Math.pow(2, 53),十进制即 9007199254740992。大于 9007199254740992 的可能会丢失精度: 9007199254740992 >> 10000000000000...000 // 共计 53 个 09007199254740992 + 1 >> 10000000000000...001 // 中间 52 个 09007199254740992 + 2 >> 10000000000000...010 // 中间 51 个 0实际上: 9007199254740992 + 1 // 丢失 9007199254740992 + 2 // 未丢失9007199254740992 + 3 // 丢失9007199254740992 + 4 // 未丢失结果如图: // 0.1 + 0.2(0.1*10 + 0.2*10) / 10 == 0.3 // true6. 运算符6.1 一元运算符
递增 "++" 和 递减 "--" 还分为前自增或后自增,前自减或后自减,两种自增自减的运算结果是不一样的;
var num = 5;console.log(num++); // 5 console.log(++num); // 7 (因为刚刚num自增了一次,这里打印的话就等于在6的基础上前自增了,在计算机科学中,被称为副效应)console.log(num--); // 7 (这里是后自减,所以先返回值,返回7,再运算--,此时的num实际是等于6了)console.log(--num); // 56.2 逻辑运算符
/*细读上面三句话,就能理解为什么会是这个打印结果了*/console.log(true && true); //trueconsole.log(false || false); //falseconsole.log(null && undefined); //nullconsole.log(null || undefined); //undefinedconsole.log("abc" && undefined); //undefinedconsole.log("abc" || undefined); //abcconsole.log(null || false || 0 || 1 || null); //1console.log("abc" && "bcd" && "def"); //def6.3 运算符的优先级
// 第一题 true && trueconsole.log(((4 >= 6) || ("人" != "狗")) && !(((12 * 2) == 144) && true)); // true// 第二题 var num = 10;// true && trueif(5 == num / 2 && (2 + 2 * num).toString() === "22") { console.log(true); // true}else{ console.log(false);}7. 选择语句7.1 if..else语句语法:只有一个判断条件的时候 if..else: if(判断条件){ // 当判断条件为true的时候执行代码1,为false的时候执行代码2 代码1; }else{ 代码2;}当不止一个判断条件的时候 else用else if 代替: if(判断条件1){ // 判断条件 1 为 true 的时候执行 代码 1 代码1; }else if(判断条件2){ // 判断条件 2 为 true 的时候执行 代码 2 代码2; }else{ // 两个条件都不满足的时候执行代码 3 代码3; }思考1:
var age = 20;if(age >= 18){ console.log("没时间解释了,赶紧上车吧"); // 打印这条}else if(age >= 16){ console.log("请在家长的陪同下观看");}else { console.log("回家学习吧");}思考2:
var date = new Date(); // 获取当前的时间var week = date.getDay(); // 获得 0-6 表示周几 0:星期日if(week == 0){ console.log("今天是星期天");}else if(week == 1){ console.log("今天是星期一");}else if(week == 2){ console.log("今天是星期二");}else if(week == 3){ console.log("今天是星期三");}else if(week == 4){ console.log("今天是星期四");}else if(week == 5){ console.log("今天是星期五");}else if(week == 6){ console.log("今天是星期六");}else{ console.log("你火星的来的吧");}7.2 switch..case语法: // switch: 开关; case: 案列;switch(变量){ // 判断变量是否全等于case的值1,或者值2, case 值1: 执行代码1; // 全等于的时候执行代码1 break; // 然后break;代码跳出switch语句, 不加break,会继续执行下面的代码 case 值2: 执行代码2; break; default: 执行代码3; // 当都不满足条件的时候,会执行默认里的执行代码3}思考:素质教育(把分数变成ABCDE) // 90-100 : A// 80-89: B// 70-79: C// 60-69: D// 0-59 : E// 这里的等级是根据一个范围的分数划定的,用if..else很容易实现,但是switch..case是一个具体的条件,怎么办呢?// 方法:将分数除以10再用parseInt属性取整 var score = 85;score = parseInt(score/10); // 8switch (score) {// score = 10 或者 9 的时候 返回 Acase 10:case 9: console.log("A"); break;// score = 8 的时候 返回 Bcase 8: console.log("B"); break;case 7: console.log("C"); break;case 6: console.log("D"); break;default: console.log("E");}7.3 三元运算符 这个运算符可以用来代替if..else条件判断。但是为什么有这个运算符呢?这里的原因是if..else使用两个代码块,却只有一个会执行,在讲究的程序员看来是一种浪费。所以使用三元运算符,用一条语句就可以完成功能。语法: 判断语句?表达式1:表达式2; 根据判断语句返回的布尔值,true的话,返回表达式1,false的话返回表达式2举个例子,看代码: var sex = 1;sex == 1 ? "男":"女"; // 判断sex是否等于1,如果true,返回第一个表达式:"男"例题:判断两个数的大小 // 用if..else语句解决// 这里使用了两个代码块,有点浪费var num1 = 18;var num2 = 39;var max;if(num1>num2){ max = num1;}else{ max = num2;}console.log(max);// 用三元运算符var num3 = 28;var num4 = 49;var max1 = num3>num4? num3:num4;console.log(max1);注意(容易出错的地方): 下面这个语句判断如果是会员,费用为2美元,非会员,为10美元。现在设置了非会员,却打印出了2美元,显然出错了。 var isMember = false;console.log("当前费用" + isMember ? "$2.00" : "$10.00"); // "$2.00" 出错的原因是?号的优先级比+号低,所以实际运行的语句是 // trueconsole.log("当前费用false" ? "$2.00" : "$10.00"); // "$2.00"8.循环语句8.1 while 循环语法:
// 1. 如果循环条件的结果是true的时候,就会执行循环体// 2. 如果循环条件的结果是false的时候,结束循环。while(循环条件){ 循环的代码; // 循环体 自增或者自减; // 一定不要忘记自增或自减,否则就会死循环}例如,求0~100的和: var num = 0;var sum = 0;while(num <= 100){ sum += num; num++;}console.log(sum); // 50508.2 do..while 循环语法:
do{ 循环的代码; // 循环体 自增或者自减; // 一定不要忘记自增或自减,否则就会死循环}while(循环条件);例如,求0~100的和: var num = 0;var sum = 0;do{ sum += num; num++;}while(num<=100);console.log(sum); // 50508.3 for 循环 写while循环的经常会忘记自增,for循环其实是while循环演化过来的,语法更加的简洁明了,使用非常的广泛。语法:
//主要for循环的表达式之间用的是;号分隔的,千万不要写成,号for(初始化表达式;判断表达式;自增表达式){ //循环体}例如:求0~100的和: var sum = 0;for(var num = 0; num <= 100; num++){ sum += num;}console.log(sum); // 50508.4 break 和 continue break:立即跳出整个循环,即循环结束,开始执行循环后面的内容(直接跳到大括号)continue:立即跳出当前循环,继续下一次循环(跳到i++的地方)1、continue 示例代码: for(var i = 1; i <= 10; i++) { if(i == 5) { continue; } console.log(i); // 1,2,3,4,6,7,8,9,10}2、break 示例代码: for(var i = 1; i <= 10; i++) { if(i == 5) { break; } console.log(i); // 1,2,3,4}8.5 循环语句练习1、计算一个数的位数当不知道循环次数的时候,用while循环: var num = 1234567;//因为不知道循环次数,所以推荐使用while循环var count = 0; // count记录位数while(num != 0){ // 循环条件 num = parseInt(num/10);// 让num缩小10倍 count++; // ,每缩小10倍就计算一次位数了}console.log(count); // 72、翻转一个数 var num = 12345678;//因为不知道循环次数,所以推荐使用while循环var str = ""; while(num != 0){ str += num%10; // 将每一位取余 num = parseInt(num/10);//让num缩小10倍}// str 是一个字符串,所以 +str将它转回Number类型console.log(+str); //3、总结:
所谓数组,就是将多个元素(通常是同一类型的),按一定顺序排列放到一个集合中,那么这个集合就称之为数组在javascript中,数组是一个有序的列表,可以在数组中存放任意的数据,并且数组的长度可以动态的调整9.1 创建数组1、通过构造函数创建数组:
数组是有序的,数组中的每一个元素都对应了一个下标,下标是从0开始的 var arr = ["aa","bb","cc"];arr[0]; // 下标是0,对应的值是"aa"arr[2]; // 下标是2,对应的值是"cc"数组的长度: 跟字符串一样,数组也有一个length的属性,指数组中存放的元素的个数 var arr = ["aa","bb","cc"];arr.length; // 数组的长度为3空数组的长度为0数组的长度与下标的关系:数组的最大下标 = 数组的长度 - 19.3 数组的赋值与取值数组的取值:
var arr = ["red","blue","green"];arr[0]; // redarr[2]; // greenarr[3]; // 返回undefined,因为数组最大的下标为2数组的赋值:
var arr = ["red", "green", "blue"];arr[0] = "yellow"; // 把red替换成了yellowarr[3] = "pink"; // 给数组新增加了一个pink的值arr[5] = "black"; // 数组输出为["red", "green", "blue",empty,empty,"black"]9.4 数组的遍历 遍历: 对数组的每一个元素都访问一次,叫做遍历数组遍历的基本语法: var arr = [1,2,3,4,5,6,7,8,9];for(var i = 0; i < arr.length; i++){ console.log(arr[i]); // 1 2 3 4 5 6 7 8 9 }数组遍历的逆向遍历语法: // i= arr.length-1 ==> 表示初始化表达式 从数组最后一位开始遍历// i>=0 表示判断条件,下标要满足大于等于0// i--,表示每次遍历 初始值都是自减的var arr = [1,2,3,4,5,6,7,8,9];for(var i = arr.length-1; i >= 0; i--){ console.log(arr[i]); // 9 8 7 6 5 4 3 2 1}9.5 数组综合练习1、求一个数组中的最大值、最小值以及对应的下标 var arr = [298, 1, 3, 4, 6, 2, 23, -88,77,44];var max = arr[0]; // 随机取数组中的一个值与其他值比较var maxIndex = 0; // 初始化最大值的下标var min = arr[0];var minIndex = 0;for(var i = 0; i< arr.length; i++){ if(max < arr[i]){ // 用一开始选择的值,与遍历后的值进行比较 max = arr[i]; // 当后面的值比初始值大,就将后面的这个值赋值给初始值,再用这个全新的值再v 去与后面的比较 maxIndex = i; // 比较结束后,此时的索引就是最大值的索引 } if(min > arr[i]){ min = arr[i]; minIndex = i; }}console.log("最大的值是:" + max);console.log("最大值的下标是:" + maxIndex);console.log("最小的值是:" + min);console.log("最小值的下标是:" + minIndex);2、让数组倒序保存到一个新的数组中需要了解数组的一个方法 push,在数组的最后面添加 var arr = ["大乔", "小乔", "甄姬", "不知火舞"];var newArr = [];for (var i = arr.length - 1; i >= 0; i--) { newArr.push(arr[i]);}console.log(newArr); // ["不知火舞", "甄姬", "小乔", "大乔"]3、将字符串数组用"|"或其他符号拼成一个字符串 var arr = ["aa","bb","cc","dd"];var str = "";for(var i = 0; i<arr.length; i++){ if(i == arr.length-1){ str = str + arr[i]; // 判断一下,如果是最后一个的话就不用加“|” }else{ str = str + arr[i]+"|"; // str初始值是一个空字符串,遍历的时候需要加上前一次的结果 } }4、数组去重
var arr = [1, 1, 5, 7, 8, 3, 2, 5, 7, 2, 4, 6, 2, 5, 7, 2, 5];//定义一个新数组var newArr = [];//遍历需要去重的数组for (var i = 0; i < arr.length; i++) { //假设不存在 var flag = true; //需要判断arr[i]这个值是否在新数组中存在 for(var j = 0; j < newArr.length; j++){ //进行比较即可 if(arr[i] == newArr[j]){ //如果发现了相等的数,说明存在 flag = false; } } if(flag){ //如果假设成立,说明不存在 newArr.push(arr[i]); }}console.log(newArr);10. 冒泡排序10.1 冒泡排序的思路 一个有8位元素的数组,让它的第一位与后面每一位进行比较,前面一位小于后面的时候,位置不变,前面的大于后面的交换位置,就这样一共要比七趟(最后一趟不要比,就剩一位,就是最小的);实现原理如下图: var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6];var tang = 0;var ci = 0;for (var i = 0; i < arr.length - 1; i++) { // 外层for循环,循环的是比较的趟数,因为只要比较8趟 所以i判断的条件为length-1 tang++; for (var j = 0; j < arr.length - 1; j++) { // 内层for循环,循环的是比较的次数,每趟比较8次 ci++; if (arr[j] > arr[j + 1]) { // 判断比较的两个数,如果前面的大于后面的一位,交换位置 var temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } }}console.log("趟数:" + tang); // 8趟console.log("次数:" + ci); // 64次console.log(arr);}
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title></title></head><body> <span id="demo"></span><br/> <button id="stb">从小到大</button> <button id="bts">从大到小</button> <span id="show"></span> <script> var demo = document.getElementById("demo"); var show = document.getElementById("show"); var bts = document.getElementById("bts"); var stb = document.getElementById("stb"); var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; demo.innerHTML = arr; bts.onclick = function() { bubbleSort(function(a, b) { return b - a; }); } stb.onclick = function() { bubbleSort(function(a, b) { return a - b; }); } function bubbleSort(fn) { var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; var strArr = []; show.innerHTML = ""; strArr.push("<br/>"); var inner = 0; var outer = 0; for (var i = 0; i < arr.length - 1; i++) { strArr.push("第" + (i + 1) + "趟"); for (var j = 0; j < arr.length - 1; j++) { if (fn(arr[j], arr[j + 1]) > 0) { var tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } inner++; } strArr.push(arr.toString()); strArr.push("共" + j + "次" + "<br/>"); outer++; } strArr.push("外循环" + outer + "次"); strArr.push("内循环" + inner + "次"); show.innerHTML = strArr.join(" "); } </script></body></html> var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6];var tang = 0;var ci = 0;for (var i = 0; i < arr.length - 1; i++) { tang++; for (var j = 0; j < arr.length - 1 - i; j++) { // 第二趟只比了7次 依次递减 ci++; if (arr[j] > arr[j + 1]) { var temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } }}console.log("趟数:" + tang); // 8趟console.log("次数:" + ci); // 36次console.log(arr);i 是从下标0开始的,第一趟的时候i=0,比了8次,第二趟i=1,只需要比7次,第三趟i=2,只需要比6次...依次类推,所以 比的次数应该就是arr.length - 1 -i;测试代码: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title></title></head><body> <span id="demo"></span><br/> <button id="stb">从小到大</button> <button id="bts">从大到小</button> <span id="show"></span> <script> var demo = document.getElementById("demo"); var show = document.getElementById("show"); var bts = document.getElementById("bts"); var stb = document.getElementById("stb"); var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; demo.innerHTML = arr; bts.onclick = function() { bubbleSort(function(a, b) { return b - a; }); } stb.onclick = function() { bubbleSort(function(a, b) { return a - b; }); } function bubbleSort(fn) { var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; var strArr = []; show.innerHTML = ""; strArr.push("<br/>"); var inner = 0; var outer = 0; for (var i = 0; i < arr.length - 1; i++) { strArr.push("第" + (i + 1) + "趟"); for (var j = 0; j < arr.length - 1 - i; j++) { if (fn(arr[j], arr[j + 1]) > 0) { var tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } inner++; } strArr.push(arr.toString()); strArr.push("共" + j + "次" + "<br/>"); outer++; } strArr.push("外循环" + outer + "次"); strArr.push("内循环" + inner + "次"); show.innerHTML = strArr.join(" "); } </script></body></html>
var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6];var tang = 0;var ci = 0;for (var i = 0; i < arr.length - 1; i++) { var flag = true; // 假设每一次进来都排好了 tang++; for (var j = 0; j < arr.length - 1 - i; j++) { ci++; if (arr[j] > arr[j + 1]) { flag = false; // 如果两位比较还满足前面的比后面的大的时候,说明假设不成立 var temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } if (flag == true) { // 最后判断一下,如果假设推翻不了,就停止运行。 break; }}console.log("趟数:" + tang); // 4 趟console.log("次数:" + ci); // 26 次console.log(arr);当顺序已经排好后,就不用再去执行趟数了;测试代码: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title></title></head><body> <span id="demo"></span><br/> <button id="stb">从小到大</button> <button id="bts">从大到小</button> <span id="show"></span> <script> var demo = document.getElementById("demo"); var show = document.getElementById("show"); var bts = document.getElementById("bts"); var stb = document.getElementById("stb"); var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; demo.innerHTML = arr; bts.onclick = function() { bubbleSort(function(a, b) { return b - a; }); } stb.onclick = function() { bubbleSort(function(a, b) { return a - b; }); } function bubbleSort(fn) { var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; var strArr = []; show.innerHTML = ""; strArr.push("<br/>"); var inner = 0; var outer = 0; for (var i = 0; i < arr.length - 1; i++) { var sorted = true; strArr.push("第" + (i + 1) + "趟"); for (var j = 0; j < arr.length - 1 - i; j++) { if (fn(arr[j], arr[j + 1]) > 0) { var tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; sorted = false; } inner++; } strArr.push(arr.toString()); strArr.push("共" + j + "次" + "<br/>"); outer++; if (sorted) { break; } } strArr.push("外循环" + outer + "次"); strArr.push("内循环" + inner + "次"); show.innerHTML = strArr.join(" "); } </script></body></html> |