JS前置知识
什么是JS语言
javascript是一种运行在客户端 的脚本语言
客户端:即接受服务的一端,与服务端相对应,在前端开发中,通常客户端指的就是浏览器。
脚本语言:也叫解释型语言,特点是执行一行,解释一行,如果发现报错,代码就停止执行 。
javascript的三个组成部分:ECMAScript、BOM、DOM
ECMAScript:定义了javascript的语法规范。
BOM:一套操作浏览器功能的API。
DOM:一套操作页面元素的API。
script标签
书写Javascript代码有两种方式,第一种是直接在script标签中书写,第二种是将代码写在js文件中,通过script进行引入。
直接在script中书写javascript代码:
<script> alert("今天天气真好呀"); </script>
通过script标签引入一个JS文件,需要指定src属性
<script src="test.js"></script>
<font color="red">tips:如果script标签指定了src属性,说明是想要引入一个js文件,这个时候不能继续在script标签中写JS代码,即便写了,也不会执行。</font>
<script src = "test.js"> alert("Hello World"); //这段代码不会执行 </script>
script标签的书写位置,原则上来说,可以在页面中的任意位置书写script标签。
- 写在head标签中,style标签之后。
- 写在body结束标签的前面。
<body> <script> </script> </body>
- 写在html结束标签的后面,即页面的最后面。
<html> </html> <script> </script>
输入输出语句
在实际开发,基本不能使用3、4、5,因为用户体验不好。
- console.log 控制台输出日志
- document.write 往页面中写入内容
- alert 弹框警告
- confirm 确认框
- prompt 输入框
注释
不被程序执行的代码。用于程序员标记代码,在后期的修改,以及他人的学习时有所帮助,在JS中,分为单行注释、多行注释以及文档注释
//这是单行注释,只能注释一行 ? /* 这是多行注释,不能嵌套 */ ? ? //文档注释在JS中通常用于对函数进行说明 /** * 计算圆的面积 * @param r{number} 圆的半径 * @returns {number} 根据圆的半径计算出来的面积 */ function getArea(r) { return Math.PI * r * r; }
注释的作用:
1. 模块划分,方便代码查找和维护 2. 用于解释复杂代码的逻辑,方便维护和后期开发。
要求:写代码的时候必须要写注释,但是需要注意注释的合理性。
【永无bug.js】
变量
变量,可以变化的量,变量是在计算机中存储数据的一个标识符。可以把变量看成存储数据的容器。
变量与字面量:
字面量:10、20、“abc”、true这种从字面上就能看出来类型和值的量叫做字面量。
变量:可以变化的量。
变量的声明与赋值
1.变量可以同时声明并赋值。 2.先声明后赋值 3.不声明,直接赋值 4.既不声明,也不赋值 5.同时声明多个变量 //如果一个变量没有声明,而是直接赋值,这个变量是隐式全局变量,可以使用 // console.log(m); 如果一个变量没有声明,也没有赋值,直接使用会报错
【测试1.html】
变量的命名规则与规范
//一个变量,如果只声明,没有初始化,默认值是undefined
命名规则(必须遵守): 1.由字母、数字、下划线、$符号组成,开头不能是数字。 2.不能使用关键字和保留字 3.严格区分大小写 命名规范(建议遵守): 1. 命名要有意义 2. 遵守驼峰命名法。首字母小写,后面单词的首字母需要大写。
【测试2.html】
变量练习
1. 交换两个变量的值(掌握) 2. 不使用临时变量,交换两个数值变量的值(了解)
tips:javascript是一种弱类型语言,不管声明什么类型的变量,都是用var,并且变量的类型是可以变化的。
var age = 90; age = "张三";
数据类型
基本数据类型包括了:number、string、boolean、undefined、null
如何查看数据类型
使用typeof关键字查看数据类型
typeof name; typeof(name);
Number类型
进制
1. 十进制,我们平时使用的就是十进制,进行运算时,八进制和十六进制的值最终都会转换成十进制。 2. 八进制,0开头的数值,数值序列:0-7 3. 十六进制,0x开头的数值,数值序列:0-9A-F ? 进制了解即可,基本都是使用十进制,稍微了解一下进制之间的转换。 ? ? var a = 12 * "abc"; //Not a Number:不是一个数字 console.log(a); //NaN它不是一个单独的数据类型,而是数字类型的一个特殊值 var c = 12 / 0; console.log(c); //Infinity 正无穷 var d = - 12 / 0; console.log(d); //-Infinity 负无穷
浮点数
科学计数法:
var num = 5e+3; var num1 = 5e-2; //如何表示0.003和20000?
浮点数的精度问题:
0.1 + 0.2 = ? 0.07 * 100 = ?
浮点数在运算的时候会出现精度丢失的问题,因此在做比较运算的时候,尽量不要用小数进行比较。
数值范围
javascript不能表示世界上所有的数,因此在javascript中,数值大小是有一定限制的。
Number.MIN_VALUE :5e-324 Number.MAX_VALUE :1.7976931348623157e+308 Infinity :正无穷 -Infinity :负无穷
数值判断
1. NaN:表示一个非数值,当无法运算或者运算错误的时候,会得到一个NaN,NaN是number类型,表示一个非数值。 2. NaN不等于NaN 3. isNaN用来判断是否是一个数字,当返回true的时候,表示不是一个数字,返回false表示是一个数字。
【案例:计算用户的工资.html】
String类型
字面量
字符串的字面量:“abc” 、 ‘abc’ 字符串可以是双引号,也可以是单引号引起来。
思考:如何打印以下字符串。 我是一个"正直"的人 我很喜欢"传‘智‘播客"
字符串长度
length属性用来获取字符串的长度
var str = "abckjdlkfjd"; str.length;//字符串的长度
字符串拼接
拼接字符串使用+号
//思考: console.log(11 + 11); console.log("hello" + " world"); console.log("100" + "100"); console.log("11" + 11);
- 两边只要有一个是字符串,那么+就是字符串拼接功能
- 两边如果都是数字,那么就是算术功能。
boolean类型
boolean类型只有两个字面量,true和false,区分大小写。
所有类型的值都可以转化成true或者false
NaN、""、undefined、null、false、0 这6个值可以转换成false,其余的都是true。
undefined类型与null类型
undefined表示一个声明了没有赋值的变量 null表示一个空的对象。 表示对象不存在,用在引用数据类型 ? var a; //undefined是一个数据类型,它里面只有一个值,这个值就是undefined //1.如果声明了一个变量,但是没有对它进行赋值,那么它的值默认就是undefined console.log(a); //undefined ? //2.如果一个函数没有明确的返回值,那么它的返回值就是undefined ? undefined派生自null。 undefined == null -->true undefined === null -->false
类型转换
如何使用谷歌浏览器,快速的查看数据类型?
字符串的颜色是黑色的,数值类型是蓝色的,布尔类型也是蓝色的,undefined和null是灰色的,这个在调试过程中时非常有用的。
转换成字符串类型
- toString() var b=true; b=b.toString();
- String() var c=undefined d=string(c);
- 在数据的最后面加上空字符串(value+"") var a=12; a=a+"";
underfined和null没有toString方法
例如:var a = 12;? a = a + ""; //字符串和基本数据类型相加,得到的结果是一个字符串?
转换成数值类型
- Number() 会先从整体上查看一下这个字符串是否是一个合法的数字
- parseInt 会逐个字符进行转换,直到遇到非数字结束,parseInt不会保留小数位 int代表的是整数的意思
- parseFloat 会保留小数位
- +num, -0 让字符串和数字做除了加法以外的运算 等运算
转换成布尔类型
- Boolean
?
//将数字转换成为布尔值 0和NaN会被转换成为false
//将字符串转换成为布尔值,只有空字符串才会被转换成为false
//布尔值转换成为布尔值,false会被转换成为false
//undefined和null都会被转换成为false
//0、NaN、空字符串、false、undefined和null会转换成为false
?
- !!
//!是逻辑非运算.只要一个!就可以将数据转换成为boolean类型 //但是转换以后的boolean值和它含义不一致 //所以需要使用两个!来进行转换
运算符
赋值运算符
var a = 23; var b = a; a += 10;
算数运算符
var a = 1; console.log(a + 1); var a = 1; console.log(a - 1); var a = 1; console.log(a * 1); var a = 1; console.log(a / 1); var a = 10; console.log(a % 2); ? ? ? 比较运算符 == 只判断数据的内容,不判断类型 === 不仅判断内容还判断类型 ? var c = "13"; console.log(c < 50); //如果是数字和字符串进行比较运算,字符串会转换成为数字 //如果是两个字符串进行比较运算,它会按照字符出现的顺序来进行比较 ? ?
一元运算符
思考: var a = 1; var b = ++a + ++a; console.log(b); var a = 1; var b = a++ + ++a; console.log(b); var a = 1; var b = a++ + a++; console.log(b); var a = 1; var b = ++a + a++; console.log(b);
逻辑运算符
&&:只要有一个值为假,结果就是假。找假值 ||:只要有一个值为真,结果就是真。找真值 !:取反 ? (1)逻辑运算的短路问题: ? // 逻辑或运算短路问题:只要有一个运算数是true,后面的运算数就不再计算 // var m = a++; m = 1,a = 2; // console.log(a++ < 10 || a++ < 20); // true // console.log(a); //2 ? //逻辑且的短路问题:只要有一个运算数是false,后面的运算数就不再计算 //var m = a++; m = 1,a = 2; console.log(a++ > 20 && a ++ < 10); //false console.log(a); //2 (2)逻辑运算的取值问题: // 逻辑 或 运算取第一个为true的值 console.log(0 || undefined || 8 || "Hello" || false); //8 //如果所有的值都为false,取最后一个值 console.log(undefined || false || "" || null || 0); //0 //逻辑 与 运算取第一个为false的值 console.log(8 && "Hello" && 0 && false && undefined); //0 //如果所有的值都为true,取最后一个值 console.log(8 && "Hello" && 12 && true && "张三"); //张三 ? 思考: true && true; false || false; null && undefined null || undefined “abc” && undefined “abc” || undefined null || false || 0 || 1 || null “abc” && “bcd” && “def”
运算符的优先级
1. () 优先级最高 2. 一元运算符 ++ -- ! 3. 算数运算符 先* / % 后 + - 4. 关系运算符 > >= < <= 5. 相等运算符 == != === !== 6. 逻辑运算符 先&& 后||
思考:
//练习1 var a = true || false && true; var b = false || true && false; var c = true || false && false; ? //练习2 var a = true && false || false && true; var b = true && true || false && false; ? //练习3 ((4 >= 6) || ("人" != "狗")) && !(((12 * 2) == 144) && true) //练习4 var num = 10; if(5 == num / 2 && (2 + 2 * num).toString() === "22") { console.log(true); }
第二天
1.选择语句
1.1.if..else
if(判断条件){ 代码 //如果满足判断条件,才执行代码 }else{ 不满足判断条件时执行的代码 } if(condition) { statement1 } else if (condition) { statement2 } else { statement3 } ? //if...else语句,如果判断的区间有重合,小的区间要写到前面 //判断条件不能够连写,需要用 && 连接 ? 三元表达式: // 表达式 ? 表达成立时的取值 : 表达式不成立时的取值 var max = +num1 > num2 ? num1 : num2;
思考:
1. 是否年满18岁 2. 素质教育(把分数变成ABCDE)90-100 3. 判断星期几
1.2.switch..case
//语法 switch (expression) { case value: statement break; // break 关键字会导致代码执行流跳出 switch 语句 ? case value: statement break; default: statement } //switch (+num(此处前面的加号是为了转换成数字防止变成字符串)){ // case 0: // case 1: // case 2: // case 3: // case 4: // alert("Hello"); // break; // case 5: // case 6: // alert("嘿嘿"); // break; // default: // alert("呵呵呵呵"); // break; // }
思考:
var a = "10"; switch (a) { case 10: console.log("10"); case 20: console.log("20"); case 30: console.log("30"); default : console.log("haha"); }
思考2:
今天星期几
1.3.三元运算符
表达式1 ? 表达式2 : 表达式3 var sex = sex == 1 ? ‘男‘:‘女‘;
思考:
从两个数中找最大值
2.循环语句
在JavaScript中,循环语句有三种,while、do while和for循环。
2.1. while循环
基本语法:
//当满足循环条件时,执行循环体里的代码 //每执行完一次循环体的代码以后,再判断一下循环条件 //如果循环不成立时,结束循环 while(循环条件){ //循环体 } while(true){ //死循环,因为条件是true永远满足条件 alert("你的电脑中毒了"); } ? //让用户输入用户名密码。如果用户名不是admin密码不是888,就让用户重新输入 //用户名是 admin 并且 密码是888 //用户名不是admin 或者 密码不是888 var userName,password; while(userName != "admin" || password != "888"){ userName = prompt("请输入用户名"); password = prompt("请输入密码"); } //这个情况下里面的逻辑运算符一定要写||,否则会有bug
示例代码:
//计算1~100所有整数之和 var i = 0; //初始化变量,用来表示循环了多少次 var sum = 0; //初始化变量,用来记录和 ? //while语句的判断条件是i<=100,只要满足这个条件,就会一直执行循环体 while(i <= 100) { sum +=i; //循环体每次进来以后,都会在sum上进行叠加 i ++; //每次加完以后,让计数器自增 }
2.2. do...while循环
do...while循环和while循环语法类似,不同点在于,do...while循环里,循环体至少会被执行一次。
语法格式:
do{ //循环体 }while(判断条件);
思考:
使用do...while完成循环输入用户名密码案例。
2.3.for循环
for循环是最常用的语句之一,它可以很方便的让代码循环规定的次数。
语法格式:
for(初始化语句;条件判断语句;循环体执行完以后的语句){ //循环体 } ? //var num = 0; // while (num <= 100) { // console.log(num); // num ++; // } //先执行一次初始化语句,然后判断循环条件是否满足,如果满足就执行循环体的代码 //执行完循环体的代码以后,再执行num++这个代码 //再判断循环条件是否满足
示例代码:
var sum = 0; for(var i =0; i <= 100; i ++){ sum += i; }
思虑:
1.求1~100以内所有数的乘积 //var product = 1; //for(var i = 1; i <= 10; i++){ // product *= i; //} //console.log(product); 2.求1~100以内3的倍数之和。 // var sum = 0; // for (var i = 1; i <= 100; i++) { // //如果i是3的倍数,才把i加上 // if (i % 3 == 0) { // sum += i; // } // } // console.log(sum); 3.求1~100以内不能被7整除的数之和。 // var sum = 0; // for(var i = 1; i <= 100; i ++){ // if( i % 7 != 0){ // sum += i; // } // } // console.log(sum); 4.求1~100以内所有偶数之和。 // var sum = 0; // for (var i = 1; i <= 100; i++) { // //如果i是3的倍数,才把i加上 // if (i % 2 == 0) { // sum += i; // } // } // console.log(sum); 5.求1~100以内所有的偶数和所有的奇数之和。 // var oddSum = evenSum = 0; // for(var i = 1;i <= 100; i++){ // if(i % 2 != 0){ //代表的是奇数 // oddSum += i; // }else{ //代表的是偶数 // evenSum += i; // } // } // console.log("奇数之和"+ oddSum + ",偶数之和"+ evenSum); 6.打印矩形 for (var j = 0; j < 3; j++) { //外循环决定行数 for (var i = 0; i < 10; i++) { //内循环决定列数 document.write("*"); } document.write("<br>"); } document.write("<br>"); 7.打印三角形 正三角形 for(var i = 0; i < 10; i++){ //i = 0 1 2 3 4 for(var j = 0; j <= i; j++){ //j <= 0 document.write("*"); } document.write("<br>"); } document.write("<br>"); 倒三角形 for(var i = 5; i > 0;i--){ for(var j = 0; j < i; j++){ document.write("*"); } document.write("<br>"); } 8.打印九九乘法表。 document.write("<table width=‘1000‘>"); for (var i = 1; i < 10; i++) { //外循环控制行数 document.write("<tr>"); for (var j = 1; j <= i; j++) { document.write("<td>"); // document.write("(" + j + "," + i + ")"); document.write(j + " * " + i + " = " + (j * i)); document.write("</td>"); } document.write("</tr>"); } document.write("</table>"); 9.本金10000元存入银行,年利率是千分之三,每过1年,将本金和利息加作为新的本金。计算5年后,获得的本金是多少 var money = 10000; var rate = 0.003; //第一年 10000 * (1 + 0.003) //第二年 10000 * (1 + 0.003) * (1 + 0.003) //第三年 10000 * (1 + 0.003) * (1 + 0.003) * (1+0.003) for (var i = 0; i < 5; i++) { // money = money * rate + money; // money = money * (1 + rate); money *= (1 + rate); } 10.斐波那契数列指的是这样的一个数列:0、1、1、2、3、5、8、13、21... ... 即第n个数是前面两个数之和。求,当n=12时,对应的值。 var num1 = 1; var num2 = 1; var sum = 0; for(var i = 3;i <= 12; i++){ sum = num1 + num2; num1 = num2; num2 = sum; } console.log(sum);
2.4.break和countinue
break:立即跳出整个循环,即结束循环。
continue:结束当前循环,继续开始下一轮循环。
// break和continue后面的语句都不会执行
思考:
for(var i = 0;i <= 10; i++) { if(i == 5) { continue; } if(i == 8) { break; } console.log(i); }
练习:
1.求1~100之间不能被7整除的数之和 var sum = 0; for(var i = 1; i <= 100; i++){ // if( i % 7 != 0){ // sum += i; // } if(i % 7 == 0){ continue; } sum += i; } console.log(sum); 2.求200~300之间,所有奇数之和 sum = 0; for(var i = 200; i <= 300; i++){ // if(i % 2 != 0){ // sum += i; // } if( i % 2 == 0){ continue; } sum += i; } 3.求200~300之间,第一个能被7整除的数。 sum = 0; for(var i = 200; i <= 300; i++){ if( i % 7 == 0){ console.log(i); break; } //所有能被7整除的数 // if(i % 7 != 0){ // continue; // } // console.log(i);
2.5.断点调试
断点调试是指在代码中添加断点,当程序运行时到这一断点时就会暂停,可以让开发人员执行后续的操作(例如,查看变量值,单步运行查看代码流程等),可以很方便的让开发人员对代码进行调试。
调试步骤:
运行JS代码-->F12打开控制台-->Sources-->找到想要暂停的JS代码-->点击行号添加断点
调试中的相关技巧:
Watch:监视。通过Watch可以查看变量的值,非常实用。 F10:单步运程,程序执行到下一行代码。 F8:直接运行到下一个断点。如果程序中没有其它断点,程序就直接运行结束
tips: 不要随便监视表达式,如果监视了表达式,表达式会被执行
3.数组
所谓数组,就是将多个元素(通常是同一类型的数据)按照一定的顺序放到一个集合中,这个集合我们就称它为数组。
练习:
为什么要使用数组? 1.一个变量同时只能用来存储一个值,当我们需要存储多个值,如全班每个人的成绩时,就必须要用到数组了。 2.使用数组把同一类型的数据放到一个集合里,便于管理,同时操作起来也比较方便。
3.1.创建数组
数组是一个有长度且按照一定顺序排列的列表。在JavaScript里,数组的长度可以动态调整。
通过构造函数创建数组:
var arr1 = new Array(); //创建了一个空的数组,这个数组里没有数据 var arr2 = new Array(10); //创建了一个空的数组,但是指定了这个数组的长度是10 var arr3 = new Array(10,13,14); //创建了一个数组,并且在这个数组里放入了三个数字10,13,14
通过字面量来直接创建数组
var arr1 = []; //创建了一个空的数组 var arr2 = [12]; //创建了一个数组,并在这个数组里放入了一个数字12 var arr3 = ["ab","cd","ef"]; //创建了一个数组,并在这个数组里放入了三个字符串,注意使用逗号分隔
3.2.数组的长度与下标
数组的长度:和字符串一样,数组也有一个length属性,指数组中存储的数据的个数。
var arr = ["123","Hello",345,true]; arr.length; //数组的长度是4
数组的下标:数组是有序的,数组里的每一个元素都有对应的下标,我们可以通过下标很方便的拿到数组里的数据。注意:数组里的下标是从0开始的。
var arr = ["hello",1234,true,4567,"world"]; arr[3]; //取出的结果是4567 arr[10]; //下标超出了数组的长度,返回值是undefined
3.3.数组的取值与赋值
数组的取值:可以通过数组的下标,很方便的取出数组里对应位置上的值。
var arr = [12,34,23,78,3,1,9]; arr[3]; //将数组里的第3个元素78取出
数组的改值:通过数组的下标,也可以很方便的修改数组里对应位置上的值。
var arr = [34,23,5,8,120]; arr[2] = "Hello"; //将数组里第2个元素数字5改成了字符串"Hello" arr[8] = "World"; //在数组的第8个位置上插入了一个字符串"World"
练习:
1.将1~100以内所有的数都放到数组里 var arr = []; //var index = 0; for (var i = 1; i <= 100; i++) { //第一种方式:直接使用i来作为数组的下标 // arr[i - 1] = i; //第二种:定义一个index作为数组的下标 // arr[index] = i; // index ++; //第三种:使用arr.length作为数组的下标 // arr[arr.length] = i; //第四种:使用arr.push方法添加元素 arr.push(i); } console.log(arr); 2.将1~100以内所有的奇数放到数组里。 arr = []; for (var i = 1; i <= 100; i++) { if (i % 2 != 0) { //arr.push(i); arr[arr.length] = i; } } console.log(arr); 3.将1~100以内能被3整除的数放到数组里。 arr = []; for (var i = 1; i <= 100; i++) { if (i % 3 == 0) { arr[arr.length] = i; } } console.log(arr);
3.4.数组的遍历
遍历:将数组里的每一个元素都访问一次,就叫遍历一次数组。
数组遍历的基本语法:
for(var i = 0; i < arr.length; i ++) { //可以操作数组里的每一个元素 }
练习1:
var arr = [234,12,86,59,30,28,49,71]; 1.求数组中所有数据之和以及平均数。 var sum = 0; for (var i = 0; i < arr.length; i++) { sum += arr[i]; } var average = sum / arr.length; console.log("sum = " + sum + " ,average = " + average); 2.求数组里的最大数。 3.求数组里最大值和最小值所在的位置 4.求数组里的最大最小值以及它们所在的位置。 var max = arr[0]; //假设数组里的第0个元素是最大的数 var maxIndex = 0; //假设第0个元素是最大数 var min = arr[0]; var minIndex = 0; for(var i = 0; i < arr.length; i++){ if(arr[i] > max){ max = arr[i]; maxIndex = i; } if(arr[i] < min){ min = arr[i]; minIndex = i; } } console.log("max = " + max +",maxIndex = " + maxIndex + ",min = " + min + ",minIndex = " + minIndex);
练习2:
var arr = ["abc","def","Hello","Hi","World"]; 1.将字符串数组用|或其它符号分割 var str = ""; for (var i = 0; i < arr.length; i++) { // console.log(arr[i] + "|"); str += arr[i] + "|"; } console.log(str); 2.有一个字符串数组,求字符串数组中每项的长度,并把长度存入到一个新的数组里。 var newArr = []; for (var i = 0; i < arr.length; i++) { // newArr.push(arr[i].length); newArr[newArr.length] = arr[i].length; } console.log(newArr); 3.将数组中值为0的项去掉,将不为0的值存入一个新的数组 arr = [2, 4, 5, 0, 3, 7, 0, 1, 0, 5, 0]; newArr = []; for (var i = 0; i < arr.length; i++) { if (arr[i] != 0) { newArr.push(arr[i]); } } console.log(newArr); 4.让一个数组倒序保存到另一个数组里 newArr = []; for (var i = arr.length - 1; i >= 0; i--) { newArr.push(arr[i]); } console.log(newArr);
3.5.冒泡排序
使用冒泡排序将一个数组里的数据升序或降序进行排列。
var arr = []; for (var i = arr.length - 1; i >= 0; i--) { var flag = true; for (var j = 0; j < i; j++) { // document.write("(" + j +"," + (j +1) + ")"); document.write("(" + arr[j] + "," + arr[j + 1] + ")"); if (arr[j] > arr[j + 1]) { flag = false; // document.write("交换了" + flag); var tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } if (flag) { //说明已经排好了 break; } document.write("<br>"); } console.log(arr);
?
(扩充)交换两个变量的值 // var tmp = a; // a = b; // b = tmp; // console.log("a = " + a + " , b = " + b); // a = a + b; // a = 28, b = 15; // b = a - b; // b = 13, a = 28 // a = a - b; // a = 15, b = 13 //按位异或运算 // a = a ^ b; // b = a ^ b; // a = a ^ b; // console.log("a = " + a + " , b = " + b); // console.log(3 ^ 2 ^ 2); var x = 23456; var result = 1024 ^ x; console.log("加密以后的数字是" + result); console.log(result ^ x);
// a = [b, b = a][0]; // console.log("a = " + a + " , b = " + b);
?
第三天
1.函数
学习目标:掌握函数的基本用法,会使用函数解决一些问题。
1.1.函数的基础知识
1.1.1.为什么要使用函数
在写代码的时候,有一些常用的代码需要书写多次,如果直接复制粘贴的话,会造成大量的冗余代码,为了提高代码的重用率,提高编码效率,我们需要使用函数。函数可以用来封装一段重复的代码,只需要声明一次,就可以被多次调用。
冗余代码缺点:
1.代码重复,可阅读性差。
2.不易维护。一旦逻辑发生改变,所有的地方也都要修改。
1.1.2.函数的声明与调用
函数的声明:声明函数需要用到function关键字。
function 函数名(){ //函数体(函数的内容) }
特点:
1.函数在声明时不会执行,只有被调用时才会被执行。 2.函数一般用来做一件事,在对函数进行命名时一定要注意,做到顾名思义。
函数的调用:
函数名();
示例代码:
//声明一个函数 function sayHi(){ alert("吃了没"); } //调用函数 sayHi();
练习:
1.封装一个打招呼的函数 function sayHello() { console.log("Hello"); console.log("早上好"); console.log("吃了没"); } 2.封装一个函数,计算两个数的和 function getSum() { console.log(3 + 2); } getSum(); 3.封装一个函数,计算1~100之间所有数的和 function getTotal() { var total = 0; for(var i = 1; i <= 100; i++){ total += i; } console.log(total); } getTotal();
1.1.3.函数的参数
1.形式参数:在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的值。这个参数是一个不存在的变量,仅仅只是为了占用位置,所以我们可以称它为形式参数,简称形参。形式的值由调用者来传入
2.实际参数:在调用有参函数时,函数名后面括号中的参数被称为实际参数,实参可以是常量、变量或者表达式。
语法:
//有参函数在声明时,需要在函数名后的括号里写上形参 function 函数名(形参1,形参2,形参3...){ //函数体 } //调用有参函数,在函数名后面的括号里直接传入实际参数 函数名(实参1,实参2,实参3...);
练习:
1.计算1~n的数字之和 function getSum1(n) { var sum = 0; for(var i = 1; i <= n; i++){ sum += i; } } getSum1(20); 2.计算两个数的和 function getSum2(m,n) { console.log(m + n); } getSum2(4,5); 3.计算m~n之间数字之和 function getSum3(m,n) { var sum = 0; for(var i = m; i <= n; i++){ sum += i; } console.log(sum); } getSum3(2,100);
1.1.4.函数的返回值
很多情况下,调用者在函数执行完成以后,需要拿到函数执行的结果(比如,拿到两个数的和,拿到两个数的较大数等),这个返回的结果就叫做返回值。//return语句用来将结果返回给调用者
返回值语法:使用return关键字标识函数的返回值。
function 函数名(形参1,形参2,形参3...) { //函数体 return 返回值; //return关键字用来标识函数的返回值 } var result = 函数名(形参1,形参2,形参3...); //调用者定义一个变量,用来保存函数的返回值。
练习:
1.计算1~n之间所有数的和,并返回结果。 function getSum1(n) { var sum = 0; for(var i = 1; i <= n; i++){ sum += i; } //return语句用来将结果返回给调用者 return sum; } 2.计算两个数的和,并返回结果 function getSum2(m,n) { return m + n; } console.log(getSum2(4, 5)); 3.计算m~n之间所有数的和,并返回结果。 function getSum3(m,n) { var sum = 0; for(var i = m; i <= n; i++){ sum += i; } return sum; // console.log(sum); } var result = getSum3(2, 100); console.log(result);
1.1.5.函数三要素
函数的三要素指的是:
/在其它强类型语言里,比如Java,函数名、参数和返回值只要有一个不一样,那这就是两个不同的函数。函数名一样,参数或者返回值不一样,就叫函数重载 //但是在JS里,只要函数名一样,就是同一个函数。在JS里不允许函数重载
文档注释:文档注释/ ** */通常用在函数的声明中,用来解释这个函数的作用。(包括函数名,参数以及返回值的作用)
<font color="red">声明函数时,使用文档注释对函数进行说明,是一种良好的开发习惯</font>
/** * 求圆的面积 * @param r {number} 圆的半径 * @returns {number} 圆的面积 */ function getArea(r){ return Math.PI*r*r; } getArea(3);
练习:
1.根据半径计算圆的面积 function getArea(r) { return Math.PI * r * r; } var area = getArea(3); console.log(area); 2.根据半径计算圆的周长 /** * 根据计算周长 * @param r {number} 圆的半径 * @returns {number} 圆的周长 */ function getLength(r) { return Math.PI * 2 * r; } var length = getLength(2); 3.求两个数中的较大数。 function getMax(a, b) { return a > b ? a : b; } console.log(getMax(13, 5)); 4.求一个数组中的最大数。 function getArrMax(arr) { // var arr = [12,3,4,5,6]; var max = arr[0]; for (var i = 0; i < arr.length; i++) { if (arr[i] > max) { max = arr[i]; } } return max; } console.log(getArrMax([1, 23, 4, 5, 6, 7])); var arr = [34, 89, 76, 23, 45, 12]; console.log(getArrMax(arr)); 5.求一个数组中的最小数。 6.翻转一个数组,返回一个新的数组。 function reverseArray(arr) { var newArr = []; for (var i = arr.length - 1; i >= 0; i--) { newArr.push(arr[i]); } return newArr; } var array = reverseArray([123, 34, 56, 78, 9, 12]); console.log(array); 7.给一个数组进行倒序排序。 function bubbleSort(arr) { for (var i = arr.length - 1; i >= 0; i--) { var flag = true; for (var j = 0; j < i; j++) { if (arr[j] < arr[j + 1]) { // arr[j] = [arr[j + 1],arr[j+1] = arr[j]][0]; flag = false; var tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } if (flag) { break; } } return arr; } var arr = bubbleSort([9, 4, 5, 2, 3, 6, 7, 8]); console.log(arr);
1.2.函数的高级知识
1.2.1.函数调用
在函数内部是可以调用其它函数的
function fn1(){ console.log("fn1开始"); fn2(); //在函数fn1里调用了fn2函数 console.log("fn1结束"); } function fn2(){ console.log("fn2的代码"); console.log("fn2的代码"); console.log("fn2的代码"); } fn1();
断点调试:
1.F8:跳转到下一个断点 2.F10:单步运行(不会跳入到函数里) 3.F11:单步调试(跳入到函数里) 4.Shift+F11:跳出函数调用
练习:
1.求阶乘 function getJC(n) { var result = 1; for (var i = 1; i <= n; i++) { result *= i; } return result; } console.log(getJC(6)); 2.求阶乘的和 // 1! + 2! + 3! + 4! + ... + n! function getJCSum(n) { var sum = 0; for (var i = 1; i <= n; i++) { sum += getJC(i); } return sum; } console.log(getJCSum(4)); 3.求任意三个数的最大值。 // 3.求任意三个数的最大值。 // function getMax(a, b, c) { //第一种写法: // var d; // var result; // if(a > b){ // d = a; // }else{ // d = b; // } // // if( d > c){ // result = d; // }else{ // result = c; // } //第二种写法 // var d = a > b ? a : b; // var result = d > c ? d : c; // return result; //第三种写法 // return (a > b ? a : b) > c ? (a > b ? a : b) : c; // } function getMax1(a,b){ return a > b ? a : b; } function getMax2(m,n,p) { var x = getMax1(m,n); return getMax1(x,p); } console.log(getMax2(1, 4, 9));
1.2.2.函数参数与返回值详解
函数的参数详解:
1.在JavaScript中,没有函数重载,只有覆盖。如果定义了两个同名函数,后面的函数会覆盖掉前面的函数。
//即使前一个函数有参数,后一个函数没有参数 //此时调用的依然是后一个函数,而不是前一个函数 //如果函数不需要参数,而调用的时候又传入了一个参数 //这个传入的参数会被 “舍弃” 掉
2.在JavaScript中,实参的个数可以和形参的个数不一致。
- 如果实参的个数多于形参的个数,多余的实参会被舍弃。(并不是真正的舍弃,而是使用了一个变量对其进行了保存)
- 如果实参的个数少于形参的个数,不足的实参使用undefined替代。
函数返回值详解:
1.return 语句作为函数的返回,它后面的语句不会执行。 2.函数也可以没有return语句。如果一个函数没有明确的返回值,那么这个函数的返回值是undefined. 3.函数也可以直接return,而不给返回值,相当于return undefined.作用是用来结束函数的调用。
练习:
1.比较两个数据大小,返回更大的那个数。 2.求数组中的最大值和最大值所在的位置,并且返回。 function getMaxAndIndex(arr) { var max = arr[0]; //修改第0个元素是最大数 var maxIndex = 0; for(var i = 0; i < arr.length; i++){ if(arr[i] > max){ max = arr[i]; maxIndex = i; } } // return max; // return maxIndex; // return {maxIndex:max}; return [max,maxIndex]; } var result = getMaxAndIndex([12,34,5,6,90,345,234,1234,899]); console.log("最大数是" + result[0] + ",最大数所在的位置是" + result[1]);
1.2.3.函数的作用域
全局变量:在最外层声明的变量就是全局变量,全局变量在任何地方都能够被访问。
局部变量:在函数中声明的变量就是局部变量,局部变量只能在当前函数内能够被访问。
隐式全局变量:没有使用var声明的变量也是全局变量。
作用域:变量可以发挥作用的区域。
全局作用域:在script标签内,函数外定义的作用域就是全局作用域。在全局作用域中定义的变量是全局变量。
函数作用域:在函数中的区域叫做函数区域,在函数作用域中定义的变量就是局部变量,只能在当前函数中访问。
<font color="red">在函数中,只有全局作用域和函数作用域。在if、while、for等语句中定义的变量都是全局变量。 </font>
1.2.4.预解析
JS解析器在执行JS代码的时候,分为两个过程:预解析过程和代码执行过程。
预解析过程:
1.把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值。
2.把函数的声明提升到当前作用域的最前面,只会提升声明,不会提升调用。
3.先提升var,再提升function
思考:
console.log(a); function a(){ console.log("aaaaa"); } var a = 1; console.log(a);
面试题:
var num = 10; fn1(); function fn1(){ console.log(num); //undefined var num = 20; } ? var a = 18; fn2(); function fn2(){ var b = 9; console.log(a); underfined console.log(b); 9 } ? fn3(); console.log(c); //9 console.log(b); //9 console.log(a); //9 function fn3(){ a = b = c = 9; console.log(a); //9 console.log(b); //9 console.log(c); //9 } ? fn3(); console.log(c); //9 console.log(b); //9 console.log(a); //9 function fn3(){ var a = b = c = 9; console.log(a); //9 console.log(b); //9 console.log(c); //报错 因为预解析时把var=a提前了,到此处a没有被赋值所以报错了 }
1.2.5.声明函数的两种方式
函数声明(命名函数)
function 函数名(){ //函数体 }
函数表达式(匿名函数)
var 函数名 = function(){ //函数体 } ? 匿名函数的调用必须要写在函数表达式的后面
这两种函数的区别:
1.命名函数可以在声明之前调用,因为预解析时,会先把函数的声明给解析出来。
2.<font color="red">匿名函数的调用必须要放在声明之后</font>,因为预解析时,只会声明变量,不会给变量赋值!(DOM注册事件)
1.2.6.匿名函数
匿名函数:没有名字的函数
匿名函数的使用:
1.将匿名函数赋值给一个变量,通过变量名来调用函数。 var test = function(){ //将匿名函数赋值给一个变量 console.log("Hello"); } test(); //通过变量名来调用函数 2.匿名自调用函数。 (function(){ console.log("Hi"); })();
自执行函数的作用:防止全局变量污染。
第四天
1.对象
学习目标:1.会创建一个对象2.会定义一个构造函数3.会操作一个对象
1.1.对象的基本概念
1.1.1.为什么要有对象?
在JavaScript中,对象跟数组、函数一样,都是一种复杂的数据类型,也叫引用数据类型。是一系列相关的属性的集合,可以很方便的对变量和函数进行管理。
面向对象编程(Object Oritented P rogramming,简称OOP)是非常重要的软件编程思想。
1.1.2.什么是对象
现在生活中:万物皆对象,对象是一个具体的事物,一个具体的事物就会有行为和特征。
编程语言:在内存上一段有意义的区域被称为对象,它也可以具有相关特征(属性),执行具体的行为(方法)。
思考:
1. 女友对象 //特征:名字、性别、身高、体重、血型、星座、生日 //行为:吃饭、睡觉、拍电影、唱歌、发微博 2. 学生对象 //特征:名字、性别、身高、体重、分数 //行为:吃饭、睡觉、学习、敲代码 3. 英雄对象 //特征:名字、性别、金钱、等级、技能 //行为:移动、攻击、防御
1.2.创建对象
1.2.1.通过构造函数创建
var hero = new Object(); //创建一个空的对象 hero.name = "奥特曼"; hero.skill = "打怪兽"; hero.attack = function(){ console.log("奥特曼发出光波打败了小怪兽"); } hero.attack();
注意事项:
1.this一定要出现在方法中才有意义,不在方法中的this没有意义。(如果一个函数挂载在对象里作为它的属性则称这个函数为方法)0
2.在方法中出现的this,指的是当前对象,即调用这个方法的对象
? //this谁调用指的就是谁
? //this只能在函数内部使用才有意义
//在函数外部使用,"没有意义"
1.2.2.对象字面量
//对象也可以理解为一个以键值对形式存在的无序集合
var person = { name : "迪伽", age : 2000, sex : "男"; fight : function(){ console.log("打怪兽"); } }; console.log(person.name); //"迪迦" 通过点可以获取到对应的值 person.fight(); //只有如此上面的额“打怪兽才能被打印出来”
1.3.批量创建对象
1.3.1.使用普通函数创建对象
优点:可以同时创建多个对象
缺点:创建出来的没有具体的类型,都是Object类型的对象。
function createTeacher(name,age,height) { var teacher = new Object(); teacher.name = name; teacher.age = age; teacher.height = height; return teacher; } var teacher1 = createTeacher("苍老师",30,165); var teacher2 = createTeacher("许老师",35,170); var teacher3 = createTeacher("姜老师",18,180);
1.3.2.查看一个对象的类型
1. typeof 只能判断基本数据类型 var arr = new Array(1,2,3); console.log(typeof arr); //object 2. instanceof 判断对象的数据类型 console.log(arr instanceof Array); //只用于判断 (true/false) 3. constructor.name 也可以获取到对象的具体类型 //调用arr的constructor.name属性,拿到arr的数据类型 //constructor指的是构造器(构造函数) console.log(arr.constructor.name); //Array console.log(teacher1.constructor.name); //Object
1.3.3.构造函数
构造函数,是一种特殊的函数,主要用来在创建对象时就给对象初始化,即为对象的成员变量赋值,总与关键字new一起使用在创建对象的语句中。
关键字new所做的操作:
1.new会创建一个新的空对象 2.new会让this指向这个对象 3.调用构造函数 4.new会返回这个创建好的对象
练习:
1.学生对象的构造函数 var student = new Object; 2.老师对象的构造函数 3.英雄对象的构造函数
1.4.操作对象的属性
1.4.1.点语法
#//获取对象属性 //对象.属性 获取对象的某个属性 //1.如果这个对象有这个属性,就返回所对应的属性值 //2.如果这个对象没有这个属性,则返回undefined var name = teacher.name; //获取到老师对象的姓名属性 teacher.name = "苍老师"; //将老师对象的姓名设置成为苍老师 ? # //设置对象属性 //对象.属性 = 值 //1.如果对象有这个属性,修改这个属性的值 //2.如果对象没有这个属性,则给这个对象添加一个新属性 var name = teacher["name"]; //获取到老师对象的姓名属性 teacher["name"] = "苍老师"; //将老师对象的姓名设置成为苍老师
1.4.2.[]语法
也叫关联数组方式,说白了就是把对象当作数组来看待。
//获取对象属性值 //对象["下标"] 把对象的属性当成是数组里的元素 (下标即属性) //设置对象属性 //对象["下标"] = 值
//注意:<font color="red">如果使用一个变量来获取对象里的属性时,必须要使用[]语法。</font>
function Student(name,age){ this.name = name; this.age = age; } var stu = new Student("张三",18); var tmp = "name"; var name = stu.tmp; //undefined,在stu对象里找tmp属性 name = stu[tmp]; //张三,这里的tmp是一个变量,它指的是"name"字符串
1.4.3.遍历对象
使用for..in循环可以遍历一个对象里的数据
var obj = {"name":"张三","age":18,"sex":"男"}; for(var x in obj){ console.log(obj[x]); }
1.5.基本数据类型与引用数据类型
基本数据类型:也叫简单数据类型,原始数据类型或者值类型。在存储时,变量存的就是值本身。
引用数据类型:也叫复杂数据类型。在存储时,变量中存储的仅仅是地址(引用)。
练习1:
//1. var num1 = 10; var num2 = num1; num1 = 20; console.log(num1); //20 console.log(num2); //10 //2. var num = 50; function fn1(num) { num = 60; console.log(num); //60 } fn1(num); console.log(num); //50 //3. var num1 = 55; var num2 = 66; function fn2(num,num1) { //var num=num; //var num1=num1; num = 100; num1 = 100; num2 = 100; console.log(num); //100 console.log(num1); //100 console.log(num2); //100 } fn2(num1,num2); console.log(num1); //55 console.log(num2); //100 console.log(num); //报错 全局作用域中没有定义这个变量
练习2:
//1. function Person(name, age) { this.name = name; this.age = age; } var p1 = new Person("zs", 18); var p2 = p1; p2.name = "ls"; console.log(p1.name); //ls console.log(p2.name); //ls //2. function Person(name, age) { this.name = name; this.age = age; } function f1(p) { p.name = "ls"; console.log(p.name); //ls } var p1 = new Person("zs", 18); console.log(p1.name); //zs f1(p1); console.log(p1.name); //ls
练习3:
//1. function f1(a, b) { a = a + 1; b = b + 1; console.log("a = " + a); //6 console.log("b = " + b); //7 } var x = 5; var y = 6; f1(x, y); console.log("x = " + x); //5 console.log("y = " + y); //6 //2. function Person(name, age) { this.name = name; this.age = age; } function f2(p) { p = new Person("ls", 50); p.name = "ww"; console.log(p.name); //ww } var p2 = new Person("zs", 18); f2(p2); console.log(p2.name); //zs //3. function f3(arr) { arr[0] = 100; } var array = [1, 2, 3]; f3(array); console.log(array); //100 2 3 //4.冒泡排序的函数中,是否可以不返回数组? var array = [4,3,9,8,5,7,1,2,0,6]; function bubbleSort(arr){ for(var i = arr.length - 1; i >=0; i--){ var flag = true; for(var j = 0; j < i; j++){ if (arr[j] > arr[j + 1]){ flag = false; arr[j] = [arr[j + 1],arr[j + 1] = arr[j]][0]; } } if(flag){ break; } } } bubbleSort(array); console.log(array);
第五天
内置对象
JS内置对象就是指Javascript自带的一些对象,供开发者使用,这些对象提供了一些常用的的功能。
常见的内置对象有Math、String、Array、Date等
内置对象有很多,我们主要是记下这些内置对象的用法即可。但是同学们也不可能一下子记住这么多的方法,因此当同学们忘了某个方法该如何使用的时候,可以通过以下方式查看。
- 跳转到定义
ctrl+左键
- 火狐开发者网站MDN
- W3School网站
- 离线文档
- 笔记
Math对象
Math对象中封装很多与数学相关的属性和方法。
- 属性PI
Math.PI
- 最大值/最小值
Math.max(); Math.min();
- 取整
1. Math.ceil();//天花板,向上取整 var b = 123.056; console.log(Math.ceil(b)); // 124 ceil 向上取整 ? 2. Math.floor();//地板,向下取整 var a = 123.789; console.log(Math.floor(a)); //123 floor是向下取整 a = -123.08; console.log(Math.floor(a)); //-124 ? 3. Math.round();//四舍五入,如果是.5,则取更大的那个数 var c = 123.456; console.log(Math.round(c)); //123 c = 23.89; console.log(Math.round(c)); //24
- 随机数
Math.random();//返回一个[0,1)之间的数,能取到0,取不到1 ? //生成 [0,100]的随机数 // parseInt(Math.random() * 101); console.log(Math.round(Math.random() * 100)); // //[50,100] --> [0,50] Math.round(Math.random() * 50) + 50; //[50,100] //[32,89] -->[0,57] Math.round(Math.random() * 57) + 32;
- 绝对值
Math.abs();//求绝对值 ? console.log(Math.abs(-234)); //234 取绝对值
- 次幂和平方
Math.pow(num, power);//求num的power次方 // Math.pow(2, 3); //8 2的3次方 ? Math.sqrt(num);//对num开平方 // Math.sqrt(4);//2 对4开平方
sin cos
// console.log(Math.sin(30)); 参数是弧度,而不是角度 PI弧度 = 180角度
console.log(Math.sin(Math.PI / 6)); //sin(30)
console.log(Math.cos(Math.PI / 6)); //cos(30)
console.log(Math.tan(Math.PI / 2)); //不存在 // console.log(Math.sin(30)); 参数是弧度,而不是角度 PI弧度 = 180角度 console.log(Math.sin(Math.PI / 6)); //sin(30) console.log(Math.cos(Math.PI / 6)); //cos(30) console.log(Math.tan(Math.PI / 2)); //不存在
## Date对象 > Date对象用来处理日期和时间 - 创建一个日期对象 ```javascript var date = new Date();//使用构造函数创建一个当前时间的对象 var date = new Date("2017-03-22");//创建一个指定时间的日期对象 //如果只给日期,不给时间,默认时间是世界标准时00:00:00 var date = new Date("2017-03-22 00:52:34");//创建一个指定时间的日期对象 //如果给日期,又设置时间,这个时间代表的是当地时区的时间 // console.log(+date); //1490115154000 (转换成毫秒) var date1 = new Date(1490115154000); // 从1970年1月1日0时起的毫秒数 console.log(date1); //Wed Mar 22 2017 00:52:34 GMT+0800 (中国标准时间)
- 日期格式化(了解)
date.toString();//默认的日期格式 date.toLocalString();//本地风格的日期格式(兼容性) date.toDateString(); date.toLocalDateString(); date.toTimeString(); date.toLocalTimeString();
- 获取日期的指定部分
getMilliseconds();//获取毫秒值 getSeconds();//获取秒 getMinutes();//获取分钟 getHours();//获取小时 getDay();//获取星期,0-6 0:星期天 getDate();//获取日,即当月的第几天 getMonth();//返回月份,注意从0开始计算,这个地方坑爹,0-11 *getFullYear();//返回4位的年份 如 2016 getYear(); //将返回的实际年份减去1900年。例如:2016年返回116 ? //Coordinated Universal Time,协调世界时,又叫世界标准时间。可以理解为0度经线所在有时区。 getUTCYear(); //返回标准时间对应的年份 getUTCHour(); //返回标准时间对应的小时 ? 例题: //现在时间:2017年08月12日,星期六,北京时间 10:33:45 var date = new Date(); var year = date.getFullYear(); var month = getNumber(date.getMonth() + 1); // if (month < 10) { // month = "0" + month; // } var riqi = getNumber(date.getDate()); // if (riqi < 10) { // riqi = "0" + riqi; // } var day = date.getDay(); switch (day) { case 0: day = "日"; break; case 1: day = "一"; break; case 2: day = "二"; break; case 3: day = "三"; break; case 4: day = "四"; break; case 5: day = "五"; break; case 6: day = "六"; break; } var hour = getNumber(date.getHours()); var minutes = getNumber(date.getMinutes()); var seconds = getNumber(date.getSeconds()); console.log("现在时间:" + year + "年" + month + "月" + riqi + "日,星期" + day + ",北京时间" + hour + ":" + minutes + ":" + seconds); ? function getNumber(a){ // if(a < 10){ // return "0" + a; // } // return a; return a < 10 ? ("0" + a) : a; }
//思考: //封装一个函数,返回当前的时间,格式是:yyyy-MM-dd HH:mm:ss
- 时间戳
var date = +new Date();//1970年01月01日00时00分00秒起至现在的总毫秒数
//思考 //如何统计一段代码的执行时间?
var start = +new Date(); for (var i = 0; i <= 10000; i++) { console.log(i);
} var end = new Date();
console.log("代码执行的时长是" + (end - start) + "毫秒");
Array对象 > 数组对象在javascript中非常的常用 - 数组判断 ```javascript //语法:Array.isArray(obj) //作用:用来判断一个对象是否是一个数组 var a = 100; var b = true; var c = [1,2,3,4,5,6]; console.log(Array.isArray(a)); //false console.log(Array.isArray(b)); //false console.log(Array.isArray(c)); //true console.log(a instanceof Array);(也可用于判断) function printElement(arr) { if(!Array.isArray(arr)){ return false; } for(var i = 0; i < arr.length; i++){ console.log(arr[i]); } return true; } var result = printElement(d); console.log("result = " +result);
- 数组转换
//语法:array.join(separator) //作用:将数组的值拼接成字符串 ? var arr = [1,2,3,4,5]; arr.join();//不传参数,默认按【,】进行拼接 arr.join("-");//按【-】进行拼接
- 数组的增删操作
array.push();//从后面添加元素,返回新数组的length array.pop();//从数组的后面删除元素,返回删除的那个元素 array.unshift();//从数组的前面的添加元素,返回新数组的长度 array.shift();//从数组的最前面删除元素,返回删除的那个元素 ? //练习1 var arr = ["刘备"]; //添加数据后变成:["赵云","马超","刘备","关羽","张飞"] arr.unshift("赵云", "马超"); arr.push("关羽", "张飞"); console.log(arr); ? //删除数据后变成:["关羽","张飞"] arr.shift(); arr.shift(); arr.shift(); console.log(arr);
//练习2 var arr = ["赵云","马超","刘备","关羽","张飞"]; //把数组的最后一个元素变成数组的第0个元素
var last = arr.pop(); //张飞 arr.unshift(last); arr.unshift(arr.pop()); console.log(arr);
//把数组的第0个元素变成数组的最后一个元素
var last = arr.pop(); //拿到最后一个 arr = "赵云", "马超", "刘备", "关羽" var first = arr.shift(); //拿到第0个 arr = "马超", "刘备", "关羽" arr.unshift(last); // arr = "张飞","马超", "刘备", "关羽" arr.push(first); // arr = "张飞","马超", "刘备", "关羽","赵云" console.log(arr);
- 数组的翻转与排序 ```javascript #array.reverse();//翻转数组 另一种方法翻转数组 // var newArray = []; // for(var i = arr.length - 1; i >= 0; i--){ // newArray.push(arr[i]); // } // console.log(newArray); #array.sort();//数组的排序,默认按照字母顺序排序 //sort方法可以传递一个函数作为参数,这个参数用来控制数组如何进行排序 arr.sort(function(a, b){ # //如果返回值>0,则交换位置 return a - b; });
//练习: //将[3, 6, 1, 5, 10, 2,11]从小到大排列 arr.sort(function (a,b) { return a - b; }) console.log(arr); ? //将字符串数组按照字符长度从小到大排列 arr = ["Hello","Hi","好","World","ITHeima","ShangHai","Beijing"]; arr.sort(function (a,b) { // console.log("a = " + a + " , b = " + b); return a.length - b.length; //按照元素的长度进行升序的排序 }); console.log(arr); ? //将学生数组按照年龄从小到大排列 arr = [ {name:"张三",age : 18}, {name:"李四",age : 14}, {name:"王五",age : 20}, {name:"赵四",age : 19}, {name:"刘能",age : 21}, {name:"谢飞机",age : 30}, {name:"赵本山",age : 68}, ]; arr.sort(function (a,b) { return a.age - b.age; }); console.log(arr);
- 数组的拼接与截取
# //concat: 数组合并,不会影响原来的数组,会返回一个两个数组合并后的新数组。 var newArray = array.concat(array2); ? # //slice: 数组切分,复制数组的一部分到一个新数组,并返回这个数组 返回值是截取的那一部分元素组成的数组(slice方法只有是从原有数组的基础上复制一部分元素生成一个新的数组) //原来的数组不受影响,包含begin,不包含end //第一个参数表示开始截取的下标;第二个参数表示结束截取的下标 var newArray = array.slice(begin, end); ? # //splice: 数组拼接,以新元素来替换旧元素,以此来修改数组的内容,常用于删除数组的某些项(需要两个以上参数) //start:开始位置 deleteCount:删除的个数 items:替换的内容 第二个以后的参数,表示删除以后,再向数组里插入的数据 array.splice(start, deleteCount, [items]); ? //在数组第5个元素前面,删除0个,再插入一个元素250 var arr = [3,4,5,6,7,8,0,2,1,9]; arr.splice(5,0,250); console.log(arr);
//练习: var arr = [4, 6, 7, 8, 3, 46, 8]; //从数组中截取一个新的数组[6,7,8,3],返回新的数组 var newArry=arr.slice(arr[1],arr[4]); //删除[6,7,8,3]和替换成[1,1,1] var neaArry=arr.splce(arr[1],4,[1,1,1])
- 数组查找元素
#//indexOf方法 用来查找数组中某个元素第一次出现的位置,如果找不到,返回-1 #array.indexOf(search, [fromIndex]); var arr = [23,89,57,63,12,57,87]; var index = arr.indexOf(57); console.log(index);
lastIndexOf() 从后面开始查找数组中元素出现位置,如果找不到,返回-1 #array.lastIndexOf(search, [fromIndex]); index = arr.lastIndexOf(57); console.log(index);
// function getElementIndex(element,array){
// for(var i = 0; i < array.length;i++){ // if (arr[i] == element){ // return i; // } // } // return -1; // } // var index = getElementIndex(157,arr); // console.log(index);
- 操作数组里的元素 ```javascript #//filter方法 //返回一个由符合函数要求的元素组成的新数组,不改变原数组 (只是在原有数组的基本上过滤一部分数据组成一个新的数组,会把数组进行一次遍历) var arr = [12,34,56,89,78,23,45,19]; //调用数组的filter方法,添加过滤方法,符合规则的元素会被存放到新数组里 #//element:表示数组里的元素;index:表示索引值;array:表示调用filter方法的数组。 var newArr = arr.filter(function(element,index,array){ return element > 30; }); console.log(arr); //filter方法不会改变原数组里的数据[12,34,56,89,78,23,45,19]; console.log(newArr); //新数组里保存符合要求的元素[34, 56, 89, 78, 45] #//map方法 让数组中的每个元素都调用一次提供的函数,将调用的后的结果存放到一个新数组里并返回。不会改变原有的数组 (只是相当于把原有的数组复制一份,再让复制后的数组里的每一个元素再执行一次map里的函数) # newArr = arr.map(function(element,index,array){ //在数组里的每一个元素的最后面都添加一个字符串"0" # return element + "0"; # }); console.log(newArr); //["120", "340", "560", "890", "780", "230", "450", "190"] console.log(arr); //map方法不会改变原数组里的数据 [12,34,56,89,78,23,45,19] #//forEach() 方法 对数组的每个元素执行一次提供的函数,且这个函数没有返回值 (没有返回值,不会生成一个新的数组,而且也不改变原有数组) var result = arr.forEach(function (element, index, array) { //数组里的每一个元素都会被打印 console.log("第" + index + "个元素是" + element); }); console.log(result); //函数没有返回值 #////some() 方法 测试数组中的某些元素是否通过由提供的函数实现的测试. result = arr.some(function (element,index,array) { //数组里否有一些元素大于50.只要有一个元素大于,就返回true console.log(element);//12,34,56 return element > 50; }); console.log(result); //true #//every() 方法 测试数组的所有元素是否都通过了指定函数的测试。 (数组里的每一个元素是否都满足条件。只要有一个不满足,就返回false) result = arr.every(function (element,index,array) { //数组里是否每一个元素都大于50.只有在所有的数都大于50时,才返回true console.log(element); //12.第0个数字就已经小于50了,就没有再比较的意义了 return element > 50; }); console.log(result); //false
- 清空数组
//1.array.splice(0,array.leng);//删除数组中所有的元素 //2.array.length = 0;//直接修改数组的长度 //3.array = [];//将数组赋值为一个空数组,推荐
- 数组综合练习
var arr = ["c", "a", "z", "a", "x", "a", "a", "z", "c", "x", "a", "x"] //1. 找到数组中第一个a出现的位置 console.log(arr.indexOf("a")); //2. 找到数组中最后一个a出现的位置 console.log(arr.lastIndexOf("a")); //3. 找到数组中每一个a出现的位置 for (var i = 0; i < arr.length; i++) { if (arr[i] == "a") { console.log("----" + i); } } //4. 数组去重,返回一个新数组 var newArr = []; for (var i = 0; i < arr.length; i++) { if(newArr.indexOf(arr[i]) == -1){ newArr.push(arr[i]); } } console.log(newArr); //5. 获取数组中每个元素出现的次数 for(var i = 0; i < arr.length; i++){ var element = arr[i]; //i = 0 --> {"c" : 1} //i = 1 --> {"c":1,"a":1} //i = 2 --> {"c":1,"a":1,"z":1} //i = 3 --> {"c":1,"a":2,"z":1} //i = 4 --> {"c":1,"a":2,"z":1,"x" : 1} //i = 5 --> {"c":1,"a":3,"z":1,"x" : 1} //i = 6 --> {"c":1,"a":4,"z":1,"x" : 1} //i = 7 --> {"c":1,"a":4,"z":2,"x" : 1} //i = 8 --> {"c":2,"a":4,"z":2,"x" : 1} //i = 9 --> {"c":2,"a":4,"z":2,"x" : 2} //i = 10 --> {"c":2,"a":5,"z":2,"x" : 2} //i = 11 --> {"c":2,"a":5,"z":2,"x" : 3} if(obj[element] == undefined){ obj[element] = 1; }else{ obj[element] ++; } } console.log(obj);
String对象
字符串可以看成是一个字符数组。因此字符串也有长度,也可以进行遍历。String对象很多方法的名字和和Array的一样。可以少记很多的单词。
- 查找指定字符串
#//indexOf: 获取某个字符串第一次出现的位置,如果没有,返回-1 #//lastIndexOf: 从后面开始查找第一次出现的位置。如果没有,返回-1
- 去除空白
#trim(); //去除字符串两边的空格,内部空格不会去除
- 大小写转换
toUpperCase(); :全部转换成大写字母 //有返回值,返回值是变成大写以后的字符串不会改变原有的字符串 toLowerCase(); :全部转换成小写字母
- 字符串拼接与截取
#//字符串拼接 //可以用concat,用法与数组一样,但是字符串拼串我们一般都用+ var str1 = "Hello"; var str2 = "World"; console.log(str1 + str2); ? #//字符串截取的方法有很多,记得越多,越混乱,因此就记好用的就行 ? #//slice : 从start开始,end结束,并且取不到end。 str = " a bcd efghi JKLN nopq rst "; console.log(str.slice(3, 6)); //a console.log(str); ? #//subString : 从start开始,end结束,并且取不到end console.log(str.substring(3, 6)); //a console.log(str); ? #// substr : : 从start开始,截取length个字符。(推荐) console.log(str.substr(3, 6)); //a bcd console.log(str);
- 字符串切割
#//split:将字符串分割成数组(很常用) //功能和数组的join正好相反。 var str = "张三,李四,王五"; var arr = str.split(","); console.log(arr); //"张三""李四""王五"
- 字符串替换
#replace(searchValue, replaceValue) 返回替换后的字符串,不会改变原来的字符串 //参数:searchValue:需要替换的值 replaceValue:用来替换的值 str = "Hello"; console.log(str.replace("o", "!")); //hell! console.log(str);//hello
- 练习
//1. 截取字符串"我爱中华人民共和国",中的"中华" slice(start,end) substring(start,end) substr(start,length) console.log(str.substr(2, 2)); console.log(str.slice(2, 4)); str.substring(2, 4); ? //2. "abcoefoxyozzopp"查找字符串中所有o出现的位置 str = " a b co e f ox y o zz op p "; for(var i = 0; i < str.length;i ++){ if (str[i] == "o"){ console.log(i); } } ? //3. 把字符串中所有的o替换成! console.log(str.replace(/o/g, "!")); //正则表达式 ? //4. 把一个字符串中所有的空格全部去掉 console.log(str.replace(/ /g, "")); //global ? //5. 统计一个字符串中每个字符出现的次数 ar obj = {}; for(var i = 0; i < str.length; i++){ if (obj[str[i]] == undefined){ obj[str[i]] = 1; }else{ obj[str[i]]++; } } console.log(obj);
基本包装类型
简单数据类型是没有方法和属性的。为了方便操作基本数据类型,JavaScript还提供了三个特殊的引用类型:String/Number/Boolean。
基本包装类型:把基本类型包装成复杂类型。
//自动装箱:把基本数据类型转换成为引用数据类型
? var str = "Hello"; //基本数据类型
? var newStr = new String("Hello"); //转换成为引用数据类型
//自动拆箱:把引用数据类型转换成为基本数据类型
? var num = new Number(12); //引用数据类型? console.log(num + 1); //自动拆箱
var str = “abc”; var result = str.indexOf(“a”); //发生了三件事情 1. 把简单类型转换成复杂类型:var s = new String(str); 2. 调用包装类型的indexOf方法:var result = s.indexOf(“a”); 3. 销毁刚刚创建的复杂类型(过河拆桥、卸磨杀驴)
补充
递归函数
递归函数:自己直接或者间接调用自己的函数,递归函数一定要留有出口,不然就是死循环了
<font color="red">递归函数比较抽象,尤其是第一次接触的同学们,大家了解即可。</font>
var count = 0; function tellStory() { count++; console.log("从前座山"); console.log("山里有个庙"); console.log("庙里有一个老和尚"); console.log("还有一个老和尚"); console.log("老和尚在给老和尚聊天"); if (count < 4) { tellStory(); } } tellStory();
1. 求1-100所有数的和 function getSum(n){ if(n == 1){ return 1; } return getSum(n - 1) + n; } console.log(getSum(1)); console.log(getSum(3)); ? 2. 斐波那契数列 function fibonicc(n){ if(n == 1 || n == 2){ return 1; } return fibonicc(n - 2) + fibonicc(n - 1); } console.log(fibonicc(12));
回调函数
回调函数:把函数当成参数来使用,那么这个函数就叫回调函数。
跟递归一样,回调函数现阶段只要求了解概念即可,在特效的时候,会用到回调函数,到时候再解释一下。
?
function uploadFile(onSuccess,onFailure) { console.log("已上传25%"); console.log("已上传50%"); console.log("已上传75%"); var num = parseInt(Math.random() * 2); //生成[0,2)的随机数 if (num % 2 == 0) { //如果是偶数,表示上传失败 //如果失败,让用户重新上传 onFailure(); } else { //如果上传成功,跳转到一个新的界面 onSuccess(); } } uploadFile(fn2,fn1); function fn1(){ alert("对不起,您的文件上传失败"); console.log("上传失败,需要重新上传"); } function fn2(){ alert("恭喜您,上传成功,哈哈哈哈"); console.log("上传成功,跳转到新的界面"); }
arguments对象
JavaScript中,arguments对象是比较特别的一个对象,实际上是当前函数的一个内置属性。也就是说所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有的实参。arguments是一个伪数组,因此及可以进行遍历
//1. 求任意个数的最大值 function getMax(a, b) { // return a > b ? a : b; var max = arguments[0]; for (var i = 0; i < arguments.length; i++) { // console.log(arguments[i]); if (arguments[i] > max) { max = arguments[i]; } } return max; } console.log(getMax(1, 3, 4, 5, 8, 192, 0, 100)); //192 ? ? //2. 求任意个数的和 function getSum(a, b) { // return a + b; console.log(delete arguments); //false var sum = 0; for (var i = 0; i < arguments.length; i++) { sum += arguments[i]; } return sum; } console.log(getSum(1, 2, 3,4)); //10
delet操作符
var student = { name : "张三", age : 18 }; console.log(student.name); //删除了一个student对象的name属性 //true 代表删除成功 console.log(delete student.name); console.log(student.name); //undefined var num = 14; //var声明的全局变量不允许删除 //DOTDELETE标识的属性不允许删除 //原型链里属性不允许删除 //flase 表示删除失败 console.log(delete num); //false console.log(num); //14 str = "Hello"; //删除成功 console.log(delete str); //true // console.log(str); //报错,变量未定义
json对象
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式。同时,JSON是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON数据跟处理对象是一样的。
JSON的属性必须用双引号包裹,而对于JS对象的属性名来说,括号可以省略。
//对于js对象来说,属性名的双引号是可以省略的。 var obj = { name:"zs", age:18, sex:"男" } ? //json对象的属性名必须使用双引号括起来 var obj = { "name":"zs", "age":18, "sex":"男" } ? //在js中,其实就可以把json当成javascript的对象,因此操作是一样。