# JavaScript
# JavaScript基础
历史
JavaScript:一门运行在(客户端)浏览器端的脚本 编程 语言
创造者 布兰登 艾奇 1995年利用10天完成JavaScript设计 脚本:戏剧的剧本。只要按照固定的流程走一遍,就可以把整部戏演完了。但是如果中间有演员出事了,戏就暂停了。这个脚本指的是JavaScript的一个特点:如果执行到某一行出错了,后面的就不会再继续执行了
# JavaScript的组成
- ECMASCRIPT: 定义了javascript的语法规范,描述了语言的基本语法和数据类型
- BOM (Browser Object Model): 浏览器对象模型
- 有一套成熟的可以操作浏览器的 API,通过 BOM 可以操作浏览器。比如: 弹出框、浏览器跳转、获取分辨率等
- DOM (Document Object Model): 文档对象模型
- 有一套成熟的可以操作页面元素的 API,通过 DOM 可以操作页面中的元素。比如: 增加个 div,减少个 div,给div 换个位置等 总结: JS 就是通过固定的语法去操作 浏览器 和 标签结构 来实现网页上的各种效果
# 引入方式
- 内嵌式:demo学习阶段的主要写法
<script>
alert('hello world');
</script>
外链式:新建一个JS文件,文件里JS的代码,引入HTML页面内;作为个文件可以重复使用,项目开发阶段使用;
<script src="./01-demo.js"></script>- 行内式:了解,一般不用
<input type="button" value="点我" onclick="alert('helloworld')">
# JS 注释
- 语法:注释更好的屡清楚你的业务逻辑;不会执行
// alert('hello world'); 单行注释,一般就是简单的做个说明
/*
* 多行注释
* 一般把想要注释的内容写到这里面来,大段内容;不能 嵌套使用;
*/
# 输入输出
作用:交互的简单入口,可以给页面输入我们想要输入的信息,页面输出一定的信息;为了与你写的代码更好交流和调试;
输入:页面中弹出 输入框,需要输入内容后才能继续;开发不常用,我们只是为了配合学习;
// 弹框
alert('弹框');
// 带输入框的弹框
prompt('带输入框的弹框');
// 控制台输出(打印)
console.log('控制台输出');
// 逗号隔开可以输出多个内容
console.log('西游记', '三国演义');
// 在页面输出标签文字
document.write('在页面上输出');
document.write('<strong>哈哈哈来点字</strong>');
# 变量
注意:
- 一个变量名只能存储一个值
- 当再次给一个变量赋值的时候,前面一次的值就没有了
- 变量名称区分大小写(JS 区分大小写)
// 声明变量 变量的作用是存储数据
// var a;
// 变量赋值 = 赋值运算符 把右边的数据存储到左边的变量里面去
// a = 10;
// 变量声明并赋值 变量的初始化
// 弱数据类型
// var a = 10;
// var b = '哈哈哈';
// var n1 = 100;
// var n2 = 200;
// console.log(n1 + n2);
// 把用户输入的信息存储到变量里边去
// var age = prompt('请告诉我您的芳龄');
// console.log(age);
// 变量可以多次赋值
// var name = '孙悟空';
// var name = '猪八戒';
// console.log(name);
// var num3 = 50;
// 把右侧的结果赋值给左边的num3
// num3 = num3 + 1;
// console.log(num3);
# 交换变量的两种方法
// 需求a=6;b=5;
// 思路 定义一个第三方变量c 先把a变量的值赋给c,再把b的值赋值给a,把c的值赋值给b
var a = '老孙';
var b = '老猪';
var c = a;
a = b;
b = c;
console.log(a);
// 交换数字变量
// 思路2 求和 a=a+b 已知a+b的和11还有b是6
var a = 5;
var b = 6;
a = b + a;
b = a - b;
a = a - b;
console.log(a);
# 同时声明多个变量
//1 变量可以一次性声明多个
var a,b,c,d;
// 2 还可以声明多个的同时进行赋值;
var a = 10;
var a = 10,b = 20,c = 30;
//3 变量也可以作为另一个变量的值
var a = 10;
// 赋值给b(复制了一份),a再次变化时,b不受影响;
var b = a;
# 命名
- 范围:字母、数字、下划线、$符号;
- 不能:变量名字不能用数字作为开头
// 变量不能使用数字开头
var 15a = 10;
// 会在控制台中报错:Uncaught SyntaxError: Unexpected
// Uncaught - 未捕获的
// SyntaxError - 语法错误
// Unexpected - 意料之外的
// number - 数字
// 翻译过来就是: 这行有一个语法错误,你的数字不符合语法要求
- 变量名字不能使用JavaScript语法中的关键字和保留字
- 关键字:在JavaScript语法中,具有特殊意义的单词,比如我们学习过的用于声明变量的
var;后面要学习的if else for wihle case break....
// 变量名字不能使用关键字
var var = 20;
// 会在控制台中报错: Uncaught SyntaxError: Unexpected token var
// token - 标记,记号,在编程中我们翻译成 '标识符'
// 意思是这行有一个语法错误,出现了一个意料之外的标识符 var
保留字:JavaScript是不断发展的,以前的功能用了以前的关键字,将来要加入新的功能的时候,可能要用到新的关键字,所有JavaScript在一开始的时候就保留了部分单词,以便将来把保留的单词作为关键字
变量名字是区分大小写的;
// 变量名字是区分大小写的
var a = 10;
console.log(a);// 正常输出
console.log(A);// 在控制台中报错:Uncaught ReferenceError: A is not defined
// ReferenceError - 引用错误
// not defined - 未定义
// 意思是 A 这个变量我们没有定义就使用了,可见a和A是不一样的,不是同一个变量
- 如何定义呢?
- 设置和你公司业务有关系的变量,取英文的翻译
- 使用驼峰(第一个单词的第一个字母小写,第二个单词的首字母大写);getData
- 个人习惯:get_data
// 驼峰 getData
var userName = '张三';
var password = '123456';
// 个人习惯 get_data
# 字符串转义符
类似HTML里面的特殊字符,字符串中也有特殊字符,我们称之为转义符。
转义符都是 \ 开头的,常用的转义符及其说明如下:
| 转义符 | 解释说明 |
|---|---|
| \n | 换行符,n 是 newline 的意思 |
| \ \ | 斜杠 \ |
| ' | ' 单引号 |
| " | ”双引号 |
| \t | tab 缩进 |
| \b | 空格 ,b 是 blank 的意思 |
- 特殊的字符:
"" '' \
# 数据类型
- 是指我们存储在内存中的数据的类型
- 我们通常分为两大类 基本数据类型 和 复杂数据类型
# 基本数据类型
//八进制 八进1 0开头
// var h = 011;
// console.log(h);
// 十六进制 由0-9,a-f组成 0x开头
// var f = 0x10;
- 数值类型(number)
- 一切数字都是数值类型(包括二进制,十进制,十六进制等)
- NaN(not a number),一个非数字
- 字符串类型(string)
- 被引号包裹的所有内容(可以是单引号也可以是双引号)
- 布尔类型(boolean)
- 只有两个(true 或者 false)
- null类型(null)
- 只有一个,就是 null,表示空的意思
- undefined类型(undefined)
- 只有一个,就是 undefined,表示没有值的意思
# 数据类型转换
- 数据类型之间的转换,比如数字转成字符串,字符串转成布尔,布尔转成数字等
其他数据类型转成数值
Number(变量)- 可以把一个变量强制转换成数值类型
- 可以转换小数,会保留小数
- 可以转换布尔值
- 遇到不可转换的都会返回 NaN
parseInt(变量)- 从第一位开始检查,是数字就转换,直到一个不是数字的内容
- 开头就不是数字,那么直接返回 NaN
- 不认识小数点,只能保留整数
parseFloat(变量)
从第一位开始检查,是数字就转换,直到一个不是数字的内容
开头就不是数字,那么直接返回 NaN
认识一次小数点
除了加法以外的数学运算
- 运算符两边都是可运算数字才行
- 如果运算符任何一遍不是一个可运算数字,那么就会返回 NaN
- 加法不可以用
# 转换为数字类型
# number方法
var age = prompt('请输入您的年龄');
console.log(typeof age);
console.log(age + 10);
// 其他类型转数值类型 Number()
var a = '15.32';
// 非数字字符串转成数字类型是NaN not number NaN 是数字类型
var b = '89.9孙悟空';
// 字符串的空 false true 转数字类型是0
var x = '';
var c = true;
var d = false;
var e;
var f=null;
var h=Number(b);
console.log(h,typeof h);
# 取整parseInt
// parseInt()取整 数字开头的非纯数字字符串也可以取整
// ''字符串的空 true false null 转数字类型是NaN
var h = parseInt(b);
console.log(h, typeof h);
# 取小数parseFloat
// parseFloat()取整 数字开头的非纯数字字符串也可以取小数
// ''字符串的空 true false null 转数字类型是NaN
var h = parseFloat(b);
console.log(h, typeof h);
# 隐式数据类型转换
// 隐式数据转化 - * / 如果用+号会直接用数字加字符串 特殊的true false等除外
var a = 10;
var b = '20';
var c = true;
console.log(a + b);
console.log(a - b);
console.log(a * b);
# 其他类型转换字符串类型
var a = '15';
var b = '89.25';
var c = true;
var d = false;
var e = null;
var h = undefined;
String()
var x = String(h);
console.log(x, typeof x);
变量.toString() 这种方法不能转undefined和null
var x = h.toString();
console.log(x, typeof x);
+号拼接 加号两边只要有一个字符串 加号就是拼接符
h = '' + h;
console.log(h, typeof h);
# 其他类型转换为布尔类型
// 其他类型转布尔类型
// false ,'' , undefined , null NaN 0转换之后是false 其他转换都是true
var f = false;
var h = '';
var i = undefined;
var j = null;
var k = NaN;
var z = 0;
var y = Boolean(z);
console.log(y, typeof y);
# 操作符
数据运算:数据参加比较、运算 字符串+:与字符串临近的类型,转为字符串;里面存在一个隐式转化;看不到的转化;隐式转化:在字符串+情况下,数字隐转为字符串;
- 情况:
- 字符串 + ;
- +字符串;
// 字符串 +
// 从左到右执行,数字相加,字符串拼接
var res3 = 10+10+"abc"+"def";
console.log(res3); //输出 20abcdef
// 算术运算符+ - * / %
// + 只要两边有一个字符类型 +就是拼接符 2边都是数字类型 就是加运算
// - * / 会有隐式类型转换
// %取余(模)
# 字符串 其他
- 字符串遇见 * / - %;
- 隐式转化:字符串会隐式转化转为Number,再次参加运算;
var res3 = '456' - 123;
console.log(res3); // 输出 数字 333
// 'abc' 隐式转化为NaN,所有输出NaN;
var res4 = 'abc' - 123;
console.log(res4); // 输出NaN
- 其实字符串遇见 * / % 一样的结果;
- 最终都是参与了隐式转化(只是我们看不见这个转化过程,但是实质还是这些数据被Number();
# 自增自减
// ++i i++ 只操作一个 数据的叫一元运算符 2+3操作2个数据就叫二院操作符
// 自增++i i++不参与运算的情况下 是一样的 都是自身加1
var i = 10;
// 自增参与运算 ++i前置自增 先自身加1 再参与运算
var a = ++i;
// i++后置自增 先参与运算 再自身加1
// 注意后置自增 到了运算符另一边 已经自身加1
var a = i++;
# 数学运算符
+- 只有符号两边都是数字的时候才会进行加法运算
- 只要符号任意一边是字符串类型,就会进行字符串拼接
-
会执行减法运算
会自动把两边都转换成数字进行运算
*- 会执行乘法运算
- 会自动把两边都转换成数字进行运算
/- 会执行除法运算
- 会自动把两边都转换成数字进行运算
%- 会执行取余运算
- 会自动把两边都转换成数字进行运算
# 赋值运算符
=- 就是把
=右边的赋值给等号左边的变量名 var num = 100- 就是把 100 赋值给 num 变量
- 那么 num 变量的值就是 100
- 就是把
+=var a = 10; a += 10; console.log(a); //=> 20a += 10等价于a = a + 10
-=var a = 10; a -= 10; console.log(a); //=> 0a -= 10等价于a = a - 10
*=var a = 10; a *= 10; console.log(a); //=> 100a *= 10等价于a = a * 10
/+var a = 10; a /= 10; console.log(a); //=> 1a /= 10等价于a = a / 10
%=var a = 10; a %= 10; console.log(a); //=> 0a %= 10等价于a = a % 10
# 比较运算符
==- 比较符号两边的值是否相等,不管数据类型
1 == '1'- 两个的值是一样的,所以得到 true
===- 比较符号两边的值和数据类型是否都相等
1 === '1'- 两个值虽然一样,但是因为数据类型不一样,所以得到 false
!=- 比较符号两边的值是否不等
1 != '1'- 因为两边的值是相等的,所以比较他们不等的时候得到 false
!==- 比较符号两边的数据类型和值是否不等
1 !== '1'- 因为两边的数据类型确实不一样,所以得到 true
>=- 比较左边的值是否 大于或等于 右边的值
1 >= 1true1 >= 0true1 >= 2false
<=- 比较左边的值是否 小于或等于 右边的值
1 <= 2true1 <= 1true1 <= 0false
>- 比较左边的值是否 大于 右边的值
1 > 0true1 > 1false1 > 2false
<- 比较左边的值是否 小于 右边的值
1 < 2true1 < 1false1 < 0false
// >< >= <= ==(等于) === != !== 比较运算符返回的结果都是true或者false
var a = 5;
var b = '5';
var c = '7';
var d = 5;
// == 等于 对数据类型没有要求 只要是值相等 就返回true 值不相同 返回false
var res5 = b == c;
// != 不等于 只比较值是否不等 不等返回true 不管数据类型 只要值相等就返回false
var res6 = a != b;
// === 全等严格的判断 必须数据类型和值完全相等,返回true 否则就返回false
var res5 = a === b;
// !== 全不等 值和数据类型有一个不相等 返回true 数据类型和值完全相等返回false
var res7 = a !== b;
// 不同类型:特别的null 、undefined
// undefined和null与其他Number类型在进行相等判断时不进行类型转换。
console.log(null==0) //false
console.log(0 == undefined); //false
// ECMAScript认为undefined是从null派生出来的,所以把它们定义为相等的;
console.log(null==undefined) // true
// 输出 false ,比较两个数据的值是否不相等, 此时两个数据的 值 都 4 ,相等,结果是 false
console.log('4'!= 4);
// 输出 true ,比较两个数据的类型和值是否不相等,此时两个数据的类型不相等,结果是 true
console.log('4'!== 4);
# 逻辑运算符
&&- 进行 且 的运算
- 符号左边必须为 true 并且右边也是 true,才会返回 true
- 只要有一边不是 true,那么就会返回 false
true && truetruetrue && falsefalsefalse && truefalsefalse && falsefalse
||- 进行 或 的运算
- 符号的左边为 true 或者右边为 true,都会返回 true
- 只有两边都是 false 的时候才会返回 false
true || truetruetrue || falsetruefalse || truetruefalse || falsefalse
!- 进行 取反 运算
- 本身是 true 的,会变成 false
- 本身是 false 的,会变成 true
!truefalse!falsetrue
// 逻辑运算符正常情况下返回true或者false
// 逻辑与&& 两边都是true 返回true 只要有一边是false 返回false 见假为假
var res = true && true;
var res = false && false;
// 逻辑或||两边只要有一个true 返回 true 两边都是false 返回false 见真即真
var res = true || true;
var res = 3 < 2 || 5 < 3;
// 逻辑!取反
var res = !true;
var res = !false;
# 自增自减运算符(一元运算符)
++进行自增运算
分成两种,前置++ 和 后置++
前置++,会先把值自动 +1,在返回
var a = 10; console.log(++a); // 会返回 11,并且把 a 的值变成 11后置++,会先把值返回,在自动+1
var a = 10; console.log(a++); // 会返回 10,然后把 a 的值变成 11
--- 进行自减运算
- 分成两种,前置-- 和 后置--
- 和
++运算符道理一样
# 优先级
大致优先级:
- 括号先算
- 其次算算术:++a优先;
- 再次算比较 > ==
- 然后算逻辑 && ||
- 最后算赋值 =
观察代码
var a = 200 === (10 + 10) * 10 > 1;
// 先算括号
200===20*10>1
// 在算计算
200===200>1
// 算右侧;
200===true;
// false
console.log(a);
- 具体计算优先级
1. 第一优先级: [] . ()
2. 第二优先级: ++ -- !
3. 第三优先级: * / %
4. 第四优先级: + -
5. 第五优先级: > >= < <=
6. 第六优先级: == != === !==
7. 第七优先级: &&
8. 第八优先级: ||
9. 第九优先级: = += -= *= /= %=
程序:来源生活,高于生活;
# 分支结构判断
# if
// if单分支
// if (条件表达式) {
// // 当条件表达式为true的时候 执行该处代码
// }
// 需求 判断一个男孩,如果年龄大于等于18 弹出提示框就可以进网吧了
// if(条件表达式){
// 如果条件表达式为true, 执行该处代码
// }else{
// 如果条件为false 执行该处代码
// }
var boy = prompt('请输入您的年龄');
boy = Number(boy);
if (boy > 18) {
alert('请进吧')
} else {
alert('小屁孩,回家洗洗睡吧')
}
// 请用户输入一个数字,判断是不是偶数
var num = Number(prompt('请输入一个数字'));
if (num % 2 == 0) {
console.log('这是一个偶数');
} else {
console.log('这是一个奇数');
}
if(条件表达式1){
如果条件表达式1的结果为ture 执行该处代码
}else if(条件表达式2){
如果条件表达式2的结果为ture 执行该处代码
}else if(条件表达式n){
如果条件表达式n的结果为ture 执行该处代码
}else{
如果上面的条件表达式都为false 执行该处代码
}
// 输入学生成绩 90-100A 80-90B 70-80C 60-70D <60E
var num = Number(prompt('输入您的成绩'));
if (90 < num && num <= 100) {
console.log('A');
} else if (80 < num && num <= 90) {
console.log('B');
} else if (70 < num && num <= 80) {
console.log('C');
} else if (60 < num && num <= 70) {
console.log('D');
} else {
console.log('E');
}
//第二种方法
var num = Number(prompt('输入您的成绩'));
if (num >= 90) {
alert('A')
} else if (num >= 80) {
alert('B')
} else if (num >= 70) {
alert('C')
} else if (num >= 60) {
alert('D')
} else {
alert('E')
}
//第三种
var a = Number(prompt('输入成绩'));
var b = parseInt(Number(a / 10));
switch (b) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
alert('e')
break;
case 6:
alert('d')
break;
case 7:
alert('c')
break;
case 8:
alert('b')
break;
case 9:
alert('a')
break;
case 10:
alert('恭喜满分')
break;
default:
alert('输入错误')
}
# switch
switch (变量) {
case 值1:
当变量和case后边的值1全等 === 数据类型和值完全相等
执行该代码
break的作用是阻断代码向下执行
break;
case 值2:
当变量和case后边的值2全等 === 数据类型和值完全相等
执行该代码
break的作用是阻断代码向下执行
break;
case 值n:
当变量和case后边的值n全等 === 数据类型和值完全相等
执行该代码
break的作用是阻断代码向下执行
break;
default:
当变量和case后边的值都不相等 执行该处代码
break;
}
var week = Number(prompt('亲 请输入周几 我会告诉你菜谱'));
switch (week) {
case 1:
alert('红烧肉')
break;
case 2:
alert('宫保鸡丁')
break;
case 3:
alert('糖醋鲤鱼')
break;
case 4:
alert('烧烤')
break;
case 5:
alert('火锅')
break;
case 6:
alert('满汉全席')
break;
case 7:
alert('宫廷盛宴')
break;
// default:
// alert('宫廷盛宴')
}
# 三元表达式
表达式:有值会返回;
语法:if else 的简写;有返回值;
// 表达式1 ? 表达式2 : 表达式3; // 首先 要知道 表达式 会返回结果; // 过程:先执行表达式1,判断其结果是true还是false, // 如果是true,则执行表达式2,然后将 表达式2的执行结果 作为整个三元表达式的结果进行返回, // 如果是false,则执行表达式3,并将 表达式3的结果 作为整个三元表达式的结果 //例如: 求二个数字中谁更大 var a = 10; var b = 20; var max = a > b ? a : b; console.log(max);// 三元表达式 // 表达式1? 表达式2: 表达式3 // 如果表达式1位true 执行表达式2 如果为false执行表达式3 var a = 10; var b = 50; // a和b的最大值 a > b ? alert(a + '大') : alert(b + '大');var i = 0; // 三元表达式? 前边的表达式也会隐式类型转换为布尔值 var num = i++ ? i++ : ++i; console.log(num);
# 循环结构
# for循环
- 执行过程:
- 执行初始化表达式(只执行一次)
- 执行条件表达式
- 如果条件表达式的结果为false, 结束循环;
- 如果条件表达式的结果为true,执行循环体
- 执行自增表达式
- 重复2~5的步骤,直到条件表达式的结果为false,结束循环
for(初始化表达式; 条件表达式; 自增表达式){
// 循环体
}
// 在页面上打印1-100
for (var i = 1; i <= 100; i++) {
console.log(i);
}
// 求1 - 10的和 1 + 2 + 3...
var sum = 0;
for (i = 1; i <= 10; i++) {
sum += i;
}
console.log(sum);
// 求1-100之间所有的偶数的和
var sum = 0;
for (i = 1; i <= 100; i++) {
if (i % 2 == 0) {
sum += i;
}
}
console.log(sum);
// 求1-4的乘积
var sum = 1;
for (i = 1; i <= 4; i++) {
sum *= i;
}
console.log(sum);
# 双层for循环
// 打印10行 每一行都是5课星
// 循环是重复做一件事 条件不满足的时候循环结束
// 外层for循环控制的是行数
for (var j = 1; j <= 10; j++) {
for (var i = 1; i <= 5; i++) {
document.write("★");
}
document.write("<br>")
}
// 直角三角形
for (var j = 1; j <= 9; j++) {
for (var i = 1; i <= j; i++) {
document.write("★");
}
document.write("<br>")
}
// 倒三角
for (var j = 1; j <= 9; j++) {
for (var i = 1; i <= 10 - j; i++) {
document.write("★");
}
document.write("<br>")
}
<!-- 等腰三角形 -->
<style>
body {
text-align: center;
}
</style>
<script>
for (var j = 1; j <= 9; j++) {
for (var i = 1; i <= j; i++) {
document.write("<span>★</span>");
}
document.write("<br>")
}
</script>
<!-- 九九乘法表 -->
<style>
span {
display: inline-block;
width: 100px;
height: 30px;
line-height: 30px;
text-align: center;
border: 1px solid #000000;
margin-left: -1px;
margin-bottom: -1px;
}
</style>
<script>
for (var j = 1; j <= 9; j++) {
for (var i = 1; i <= j; i++) {
document.write("<span>" + i + 'x' + j + '=' + i * j + "</span>");
}
document.write('<br>')
}
</script>
# while循环
当循环次数已知的时候用for循环 当循环次数未知的时候用while和do while
while (条件表达式) {
// 当条件表达是为true的时候 执行循环体的代码 条件表达式为false的时候 循环体代码不执行
}
// 求1-100的和
var i = 1, sum = 0;
while (i <= 100) {
sum += i;
i++;
}
console.log(sum);
// 用户名和密码只要有一个输入错误 用户就需要一直输入
var userName = prompt('用户名')
var passWord = prompt('密码')
while (userName != 'admin' || passWord != '123456') {
userName = prompt('用户名')
passWord = prompt('密码')
}
alert('登录成功')
# do while
// do{
// 循环体
// 循环体首先执行一次 再去看条件表达式 如果条件表达式为true 循环体继续循环 如果为false 循环结束
// }while(条件表达式)
do {
var userName = prompt('用户名')
var passWord = prompt('密码')
} while (userName != 'admin' || passWord != '123456') {
alert('登录成功');
}
# break和continue
- 循环退出:
- 满足条件退出
- 关键字退出:某些情况下,我们不一定要循环从头到尾执行,这个时候就要使用break和continue控制循环的次数;
// break 结束的是当前循环
/* 例子:电梯一共有6层,现在我们要上电梯,我们的教室在3楼,电梯只要到3楼就可以了。*/
for(var i = 1; i <= 6 ; i++ ){
console.log('现在是'+i+'楼');
if(i == 3){
console.log('3楼到了,电梯停了,请下电梯。');
// 程序 执行到 3,执行了四次就结束了;
break;
}
}
// 这里案例用的是for循环演示,while 和do-while一样;
// continue
// 电梯一共有6层,除了3楼没人下去,其他楼层都有人下去(3楼不停,其他楼层都要停)
for(var i = 1; i <= 6; i++){
if(i == 3){
// 执行到 3 时。当前次的程序后面的全部跳过;继续执行后面的次数;
continiue;
}
console.log(i+'楼到了,电梯停了,请下电梯。');
}
总结:这个地方只是用for做终止
break用于结束整个循环
continue用于结束整个循环中的一次,结束当前这次循环;
break和continue后面的代码都不会执行,执行前面的代码;
# 逻辑中断 短路
// &&与操作(中断)短路 找假 如果找不到就返回最后一个的值
// var res = null && 3 && true;
// console.log(res);
// || 或操作(中断)短路 找真 如果找不到到就返回最后一个的值
var res = 0 || 3 || NaN;
console.log(res);
# 调试
- 对于初学者来说,感受代码的执行过程是非常重要的,浏览器中提供了一个可以观察代码执行过程的工具
- 第一步:F12打开开发者工具,点击Sources选项
- 第二步:在左边找到代码所在文件,双击打开
- 第三步:在中间部分找到自己写的代码,在想要暂停的数字地方打上断点
- 第四步:触发代码的执行,现在我们的代码是在浏览器打开的时候执行,所以我们只要刷新页面即可。当代码执行到断点所在行,会暂停
- 第五步:通过点击右边的控制执行按钮,可以让代码按照你的意愿

# 习题练习
# 1- 判断时间阶段。
题目描述:
用户输入几点弹出问候信息;
如用户输入12点中午好; 用户输入18点 弹出傍晚好; 用户输入23点弹出深夜好;题目提示:
通过比较运算符判定输入的时间的范围,弹出相应的问候信息
var i; var j = Number(prompt(i)); if (j == 12) { alert('中午好'); } else if (j == 18) { alert('傍晚好'); } else if (j == 23) { alert('深夜好'); } else { alert('输入错误'); }
# 2 - 比较两个数的最大值
题目描述:
用户依次输入2个值,最后弹出最大的那个值
题目提示:
通过比较运算符弹出最大值
var i = Number(prompt('请输入i的值')); var j = Number(prompt('请输入j的值')); if (i > j) { alert('i' + '大') } else { alert('j' + '大') }
# 3 - 判断奇偶性
题目描述:
用户输入一个数,判断是奇数还是偶数
题目提示:
通过%运算符可以得出数字的奇偶性
var i = Number(prompt('请输入数字判断奇数还是偶数')) if (i % 2 == 0) { alert('偶数') } else { alert('奇数') }
# 4 - 判断星期
题目描述:
周三 周四 周五 周六 周日 周一 周二 周三 周四 周五 周六 周日 周一
1 2 3 4 5 6 7 8 9 10 11 12 13
假设这个月1号是星期三,提示用户输入本月的日期(即1日-31日),返回用户输入的那一天是星期几
题目提示:
利用%和7取余,再判定是星期几
var i = Number(prompt('请输入日期')); if (i % 7 == 0) { alert('今天是周二') } else if (i % 7 == 1) { alert('今天是周三') } else if (i % 7 == 2) { alert('今天是周四') } else if (i % 7 == 3) { alert('今天是周五') } else if (i % 7 == 4) { alert('今天是周六') } else if (i % 7 == 5) { alert('今天是周日') } else if (i % 7 == 6) { alert('今天是周一') }//第二种解法 var day = Number(prompt('请输入几号')); day = (day + 2) % 7; if (day == 0) { alert('这一天是周日') } else { alert('这一天是周' + day); }
# 5 - 请客吃饭
题目描述:
接收班长口袋里的钱数?
若大于等于2000,请大家吃西餐。 2000<=j 若小于2000,大于等于1500,请大家吃快餐。1500<=j<2000 若小于1500,大于等于1000,请大家喝饮料。 1000<=j<1500 若小于1000,大于等于500,请大家吃棒棒糖。 500<=j<1000 否则提醒班长下次把钱带够题目提示:
使用switch或者if else if 来进行逻辑书写
var i = Number(prompt('班长口袋里面的钱数')); if (i >= 2000) { alert('请大家吃西餐') } else if (i < 2000 && i >= 1500) { alert('请大家吃快餐') } else if (i < 1500 && i >= 1000) { alert('请大家喝饮料') } else if (i < 1000 && i >= 500) { alert('请大家吃棒棒糖') } else { alert('班长下次把钱带够') }var i = Number(prompt('班长口袋里面的钱数')); var j = parseInt(i / 500); switch (j) { case 0: alert('班长下次把钱带够') break; case 1: alert('请大家吃棒棒糖'); break; case 2: alert('请大家喝饮料'); break; case 3: alert('请大家吃快餐'); break; case 4: alert('请大家吃西餐'); break; }
# 6 - 成绩表
题目描述:
分数转换,给一个分数,判定等级。大于等于90 A,大于等于80小于90 B,大于等于70小于80 C ,大于等于60小于70 D,小于60 E
题目提示:
使用if else if 来进行逻辑书写,当使用if else if 时注意判定大小顺序
思考:是否可以使用switch完成本题目
var i = Number(prompt('请输入你的成绩'));
var j = parseInt(i / 10);
switch (j) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
alert('E')
break;
case 6:
alert('D')
break;
case 7:
alert('C')
break;
case 8:
alert('B')
break;
default:
alert('A')
}
var i = Number(prompt('请输入你的成绩'));
if (i >= 90) {
alert('A');
} else if (i >= 80) {
alert('B');
} else if (i >= 80) {
alert('C');
} else if (i >= 70) {
alert('D');
} else {
alert('E');
}
var score = Number(prompt('请输入成绩'));
switch (true) {
case score >= 90:
alert('A')
break;
case score >= 80:
alert('B')
break;
case score >= 70:
alert('C')
break;
case score >= 60:
alert('D')
break;
case score < 60:
alert('E')
break;
default:
alert('输入错误');
break;
}
# 1.1 求100以内所有能被3和7整除的数的和
题目描述:
- 把1-100之间所有能够被3和7同时整除的数找出来,计算累加和
题目提示:
- 在算入累加和之前,使用%判定遍历到的数字是不是可以被3和7整除
- ``
var sum = 0; for (i = 1; i <= 100; i++) { if (i % 3 == 0 && i % 7 == 0) { sum += i; } } console.log(sum);
# 1.2 使用for循环打印三角形
题目描述:
在控制台一次性打印形状如下:
☆ ☆☆ ☆☆☆ ☆☆☆☆ ☆☆☆☆☆
var x = ''; for (i = 1; i <= 5; i++) { for (j = 1; j <= i; j++) { // console.log('★'); x = x + '★'; // document.write('★') } // document.write('<br>') console.log(x) x = ''; }for (i = 1; i <= 5; i++) { for (j = 1; j <= i; j++) { // console.log('★'); // x = x + '★'; document.write('★') } document.write('<br>') // console.log(x) // x = ''; }
题目提示:
- 利用双重for循环
# 1.3 使用for循环打印99乘法表
题目描述:
使用for循环,打印99乘法表
在控制台打印具体效果如下:
1×1=1 1×2=2 2×2=4 1×3=3 2×3=6 3×3=9 1×4=4 2×4=8 3×4=12 4×4=16 1×5=5 2×5=10 3×5=15 4×5=20 5×5=25 1×6=6 2×6=12 3×6=18 4×6=24 5×6=30 6×6=36 1×7=7 2×7=14 3×7=21 4×7=28 5×7=35 6×7=42 7×7=49 1×8=8 2×8=16 3×8=24 4×8=32 5×8=40 6×8=48 7×8=56 8×8=64 1×9=9 2×9=18 3×9=27 4×9=36 5×9=45 6×9=54 7×9=63 8×9=72 9×9=81
题目提示:
- 利用双重for循环
<style>
span {
display: inline-block;
width: 100px;
height: 50px;
line-height: 50px;
text-align: center;
border: 1px solid #000000;
margin-bottom: -1px;
margin-left: -1px;
}
</style>
<script>
for (i = 1; i <= 9; i++) {
for (j = 1; j <= i; j++) {
document.write("<span>" + i + 'x' + j + '=' + i * j + "</span>");
}
document.write('<br>');
}
</script>
# 1.4 用户登录验证
- 题目描述:
- 接收用户输入的用户名和密码,若用户名为 “admin” ,且密码为 “123456” ,则提示用户登录成功! 否则,让用户一直输入。
- 题目提示:
- 利用while循环或者do while 循环
var userName = prompt('请输入用户名');
var passWord = prompt('请输入密码');
while (userName != 'admin' && passWord != '123456') {
var userName = prompt('请输入用户名');
var passWord = prompt('请输入密码');
}
alert('密码输入正确');
do {
var userName = prompt('请输入用户名');
var passWord = prompt('请输入密码');
} while (userName != 'admin' && passWord != '123456') {
alert('密码输入正确');
}
# 1.5 求1-100之间个位数不为3的数的累加和。
题目描述:
- 求整数1~100的累加值,但要求跳过所有个位为3的数。
题目提示:
- 使用%判个位数是否为3
- 用continue实现
var sum = 0; for (var i = 1; i <= 100; i++) { //如果能被3整除,跳过continue if (i % 3 == 0) { continue; } sum += i; } console.log(sum);var a = 0, sum = 0; for ( var i = 1; i <= 100; i++) { a += i; if (i % 10 == 3) { sum += i; } } console.log(a - sum);var sum = 0; for (i = 1; i <= 100; i++) { if (i % 10 != 3) { sum += i; } } console.log(sum);
# 2.1 简易ATM
题目描述:
里面现存有 100 块钱。
如果存钱,就用输入钱数加上先存的钱数, 之后弹出显示余额提示框
如果取钱,就减去取的钱数,之后弹出显示余额提示框
如果显示余额,就输出余额
如果退出,弹出退出信息提示框
操作界面如下


题目提示:
- 通过输入的数值判断用户操作
- 定义一个变量,保存钱数
- 先接收一下用户输入的数字 存到变量里边
- 用while循环
- whilie循环里边,switch case 比较简单
var money = 100
for (let i = 0; i < 5; i++) {
var work = parseFloat(prompt("请输入你要进行的操作" + "\n" + "1.存钱" + "\n" + "2.取钱" + "\n" + "3.显示金额" + "\n" + "4.退出"))
switch (work) {
case 1:
var cun = parseFloat(prompt('请输入你要存的金额'));
money += cun;
alert("你的剩余金额是" + money);
break;
case 2:
var qu = parseFloat(prompt('请输入你要取出的金额'));
money = money - qu;
alert("你的剩余金额是" + money);
break;
case 3:
alert("你的剩余金额是" + money);
default:
break;
}
}
//开关阀atm
var flag = true;
var money = 100;
while (flag) {
var mes = Number(prompt('请输入你的操作:\n1.存钱\n2.取钱\n3.显示余额\n4.退出'));
switch (mes) {
case 1:
var pay = Number(prompt('请输入您的存款金额'));
money += pay;
alert('您的余额是' + money);
break;
case 2:
var get = Number(prompt('请输入您的取款金额'));
money -= get;
alert('您的余额是' + money);
break;
case 3:
alert('您的余额是' + money);
break;
case 4:
flag = false;
}
}
# 2.2 求从1 开始第35个能被7和3整除的整数
题目描述:
- 求从1开始第35个能被7和3整除的整数
题目提示:
- 通过变量记录是第几个可以被3和7整除的数
var num = 1, count = 0, result = 0;
for (var i = 1; i <= num; i++) {
num++;
if (i % 3 == 0 && i % 7 == 0) {
// 使用result把i的值取出来
result = i;
// 取出一个i count自增一次
count++;
// 到第35个i的时候循环终止
} else if (count == 35) {
break;
}
}
console.log(result);
var i = 1, count = 0, result = 0;
while (count < 35) { //当count等于35的时候就会停止执行
i++; //i的自增bai
if (i % 3 == 0 && i % 7 == 0) {
result = i; //把能整除3和7的数字保存下来
count++; //一旦发现一次能整除3和7的数字,就加1
}
}
console.log(result);
var a = 1; b = 0; //b 是计数器
// b不等于35循环一直进行下去 等于35的条件表达式为false 循环结束
while (b != 35) {
if (a % 7 == 0 && a % 3 == 0) {
b++;
if (b == 35) {
alert(a)
}
}
a++;
}
//开关法
var a = 1, b = 0, flag = true; //b 是计数器
// flag为true的时候 循环一直执行 flag为false的时候 循环终止
while (b != 35) {
if (a % 7 == 0 && a % 3 == 0) {
b++;
if (b == 35) {
alert(a)
// 循环停止
flag = false;
}
}
a++;
}
# 2.3 斐波那契数列
“兔子数列 (opens new window)”,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34 ,55, 89
特点是: 后一个月是前2个月的和
求第12个月的兔子数?
提示:
var a = 0, b = 1;
for (i = 3; i <= 12; i++) {
var c = a + b;
a = b;
b = c;
}
alert(c);
# 2.4 质数
质数是只能被1和他自身整除的数
比如7 1 2 3 4 5 6 7 是质数 9不是质数 1 2 3 4 5 6 7 8 9 因为9能被3整除
n 2, 3, 4 ,5 ,6 ...n - 1 , n
提示:
开关法
// 用户任意输入一个数 如果是质数弹框提示 如果不是质数 弹出提示不是质数
var num = Number(prompt('请输入一个数 我会告诉你他是不是质数'));
var flag = true;
if (num == 2) {
alert('质数');
}
for (var i = 2; i < num; i++) {
if (num % i == 0) {
flag = false;
alert('不是质数');
break;
}
}
if (flag) {
alert('质数');
}
var num = Number(prompt('请输入一个数 我会告诉你他是不是质数'));
//num%2.......num-1 !=0是质数 num%2......num-1==0 说明不是质数
for (var i = 2; i < num; i++) {
//比如num是6 这时候6%i==0 i是2 循环结束
//比如num7 这时候7%(2.....6) !==0 然后循环结束 循环结束的时候 i应该是num 这个数是质数
if (num % i == 0) {
alert('不是质数');
break;
}
}
// 当num从2一直到num-1取余不等于0 这时候上边的循环结束 循环结束的时候i++最后变成了num
if (num == i) {
alert('质数');
}
var num = Number(prompt('请输入数字 判断是否为质数'));
var con = 0;
for (i = 1; i <= num; i++) {
if (num % i == 0) {
con++;
}
}
// 循环结束之后 con的次数确定了 再进行判断 如果 num%(1...num)2次等于0 是质数 否则不是质数
if (con == 2) {
alert('质数');
} else {
alert('不是质数');
}
var count = 0;
var num = Number(prompt('请输入数字 判断是否为质数'));
for (i = 2; i <= num; i++) {
if (num % i == 0) {
count++;
}
}
if (count == 1) {
alert('质数');
} else {
alert('不是质数')
}
# 介绍
- 数组是一个有顺序、有长度的数据集合;
- 数组:类型Object;
- 特点:
- 把数据放在一起;
- 有先后位置上的顺序;
- 有数据的长度;
// 数组一组有序的有长度的数据集合 数组里面可以存储任意的数据类型
// 声明数组
// 1字面量声明数组
// 数组元素顺序是靠索引来控制的 索引(下标)从0开始
//创建一个空数组
var arr = [];
arr[0] = 89;
arr[1] = 'www';
arr[2] = true;
console.log(arr);
//创建一个有内容的数组
var arr1 = [12, 39, 'hahahha', 78];
console.log(arr1);
//拿到索引为0 顺序上第一个位置上的数据
//把数组[索引]格式当成一个变量使用就行了
console.log(arr1[0])
# 存值
- 数组中的数据使用索引管理。
- 索引 下标:位置:方便放入存值和寻找;
- 索引 规则:用数字表示,从0开始
//把成绩存储到数组中
arr[0] = 91;
arr[1] = 88;
arr[2] = 72;
arr[3] = 45;
arr[4] = 63;
console.log(arr); // 输出 [91,88,72,45,63] 就是一个数据集合
- 把
数组[索引]格式当成一个变量使用就行,
// 初始化赋值完成后,也可以再次改变值,把前面的值覆盖掉;
arr[0] = 100;
- 如果一开始就知道数组了,可以直接使用一个简单的语法存储数据
var arr = [91,88,72,45,63];
console.log(arr); // 输出的结果是一样的
- 上面每个位置上存的都是数字类型,可以为其他类型;
# 取值
- 把数据取出来,得知道你要取哪个位置上的数据把。
- 数据取值同样使用索引取。
// 拿到索引为0,顺序上第一个位置上的数据;
// 把 数组[索引] 格式当成一个变量使用就行;
console.log(arr[0]);
// 数组求和:班里的成绩总和
var sum = arr[0] + arr[1] + arr[2] + arr[3] + arr[4];
console.log(sum); // 输出370
# 遍历
- 求成绩总和:一个一个地把数组里面的数组取出来了,从索引 0 到最后一个索引,
- 索引从0开始到结束的过程,有重复的思想,需要用到循环;
// 最初的写法
var sum = arr[0] + arr[1] + arr[2] + arr[3] + arr[4];
// 循环 这个从0~最后一个索引,有重复的思想在里面,使用循环。
var sum = 0;
for(var i = 0; i <= 4; i++){
sum += arr[i];
}
console.log(sum); // 输出 370,和我们一个一个相加是一样的
- 使用循环来遍历数组,当数组中的数据比较多的时候,会比较方便。一般是使用for循环;
# 数组长度
# 语法
存取数据:涉及到就是数组的顺序问题,通过索引去存取;
数组长度:数组中一共存放了多少个数据;
console.log(arr.length); // 数组.length 就是数组的长度
- 如果数组的长度是5,最后一个元素的索引就是4;
- 我们发现最大索引总是比长度少 1 ,所以遍历还可以这么写
# 数组的索引
索引,也叫做下标,是指一个数据在数组里面排在第几个的位置
注意: 在所有的语言里面,索引都是从 0 开始的
在 js 里面也一样,数组的索引从 0 开始
for(var i = 0; i <= arr.length - 1; i++){
console.log(arr[i]);
}
// 简化一下
for(var i = 0; i < arr.length; i++){
console.log(arr[i]);
}
// i是索引值 从0开始
// 数组里边的最大索引值是数组名.length - 1
var arr = [22, 5, 6, 7, 8, 98];
for (i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
var arr = [22, 5, 6, 7, 8, 98];
/* 数组长度小于数组的实际长度 后边的元素会删除掉
arr.length=2;
数组长度大于数组的实际长度 后边的元素会显示empty 就是undefined */
arr.length = 9;
//输出数组内的所有元素
console.log(arr);
//输出数组的长度
console.log(arr.length);
//输出索引值的第七位
console.log(arr[7]);
# 数组后面追加元素
```js
// 数组后边追加新元素 数组名[数组名.length]=值 // 0 1 2 3 4 n // 数组长度1 2 3 4 5 n+1 var arr = [22, 5, 6, 98]; arr[arr.length]=32; arr[arr.length]=50; ```
# 习题练习
# 求数组中所有数字的和以及平均值
- 分析:
- 总和:循环遍历,加在一个变量上得到;
- 均值:总和 / 个数;(arr.length)
var sum = 0;
var arr = [2, 3, 4, 5];
for (i = 0; i < arr.length; i++) {
sum += arr[i];
}
console.log(sum, sum / arr.length);
# 求数组中的最大值
- 分析:生活中,一堆人最高的(人很多,多到你一下看不出来);
- 最大值:最起码得两个数比较下,得到最大值;
- 假设:其中随便一个是最大值MAX,每个元素和max比较,
- 若有比MAX大的,那该元素代替MAX;
- 若都没有MAX大,恭喜,你一开始就猜对了;
var arr = [22, 5, 6, 98];
var max = arr[0];
for (var i = 1; i < arr.length; i++) {
if (max < arr[i]) {
max = arr[i];
}
}
console.log(max);
# 把老数组里面大于10的选出来 追加到新的空数组里面
// 把老数组里面大于10的选出来 追加到新的空数组里面
// 结果newArr=[12, 5, 6, 23, 32, 48]
// 把老数组里面大于等于10的选项挑出来
// for 遍历 因为要老数组里面的每一项去和10比较
// if(arr[i]>=10) 条件大于等于10
// newArr[newArr.length]向新数组追加元素
var arr1 = [12, 5, 6, 23, 32, 48];
var newArr = [];
for (i = 0; i < arr1.length; i++) {
if (arr1[i] >= 10) {
newArr[newArr.length] = arr1[i];
}
}
console.log(newArr);
# 翻转数组
// 翻转数组
var arr = ['张三', '李四', '王五', '赵六', '陆奇'];
// 结果是arr 陆奇 赵六 王五 李四 张三
// 交换位置 交换次数
// 交换位置 arr[i]和arr[arr.length-1-i] 交换变量的值
// 交换需要用到数组的每一项 遍历
for (i = 0; i < (arr.length - 1) / 2; i++) {
var temp = arr[i];
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = temp;
}
console.log(arr);
翻转数组
arr[i] arr[i] arr[arr.length-1-i] arr[arr.length - 1 - i]
var arr = ['张三', '李四', '王五', '赵六', '鲁七', 6];
// // 结果是 arr = ['鲁七', '赵六', '王五','李四', '张三' ];
// // 交换次数 交换2次
// // 交换位置 arr[i] 和 arr[arr.length-1-i] 交换变量的值
// // 交换需要用到数组里边的每一项,遍历
for (var i = 0; i < (arr.length- 1) / 2; i++) {
var temp = arr[i];
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = temp;
}
console.log(arr);
# 冒泡排序
// 冒泡排序数字数组从小到大(从大到小排列)
var arr = [5, 3, 8, 7];
// 比较 数组里面第一个元素 第一个元素比后边大的,交换位置
// 外边的循环控制的是交换的次数
for (var j = 0; j < arr.length - 1; j++) {
// 里面的循环控制是每一轮交换
for (var i = 0; i < arr.length - 1 - j; i++) {
if (arr[i] < arr[i + 1]) {
var temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
}
console.log(arr);
// if(5 > 3) {
// 交换位置
// }
// 第1轮 比较了3次 j 0 arr.length - 1 - j
// [3, 5, 8, 7]
// if(5 > 8) {
// 交换位置
// }
// // [3, 5, 8, 7]
// if(5 > 7) {
// 交换位置
// }
// // [3, 5, 8, 7]
// 第2轮 比较了2次 j 1 arr.length - 1 - j
// if(3 > 8) {
// 交换位置
// }
// [3, 5, 8, 7]
// if(3 > 7) {
// 交换位置
// }
// [3, 5, 8, 7]
// 第3轮,比较了1次 j 2 arr.length - 1 -j
// if(8> 7) {
// 交换位置
// }
// [3, 5, 7, 8]
// 结果 arr = [3, 5, 7, 8]
var arr = [2, 3, 56, 21]
for (i = 0; i < arr.length - 1; i++) {
for (j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] < arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
console.log(arr);
// 第一轮 i 0 arr.length-1 j 3 arr.length-1
/* 第一次 2<3 交换位置
第二次 2<56 交换位置
第三次 2<21 交换位置 3 56 21 2
第二轮 i 1 2 arr.length-1-1
第一次 3<56 交换位置
第一次 3<21 交换位置 56 21 3 2
第三轮 i 2 1 arr.length-1-1-1 arr.length-1-i
第一次 56<21 56 21 3 2
*/
# js去重
// 去重将数组里面重复的项去掉 只保留一个 写到新数组里面
/* 思路 拿老数组里面的某一项和新数组中的每一项比较 只要有一个相等 不用追加 除非都不相等 把老数组中的这一项 追加到新数组里面去
双层for循环 */
// 遍历老数组
var arr = [1, 2, 3, 3, 2, 7, 8]
var newArr = [];
for (var i = 0; i < arr.length; i++) {
// 考虑开关的位置
var flag = true;
// 遍历新数组
for (var j = 0; j < newArr.length; j++) {
// 老数组里边的某一项和新数组中的任意一项比较相等 不用追加到新数组里面
if (arr[i] == newArr[j]) {
flag = false;
break;
}
}
if (flag) {
newArr[newArr.length] = arr[i];
}
}
console.log(newArr);
var arr = [1, 2, 3, 3, 2, 7, 8]
var newArr = [];
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < newArr.length; j++) {
if (arr[i] == newArr[j]) {
break;
}
}
// 如果老数组中的某一项和新数组里面全部元素比较完之后 都不相等 追加到新数组里面去
// 老数组循环一遍 都不相等 老数组循环结束 最后一次i++变成了newArr.length
if (j == newArr.length) {
newArr[newArr.length] = arr[i];
}
}
console.log(newArr);
# 数组的构造函数
- 数组在JS中还可以使用另一种方式创建,这个方式我们称为 : 构造函数
- 构造函数:能构造一个你需要的东西(对象);
// 使用 构造函数 创建数组
var arr = new Array();
// 存储数据
arr[0] = 10;
arr[1] = 20;
console.log(arr);
var arr = new Array(10,20);
console.log(arr);
- 注意:一个数据,不要使用这个方式存储数据;它会认为你想要设置数组的长度,而不是要把数据存储在数组中。
var arr = new Array(10);
console.log(arr); // 输出 [empty × 10]
- arr.length = 0;
# 字面量创建一个数组
直接使用
[]的方式创建一个数组// 创建一个空数组 var arr1 = [] // 创建一个有内容的数组 var arr2 = [1, 2, 3]
# 函数声明调用
// 函数的声明
// function 函数名(){
// 函数体
// }
// 函数调用 函数自己不执行 只有被调用的时候才执行
// 函数名();
// function: 声明函数的关键字,表示接下来是一个函数了
//getSum: 函数的名字,我们自己定义的
// (): 必须写,是用来放参数的位置
// {}: 就是我们用来放一段代码的位置
function getSum() {
var sum = 0;
for (i = 1; i <= 100; i++) {
sum += i;
}
console.log(sum);
}
getSum();
getSum();
getSum();
# 赋值式
- 其实就是和我们使用
var关键字是一个道理了 - 首先使用
var定义一个变量,把一个函数当作值直接赋值给这个变量就可以了 - 语法:
var fn = function () {
// 一段代码
}
// 不需要在 function 后面书写函数的名字了,因为在前面已经有了
# 参数
# 配置参数
- 参数:对于函数来说,函数内部的变量;
- 作用:为什么?给别人讲故事,不同的情况套用不同的人名;把函数封装的代码,变活了;
- 定义参数:位置,小括号上自定的参数;
- 特点:只能在内部使用,和外部没有关系;
- 使用:传入值,给了形参;
- 语法:
// 在小括号内的变量,对于函数来说,就是参数;
// 参数就是函数 内部的变量;
function 函数名(参数){
// 函数体
}
// 参数:对于函数,这些参数都是形式上的参数,它就是代替位置,相当于是变量在这占了个坑;至于这个参数真实背后代表什么值,我们现在还不知道;
function tellStroy(name){
console.log("从前有座山,山里有座庙");
console.log("庙里有个老和尚在给小和尚讲故事");
console.log("讲的是什么呢?");
console.log("老和尚对"+ name +"说:");
}
- 既然是变量,可以被改变存储值;如何改变?调用时传递一个值;
// 调用函数的时候,传入参数;
tellStroy('清风');
tellStroy('明月');
- 需求:如果我们想在调用函数的时候,把老和尚的名字也明确一下,就把老和尚的名字作为变量改变下;
// 声明函数,配置参数;
function tellStroy(name1,name2){
console.log("从前有座山,山里有座庙");
console.log("庙里有个老和尚在给小和尚讲故事");
console.log("讲的是什么呢?");
console.log(name1 "对"+ name2 +"说:");
}
// 调用函数
tellStroy('圆通','清风');
# 参数不赋值
- 变量:函数内部的变量,没有赋值,默认为undefined;和我们的变量一模一样;
function tellStroy(name){
console.log("从前有座山,山里有座庙");
console.log("庙里有个老和尚在给小和尚讲故事");
console.log("讲的是什么呢?");
console.log("老和尚对"+ name +"说:"); // 老和尚对undefined说;
}
- 解决:对参数进行判断,如果是undefined,给一个默认值;
function tellStroy(name){
// if 条件语句
if(name==undefined) {
name = '小和尚'
}
else {
name = name;
}
// 三元表达式;
name = name?name:"小和尚";
console.log("从前有座山,山里有座庙");
console.log("庙里有个老和尚在给小和尚讲故事");
console.log("讲的是什么呢?");
console.log("老和尚对"+ name +"说:");
}
# 形参与实参
- 形参:外面不能使用;和外面没有任何关系;只能函数内部使用;
- 实参:调用函数时,真实参与运算的数据,外部调用函数的时候,传入真实数据,实参;把真实数据赋值了一份给形参;
- 相互不影响:传入简单值类型,互不影响;
- 核心点:函数里面和函数外面,没有关系;
// 特点(规则):形参与实参相互不影响;
// 形参:外面不能使用;和外面没有任何关系;只能函数内部使用;
// 实参:把实参的数据,赋值(复制)了一份给形参;
function fn(a) {
a = a + 10;
}
var a = 10;
fn(a);
// a = a;
// 前面a:形参,只能在函数内部使用,和外面没有关系;
// 后面a:实参,外面的实参把自己的值,赋值(复制)了给里面的形参a;
- 什么时候配置形参:形参,内部的变量,只能在内部使用;既然只能在内部使用,和外面没有关系,那么什么时候需要配置形参?如果外面的数据需要给内部加工下,那就配置形参;实参传入真实数据;
- 里面加工,和外面没有关系;如何把里面的加工给到外面呢?返回值值;
// 实参多 形参少 实参会按照顺序传递给形参 多余的实参不传值
// 形参多 实参少 多余的形参undefined
function fn(a, b, c, d) {
console.log(a, b, c,d);
}
fn(1, 2, 3)
# 函数return返回值
- 作用:函数内部运算出来的一切和外面没有任何;如果外面想用内部运算完的结果,设置返回值;
- return 返回的意思,其实就是给函数一个 返回值 和 终断函数
# 终断函数
当我开始执行函数以后,函数内部的代码就会从上到下的依次执行
必须要等到函数内的代码执行完毕
而
return关键字就是可以在函数中间的位置停掉,让后面的代码不在继续执行
- 语法:
function fn(a) {
a = a + 10;
// 内部:只能在函数内部使用,把变量后面真实数据返回出去;
// 关键字:return;
return a;
}
// 外面:需要找个变量接受
var b = fn(10);
console.log(b);
- 特点规则:
// 特点(规则):
// 1. 作用:函数返回值,把内部的值进行返回,返回到外面;
// 2. 只要函数内部出现了return,函数内return下面的代码(函数内)不再执行;
// 3. 如果return 后面没有任何数据(变量),默认返回undefined;
// 4. 如果连return都没有,函数就没有返回值,执行函数,默认返回undefined;
// 规则2:
function fn(a) {
a = a + 10;
// 内部:只能在函数内部使用,把变量后面真实数据返回出去;
// 关键字:return;
return a;
// 函数内部 return下面的代码不再执行;
console.log("--------------------------------------------");
}
// 规则3:
function fn() {
return;
}
var a = fn();
console.log(a);
// 规则4:
function fn() {
// return;
}
var a = fn();
console.log(a);
function fn(a, b) {
//return 把函数运行的结果 返回给函数调用
return a + b;
}
var res = fn(2, 5) + 3;
console.log(res);
// 1.如果函数没有return 默认返回undefined
// 2.函数体里面只有return return后边没有值 返回undefined
// 函数体里面return后面的代码不执行
// 4.有return并且后边有值 就是把return后边的值返回给函数调用
function fn(a,b) {
return a+b;
}
var res=(a+b);
console.log(res);
# 函数的优点
- 函数就是对一段代码的封装,在我们想调用的时候调用
- 函数的几个优点
- 封装代码,使代码更加简洁
- 复用,在重复功能的时候直接调用就好
- 代码执行时机,随时可以在我们想要执行的时候执行
# 小结
- 函数:把一些复用代码 封装 起来,在未来 调用;
- 需求:函数里面的功能不能写成固定代码;变活;
- 参数:
- 形参:函数内部的变量,只能在函数内部玩耍;函数的外面不能使用;即使外面的变量和内部的变量同名,也没有任何关系;
- 实参:实际参与运算的数据,把实参的数据,赋值(复制)了一份给形参;
- 返回:如何函数里面加工完结果,外面需要,设置返回值 return 数据;
- 核心:函数把代码分成 里面 和 外面;里面和外面没有任何关系;
- 两座桥:
- 外面的数据 怎么 进入函数内部?参数;
- 函数内部的数据怎么 给到函数的外面?返回值;
- 两座桥:
// 让用户输入任意两个数的和
// 函数声明的时候 小括号里面的是形参 形式上的参数
// 函数调用的时候,小括号里面的是实参
// 实参传值给形参 相当于给形参赋值
function getSum(a, b) {
var sum = 0;
for (i = a; i <= b; i++) {
sum += i;
}
console.log(sum);
}
getSum(1, 100);
# 习题
// 封装一个函数 比价a,b,c的大小
// function fn(a, b, c) {
// if (a > b && a > c) {
// return alert(a);
// } else if (b > a && b > c) {
// return alert(b);
// } else if (c > b && c > a) {
// return alert(c);
// }
// }
// fn(8, 4, 5)
// 封装一个函数 求n-m的和 比如用户输入了10 输入了100 求10-100的和
function sum(n, m) {
var sum = 0;
for (var i = n; i <= m; i++) {
sum += i;
}
return sum;
}
console.log(sum(10, 100));
var res = sum(10, 100);
// 封装一个冒泡排序的函数 输出排序之后的结果
function sort(arr1) {
for (var i = 0; i < arr1.length - 1; i++) {
for (var j = 0; j < arr1.length - 1 - i; j++) {
if (arr1[j] > arr1[j + 1]) {
var temp = arr1[j];
arr1[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr1;
}
var arr = [3, 3, 6, 2, 8, 3];
var res = sort(arr);
console.log(res);
// 封装判读一个数是否是质数的函数
var num = Number(prompt('请输入一个数字'));
function isZhiShu(a) {
for (var i = 2; i < a; i++) {
if (a % i == 0) {
return alert('不是质数');
}
}
return alert('质数');
}
isZhiShu(num)
# arguments 伪数组
// 封装一个函数 实现求任意个数的最大值
function getMax() {
// arguments伪数组 是把实参元素放到一个数组里面 方便
// console.log(arguments.length0);
// for(var i=0;i<arguments.length;i++){
// console.log(arguments[i]);
// }
var max = arguments[0];
for (var i = 1; i < arguments.length; i++) {
if (max < arguments[i]) {
max = arguments[i];
}
}
return max;
}
var res = getMax(12, 3, 5, 6, 365, 6555, 23);
console.log(res);
解决:多个参数的问题;
目标:无论输入多少个参数,都可以参加运算;
语法:arguments,获取所有实参的伪数组,函数内部的变量(不是我们声明的,也不需要我们声明)
function fn(){
console.log(arguments);
}
fn(1); // 输出 [1]
fn(1,2) // 输出 [1,2]
fn(1,2,3,4,5) // 输出 [1,2,3,4,5]
- arguments 这个东西看起来样子像数组,但是其实不是一个数组,我们管它叫
伪数组。它具有数组的长度和顺序等特征。本质为对象, - arguments 伪数组可以循环遍历;
function getSum(){
var sum = 0;
for(var i = 0; i < arguments.length ; i++){
sum += arguments[i];
}
return sum;
}
getSum(1,2,3);// 输出 6
getSum(1,2,3,4,5); // 输出15
- 应用场景:当我们不知道我们的参数个数的时候;
// 函数表达式 声明函数
var 函数名=function(){
函数体
}
var getSum=function(a,b){
console.log(a+b);
}
getSum(3,2);
# 函数表达式
- js中声明函数的方式不只有一种,还有一种方式叫
函数表达式; - 声明变量,赋值为函数;
//
var 函数名 = function (参数){
//函数体
}
var getSum = function(a,b){
return a + b;
}
getSum(10,20);
# 匿名函数
匿名函数:没有名字的函数,但是在js的语法中,是不允许匿名函数单独存在的,要配合其它语法使用:
如:
function (参数){
函数体
}
var fn = function(a,b){
return a + b;
}
- 自调用函数(自执行函数):匿名函数的另外一种使用方法;很多时候,我们需要加载页面后,自动执行一个函数;
// 定义之后,立刻调用,输出10
(function(){
console.log(10);
})();
//函数名里面存储的是函数的代码
//自调用函数(自执行函数) 自己调用自己 立即执行
// (匿名函数)();
(function(){
console.log(20);
})();
# 函数类型
function fn(){}
console.log(typeof fn); // 输出字符串的function
- 在js中,只要是一种数据类型的,都可以作为函数的参数,
function f1(a,b){
return a + b;
}
f1(10,20); // 数字作为参数
f1('abc','def') // 字符串作为参数
# 回调函数(了解)
- 函数有数据类型,也可以作为别的函数的参数传入;
// fn 只不过在函数内部是一个形参,内部变量;
function f1(a,fn){
console.log(a);
// 函数的调用,在函数名的后面加括号;
// 内部的函数对外面的函数叫回调函数;
fn();
}
function f2(){
console.log('f2函数执行了');
}
f1(10,f2);// 输出 10 和 'f2函数执行了'
- 像这种作为函数的参数,并在之内调用的函数,我们称为
回调函数;
# 作用域
- 全局:
- 全局作用域规则:全局的变量,能在JS部分的任何位置都可以访问;
- 全局变量:在全局作用哉下声明的变量;
- 局部:
- 局部作用域:只能在局部的作用域范围进行访问;
- 局部变量:在局部作用域下声明的变量;
var a = 10;
function f1(){
console.log(a);
}
f1();// 变量a在函数外定义,可以在函数内使用
function f2(){
var b = 20;
}
// 变量b在函数内定义,在函数外无法访问,报错: b is not defined
console.log(b);
// 作用域 生效的范围
// 全局作用域 在整个js代码都生效
// 全局变量 在函数外面用var声明的变量就是全局变量
// 局部作用域 在函数体里边生效
// 局部变量 在函数体里边用bar声明的变量
// 特殊情况 在函数体里边不用var 变量=赋值 是全局变量
// 特殊情况 函数形参是局部变量
# 作用域链
作用域链 这个变量当前作用域没有会去上一级找, 找到为止
# 预解析
// 预解析 就是js代码执行之前, 提升变量声明和函数声明 提升到当前作用域的最顶端
// 函数声明在最上边 变量声明次之
function fn() {
console.log(22);
}
var a;
console.log(a);
a = 20;
fu();
// console.log(a);
// var a = 20;
// fu();
// function fn() {
// console.log(22);
// }
# 利用函数完成数组冒泡从大到小排序 去重
// 使用函数完成数组冒泡排序和数组去重
function fn(arr1) {
for (i = 0; i < arr1.length - 1; i++) {
for (j = 0; j < arr1.length - 1 - i; j++) {
if (arr1[j] < arr1[j + 1]) {
var temp = arr1[j];
arr1[j] = arr1[j + 1];
arr1[j + 1] = temp;
}
}
}
return arr1;
}
var arr2 = [12, 52, 12, 16, 52, 100, 100]
var res = fn(arr2);
console.log(res);
function fn2(a) {
var newArr = []
for (i = 0; i < a.length - 1; i++) {
flag = true;
for (j = 0; j < a.length - 1 - i; j++) {
if (a[i] == newArr[j]) {
flag = false;
break;
}
}
if (flag) {
newArr[newArr.length] = a[i];
}
}
return newArr;
}
var tt = fn2(res);
console.log(tt);
# 案例小娜
# 字符串转数组的方法
var str = '来点字|哈哈哈|大傻瓜';
// 字符串转数组的方法
var arr = str.split('|');
console.log(arr);
//求和
var str = '1|2|3';
// 字符串转数组的方法
var arr = str.split('|');
var sum = 0;
for (i = 0; i < arr.length; i++) {
sum += Number(arr[i]);
}
console.log(sum);
// console.log(arr);
# 随机数
var joke = ['笑话1', '大傻瓜2', '笑话3'];
// joke[]
// Math是一个数学计算的对象
// 返回一个随机数 范围[0,1) 包含0不包含1
var a = Math.random();
a = a * joke.length;
a = Math.floor(a);
alert(joke[a]);
// function getSum() {
// var num = prompt('请输入1-2-3格式的数字');
// var arr = num.split('-');
// var sum = 0;
// for (var i = 0; i < arr.length; i++) {
// sum += Number(arr[i]);
// }
// alert(`求和的结果是${sum}`);
// }
// function getTime() {
// var time = new Date();
// var year = time.getFullYear();
// var month = time.getMonth() + 1;
// var day = time.getDate();
// var h = time.getHours();
// var f = time.getMinutes();
// var m = time.getSeconds();
// alert(`${year} 年 ${month} 月 ${day} 日 ${h} 时 ${f} 分 ${m} 秒`);
// }
// function getJoke() {
// var joke = ['笑话1哈哈哈', '笑话2大傻瓜', '笑话3喝多了', '笑话4吐一脸'];
// var i = Math.floor(Math.random() * joke.length);
// alert(joke[i]);
// }
var xiaoNa = {
getSum: function () {
var num = prompt('请输入1-2-3格式的数字');
var arr = num.split('-');
var sum = 0;
for (var i = 0; i < arr.length; i++) {
sum += Number(arr[i]);
}
alert(`求和的结果是${sum}`);
},
getTime:function () {
var time = new Date();
var year = time.getFullYear();
var month = time.getMonth() + 1;
var day = time.getDate();
var h = time.getHours();
var f = time.getMinutes();
var m = time.getSeconds();
alert(`${year} 年 ${month} 月 ${day} 日 ${h} 时 ${f} 分 ${m} 秒`);
},
getJoke:function() {
var joke = ['笑话1哈哈哈', '笑话2大傻瓜', '笑话3喝多了', '笑话4吐一脸'];
var i = Math.floor(Math.random() * joke.length);
alert(joke[i]);
}
}
var flag = true;
while (flag) {
var mes = prompt('您好,我是小娜,请选择操作的功能\n1.求和\n2.系统时间\n3.笑话\n4.退出');
switch (mes) {
case '1':
// getSum();
xiaoNa.getSum();
break;
case '2':
// getTime();
xiaoNa.getTime();
break;
case '3':
// getJoke();
xiaoNa.getJoke();
break;
case '4':
alert('你不爱小娜了吗')
flag = false;
break;
default:
alert('请输入1或2或3或4');
break;
}
}
# 对象
- JS核心概念:万物皆对象,我们在编程中,使用对象来描述万事万物。
- 对象:使用
属性描述事物的特征,使用方法来描述功能, 就是对象这种语法。 - 对象**:属性和方法的集合体**;
- 数组:数据集合体;
- 对象 描述 扳手 :
- 属性(特征):名称 金属、银白色,
- 方法:能拧螺丝、防身等;
# 创建对象
# 字面量创建对象
// 对象是属性和方法的几何体
// 字面量创建对象
var dog = {};
// 对象添加属性 对象.属性=值
dog.name = '旺财';
dog.age = 6;
// 对象添加方法 对象名.函数表达式
dog.height = 50;
dog.eat = function () {
console.log('吃骨头');
}
dog.cell = function () {
console.log('汪汪叫');
}
// 调用对象的属性 对象名.属性
console.log(dog.name);
// 调用对象的方法 对象名。方法名()
dog.eat();
# 通过字面量初始化对象时,初始化属性
// 2.字面量初始化对象;
var cat = {
// 添加属性 属性:值
// 键名 值 键值对
name: 'tom',
height: 30,
color: 'orange',
// 添加方法 方法名:匿名函数
eat: function () {
console.log('吃鱼肉');
},
play: function () {
console.log('玩球');
}
}
console.log(cat.name);
console.log(cat.height);
cat.eat();
# 使用键的方法添加属性和方法
// 使用键的方法添加属性和方法
var pig = {};
// 添加属性 对象名['属性']=值
pig['name'] = '佩奇';
pig.height = 172;
pig.weight = 172;
pig['age'] = 26;
// 添加方法 对象名['方法名']=匿名函数
pig['demo'] = function () {
console.log('敲代码');
}
console.log(pig['age']);
console.log(pig.name);
// 调用方法 对象名['方法名']()
pig['demo0']();
# 利用构造函数创建对象
构造函数
构造函数:是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与 new 运算符一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。
构造函数的封装格式:
function 构造函数名(形参1,形参2,形参3) { this.属性名1 = 参数1; this.属性名2 = 参数2; this.属性名3 = 参数3; this.方法名 = 函数体; }构造函数的调用格式
var obj = new 构造函数名(实参1,实参2,实参3)以上代码中,obj即接收到构造函数创建出来的对象。
//通过构造函数创建数组 // var arr = new Array(); // 构造函数 定义一类对象的属性和方法 // 1. 在构造函数代码开始执行之前,创建一个空对象; // 2. 修改this的指向,把this指向创建出来的空对象; // 3. 执行函数的代码 // 4. 在函数完成之后,返回this---即创建出来的对象 // 通过构造函数创建对象 // 构造函数 定义一类对象的属性和方法 function SuperStar(a, b, c) { // this.属性=形参接收过来的实参的值 this.name = a; this.age = b; this.height = c; this.sing = function (song) { console.log('经典老歌' + song); } } // 通过构造函数SuperStar这个构造函数创建ldh的对象 var ldh = new SuperStar('刘德华', '59', 172, '冰雨'); console.log(ldh); // 通过构造函数SuperStar这个构造函数创建gfc的对象 var gfc = new SuperStar('郭富城', '56', 172, '哈哈哈'); console.log(gfc); console.log(gfc.name); gfc.sing('爱不完');注意事项
- 构造函数约定首字母大写。
- 函数内的属性和方法前面需要添加 this ,表示当前对象的属性和方法。
- 构造函数中不需要 return 返回结果。
- 当我们创建对象的时候,必须用 new 来调用构造函数。
其他
构造函数,如 Stars(),抽象了对象的公共部分,封装到了函数里面,它泛指某一大类(class)
创建对象,如 new Stars(),特指某一个,通过 new 关键字创建对象的过程我们也称为对象实例化
new关键字的作用
- 在构造函数代码开始执行之前,创建一个空对象;
- 修改this的指向,把this指向创建出来的空对象;
- 执行函数的代码
- 在函数完成之后,返回this---即创建出来的对象
js 给我们内置了一个 Object 构造函数
这个构造函数就是用来创造对象的
当 构造函数 和 new 关键字连用的时候,就可以为我们创造出一个对象
因为 js 是一个动态的语言,那么我们就可以动态的向对象中添加成员了
# object创建对象
// 就能得到一个空对象
var o1 = new Object()
// 正常操作对象
o1.name = 'Jack'
o1.age = 18
o1.gender = '男'
# 对象使用for...in遍历
var ldh = {
name: '刘德华',
age: 59,
['height']: 172,
sing: function () {
console.log('冰雨');
},
['film']: function () {
console.log('赌神');
}
}
ldh['film']();
console.log(ldh);
// 遍历对象
//for (var key in obj) {
// }
for (var key in ldh) {
// 遍历键名
console.log(key);
// 遍历值
console.log(ldh[key]);
}
# 内置对象
//内置对象的学习方法
// 有没有实参
// 功能
// 返回值
// 圆周率
// console.log(Math.PI);
// 没有参数 返回一个[0,1)的随机浮点数(小数) 包含0 不包含1
var a = Math.random();
console.log(a);
// 返回一个0-10的随机整数
var b = parseInt(Math.random() * 11);
var arr = ['狗', '猫', '猴', '老虎'];
// 0-3的随机数
var c = parseInt(Math.random() * 4);
alert(arr[c]);
# es6模拟字符串
var a = 39, b = 28, c = 10;
// ${变量名} 其他的该怎么写怎么写
console.log(`a的大小是,${a}b的大小是,${b}c的大小是,${c}`);
document.write('<div style="width:100px; height:20px; background-color:skyblue"></div>');
// 随机数实现多线条
var h = parseInt(Math.random() * 31);
for (var i = 0; i <= h; i++) {
var x = parseInt(Math.random() * 256);
var y = parseInt(Math.random() * 256);
var z = parseInt(Math.random() * 256);
document.write(`<div style="height:40px; background-color:rgb(${x},${y},${z})"></div>`);
}
# 内置对象
# Math
- Math.random();这个方法的作用是生成一个 [0,1) 之间的随机浮点数
//没有参数 返回一个[0, 1)的随机浮点数(小数) 包含0,不包含1
// var a = Math.random();
// // console.log(a);
// // 返回一个0-10的随机整数
// var b = parseInt(Math.random()*11) // 0 - 10.99999999
// // console.log(b);
- Math.floor(x) 地板函数:把一个浮点数进行向下取整
console.log(Math.floor(3.1)); // 3
console.log(Math.floor(3.9)); // 3
console.log(Math.floor(-3.1)); // -4
console.log(Math.floor(-3.9)); // -4
- 案例:刷新页面,页面改变颜色;
function getRandom() {
return Math.floor(Math.random() * (255 + 1));
}
function getRandomColor() {
var r = getRandom();
var g = getRandom();
var b = getRandom();
var color = 'rgb(' + r + ',' + g + ',' + b + ')';
return color;
}
document.write(`<div style='background:${getRandomColor()}'></div>`)
- Math.round(x) 把一个浮点数进行四舍五入取整
console.log(Math.round(3.1)); // 3
console.log(Math.round(3.9)); // 4
console.log(Math.round(-3.1)); // -3
console.log(Math.round(-3.9)); // -4
- Math.ceil(x) :天花板函数 把一个浮点数进行向上取整,向比数据大的方向取整;
console.log(Math.ceil(3.1)); // 4
console.log(Math.ceil(3.9)); // 4
console.log(Math.ceil(-3.1)); // -3
console.log(Math.ceil(-3.9)); // -3
- Math.abs(x) :求一个数的绝对值 正数
console.log(Math.abs(3)); // 3
console.log(Math.abs(-3)); // 3
- Math.max(x,y...) 求多个数字中的最大值,同理 Math.min(x,y...);
console.log(Math.max(10,20)); // 20
console.log(Math.max(8,4,5,7,3)); // 8
console.log(Math.min(10,20)); // 10
console.log(Math.min(8,4,5,7,3)); // 3
# Date
var time = new Date();
// 获取系统年份
// console.log(time);
var year = time.getFullYear();
// console.log(year);
// 获取当前月份 月是从0-11 所以记得加一
var month = time.getMonth() + 1;
// console.log(m);
// 获得当前几号
var day = time.getDate();
// console.log(day);
// 获取周几
var week = time.getDay();
// console.log(week);
// 获取时
var h = time.getHours();
// console.log(h);
// 获取分
var f = time.getMinutes();
// console.log(f);
// 获取秒
var m = time.getSeconds();
var now = `${year}年${month}月${day}日${h}时${f}分${m}秒`;
console.log(now);
创建指定的时间对象
// 创建指定的时间对象
var time = new Date('2015-10-10 15:30:20');
var h = time.getHours();
// console.log(h);
console.log(time);
var time = new Date(2015, 9, 10, 15, 12, 23);
console.log(time);
# 时间戳
// 时间戳
// var time=new Date();
// console.log(time.valueOf());
// console.log(time.getTime());
// console.log(1*time);
// console.log(Date.now());
// h5新增加的时间戳的写法 某一个时间点据世界时间(1970年1月1日)的总毫秒数
// var time=+new Date();
// console.log(time);
// 倒计时
// 距现在的时间戳
var now = + new Date();
// console.log(now);
// 距将来19点的时间戳
var fut = +new Date('2020-12-10 19:00:00');
// 将来总毫秒-现在的总毫秒数
var time = fut - now;
var miao = Math.floor(time / 1000 % 60);
var fen = Math.floor(time / 1000 / 60 % 60);
var xiaoshi = Math.floor(time / 1000 / 60 / 60 % 24);
console.log(`${xiaoshi}时${fen}分${miao}秒`);
# 简单类型和复杂类型
# 规则
- JS 数据都是存在内存上的,内存上分为两个地方: 栈 堆;只要var 变量,就要在 栈上开个格子;
- 简单类型 存储在内存的栈空间中
- 复杂类型 存储在内存的堆空间中
# 简单类型的储存
// 简单数据类型
function fn(b) {
// 局部变量b
b = 2;
}
var a = 1;
fn(a)
// b = a;
console.log(a); // ?

# 复杂类型的储存
// 复制数据类型
function f2(o) {
o.name = '翠花';
}
var a = {
name: '狗蛋'
}
f2(a);
// 最终a的name属性是多少?翠花
console.log(a.name);

- 练习:
var obj_a = {};
var obj_b = obj_a;
// true 同类型,比值:同一个地址
console.log(obj_b == obj_a);
// false 同类型,比值:不同的地址;
var obj_a = {};
var obj_b = {};
console.log({} == {});
# 变量 属性 函数 方法的区别
1.变量和属性的相同点 他们都是用来存储数据的
- 变量 单独声明并赋值 使用的时候直接写变量名 单独存在的
- 属性 在对象里面的不需要声明的 使用的时候必须是对象.属性 2.函数和方法 的相同点 都是实现某种功能 做某种事
- 函数是单独声明 并且调用的 函数名() 单独存在的
- 方法 在对象里面 调用的时候对象.方法
# 内置对象
# Array数组
# 数组首末位置的增删
/* 内置对象的学习方法
有没有参数
功能
返回值 */
var arr = [1, 2, 3];
// 数组名.push[参数1, 参数2, 参数3]; 有参数 个数不固定 功能在数组的末尾添加元素 返回数组的长度
var a = arr.push(4, 5, 6);
console.log(a);
// 数组名.unshift(参数1, 参数2, ...参数n) 有参数 个数不固定 功能 在数组的起始处添加元素 返回数组长度
var b = arr.unshift(7, 8, 9);
console.log(b);
// 数组名.pop() 无参 功能 删除数组的最后一个元素 返回被删除的元素
var c = arr.pop();
console.log(c);
// 数组名.shift() 无参 功能 删除数组的第一个元素 返回的是被删除的元素
var d = arr.shift();
console.log(d);
# splice:可进行数组任何位置的增删改
// 数组的splice方法用于从数组的指定位置移除、添加、替换元素
var arr = ['a','b','c','d','e'];
// arr.splice(a,b,c...n) 有参 第一个参是索引 功能第2个参是索引开始删除的个数,第三个参开始 从索引的前边开始添加元素 返回的是数组 如果有删除的元素,数组里面是删除元素
// 对原数组操作
// 作用:从索引3开始移除,总共移除1个元素 ,
// 返回:被移除元素的数组
arr.splice(3,1);
console.log(arr);
// 在c的后面添加7和8两个元素
// 作用:从索引3开始添加,移除0个元素,把7,8加入;
// 返回:一个空数组
// 操作原数组;
arr.splice(3,0,7,8);
// 作用:从索引1开始替换,总共替换1个,用0替换 ;
// 返回:被替换元素的数组
arr.splice(1,1,0);
console.log(arr);
# 拼接与截取
- concat 拼接数组,不改变原数组,创建新数组返回
// concat
// 作用:数组的拼接
// 参数:要拼接的数据(单个数据、多个数据、单个数组,多个数组)
// 返回:拼接后的 新 数组;
// var arr1 = [1, 2, 3];
// var arr2 = [4, 5, 6];
// var arr3 = [7, 8, 9];
// var res = arr1.concat(arr2, arr3);
// console.log(arr1, res);
- slice 截取数组:不对原数组操作,返回的是截取出来新的数组;
// slice:
// 作用:截取数组
// 参数:
// 返回:被截取的新数组;
var arr = ['a', 'b', 'c', 'd', 'e'];
// 参数:2个参数。第一个参数从哪个下标开始(包括),截取到哪个下标结束(不包括),
// var res = arr.slice(1, 4);
// console.log(arr, res);
// 参数:1个参数,从哪个下标开始,一直到结尾都要截取
// var arr_1 = arr.slice(1);
// console.log(arr_1);
// 参数:没有参数,全部截取,复制数组;
// var res = arr.slice();
# 与字符串互转
- join 用于将数组中的多元素以指定分隔符连接成一个字符串
// 数组名.join() 有参(可以无参) 功能数组转字符串 参数是分隔符 返回的是转换之后的字符串
var arr = ['刘备','关羽','张飞'];
var str = arr.join('|');
console.log(str); // 刘备|关羽|张飞
- split 字符串的方法:转数字,后面为分隔的字符
// 字符串.split() 有参(可以无参) 功能是字符串转数组 参数是分隔符 返回转换之后的数组
// 这个方法用于将一个字符串以指定的符号分割成数组
var str = '刘备|关羽|张飞';
var arr = str.split('|');
console.log(arr);
# 查找元素
- indexOf:根据元素查找索引,如果这个元素在数组中,返回索引,否则返回-1,找元素在不在数组内部
// indexOf 【!!!】
// 参数:被查找的元素
// 返回:下标(没有找到返回-1)
// 场景:查找数组中有没有我们需要的数据;
// var arr = [1, 10, 20];
// var index = arr.indexOf("a");
// console.log(index);
// 数组名.indexOf() 有参 功能 查找 正向查找参数是不是数组的元素 如果是 返回的第一个查找的元素索引值
var arr1 = ['a', 'd', 'c', 'd', 'e'];
var index = arr1.indexOf('d');
console.log(index);
// 数组名.lastIndexOf() 有参 功能 查找 反向查找参数是不是数组的元素 如果是 返回的第一个查找的元素索引值
var arr1 = ['a', 'd', 'c', 'd', 'e'];
var index = arr1.lastIndexOf('d');
console.log(index);
- findIndex方法用于查找满足条件的第一个元素的索引,如果没有,则返回-1 了解;
// findIndex
// 语法:
// 参数:函数(被传入的函数,回调函数)
// 格式要求:
// item 回调函数,代表每一次遍历的数据
// return 判断条件(自己写)
// 返回:满足条件的第一个元素的下标,若没有,返回-1;
// var index = arr.findIndex(function(item) {
// return item === 20;
// });
// console.log(index);
// 数组名.findIndex(匿名函数) 有参 参是匿名函数 功能正向查找 满足条件的元素 返回的是正向第一个满足条件的元素的索引值
var arr = [10, 20, 30, 40, 50];
var res = arr.findIndex(function (item) {
return item > 20;
});
console.log(res);
# 遍历数组
- for循环:JS基础语法;【!!!】
- forEach:遍历数组;
// 如何学习?关注参数?返回是什么?
// 不关注什么?内部如何实现不用关注。3年后可以看内部如何实现;
// forEach:
// 作用:遍历数组
// 参数:函数(函数函数)格式要求:
// 函数函数参数:item,index,arr
// item:每个数据
// index:下标;
// arr:当前遍历的数组;
// var max = arr[1];
// arr.forEach(function(item, index, arr) {
// // console.log(item, index, arr);
// if (item > max) {
// max = item;
// }
// });
// console.log(max);
// 数组名.forEach(function (item, index, arr){
// item 是数组的每一项元素
// index 索引
// arr 当前遍历的数组
// })
var arr = [10, 20, 30, 40, 50];
var sum = 0;
arr.forEach(function (item, index, arr) {
sum += item;
})
console.log(sum);
- filter 筛选出数组中满足条件的数组,返回是一个新的数组;
// filter
// 作用:对当前数组一定的过滤;
// 参数:函数(函数函数)格式要求:
// 函数函数参数:item,index,arr
// item:每个数据
// index:下标;
// arr:当前遍历的数组;
// return 过滤条件; 返回是true,把当前满足条件的item 放入新的数组中
// 返回:返回过滤后的新数组;
var arr_1 = arr.filter(function(item, index, arr) {
// 过滤条件; 返回是true,把当前满足条件的item 放入新的数组中
return item == 10;
});
console.log(arr, arr_1);
// 数组名.filter(function(item,index,arr){
// /* return 条件
// item 当前数组的每一项
// index 索引
// arr 当前组
// 参数是匿名函数 功能筛选条件 返回满足条件的数组 数组里面是满足条件的元素 如果不满足条件 返回的是空数组
// */
// }
// )
var abc = [10, 20, 30, 40, 50];
var res = abc.filter(function (item, index, arr) {
return item > 10;
})
console.log(res);
# 数组去重
var arr = [12, 2, 2, 12, 3, 6, 2, 8, 2];
newArr = [];
// 思路: 用原数组中的每一项去新数组中查询 如果不存在 添加到新数组
for (var i = 0; i < arr.length; i++) {
// 用老数组中每一项去新数组中查询 返回-1说明老数组这一项 在新数组中不存在
if (newArr.indexOf(arr[i]) == -1) {
// 老数组中的这一项添加到新数组
newArr.push(arr[i]);
}
}
console.log(newArr);
# 冒泡排序
var arr = [15, 6, 8, 45]
var res = arr.sort(function (a, b) {
return a - b;
})
console.log(res);
# 字符串
# String
# 不可变
特性:不可变性;
旧的字符串赋值在一个变量上,给变量重新赋值新的字符串(完全新的字符串,或者拼接后字符串),旧的字符串不是被覆盖;在内存的游离状态;
所以尽量避免大量使用字符串的拼接;这个算前端性能优化的一点;
- 提升前端性能:
# 查找
- indexOf 字符串中是否存在指定字符 存在就返回找到的下标,没有就-1;
// 这个方法用于查找某个字符串是否包含于另一个字符串
var str = '我爱中华人民共和国';
console.log(str.indexOf('中华'));
- lastIndexOf 用法和indexOf一样,只不过是从后面开始找,【了解】;
- charAt:【了解】
// 这个方法用于获取字符串中位于指定位置的字符
var str = '我爱中华人民共和国';
console.log(str.charAt(2));
- charCodeAt :【了解】
// 这个方法用于获取字符串中位于指定位置的字符的ASCII码
var str = 'abcdef'
console.log(str.charCodeAt(0));
# 转为数组
- split 字符串转数组,后面的分隔的字符
// 这个方法用于将一个字符串以指定的符号分割成数组
var str = '刘备|关羽|张飞';
var arr = str.split('|');
console.log(arr);
- 案例:解析地址
b.com?id=1&name=2中的参数;
# 拼接与截取
- +隐式转化;
- concat 拼接
- 两者的区别:https://www.cnblogs.com/zheting/p/7643458.html
// 这个方法用于连接多个字符串;
var res = "abc".concat('def','ghi');
console.log(res);
- substring 截取字符串,不操作原字符串;返回截取出来的字符串;
// 这个方法用于获取字符串中的部分字符
var str = '我爱中华人民共和国';
// 从索引2开始,到索引4结束,得到之间的字符,不包含索引4的字符
var res = str.substring(2,4);
console.log(res);
- slice
// 这个方法用于获取字符串中的部分字符
var str = '我爱中华人民共和国';
var res = str.slice(2,4);// 从索引2开始,到索引4结束,得到之间的字符,不包含索引4的字符
console.log(res);
// 看起来和substring 没有啥区别,
// 但是 slice()可以设置参数为负数,slice()方法在遇到负的参数的时候,会将这个负值与字符串的长度相加。
console.log(str.slice(-6,7));
console.log(str.slice(2,-5));
console.log(str.slice(-9,-7));
- substr
// 这个方法用于获取字符串中的部分字符
// 字符串.substr(索引, 截取的个数) 有参(最少一个) 功能 截取字符串从索引开始 第2个参 截取的个数
var str = '我爱中华人民共和国';
var res = str.substr(2,2);// 索引2开始,总共获取2个字符,第二个参数为个数
# 索引
// 字符串方法
var str = '西红柿土豆西瓜'
// 字符串的长度 字符串.length
console.log(str.length);
for (i = 0; i < str.length; i++) {
console.log(str[i]);
}
// 字符串.indexOf(参) 有参 功能正向查找 返回正向查找存在该字符 返回第一个的索引值 如果查找不到 返回-1
var a = str.indexOf('西');
console.log(a);
// 字符串.indexOf(参) 有参 功能反向查找 返回反向查找存在该字符 返回第一个的索引值 如果查找不到 返回-1
var b = str.lastIndexOf('西');
console.log(b);
// 字符串.charAt(参) 功能参数是索引值 根据索引找字符 返回 索引位置对应的字符
// var str = '西红柿土豆西瓜';
// console.log(str.charAt(2));
var str = '西红柿土豆西瓜';
for (var i = 0; i < str.length; i++) {
console.log(str.charAt(i));
}
// 字符串.charCodeAt(索引值) 有参 功能 根据索引找到字符 返回的是ascll编码
var str = 'a西红柿土豆西瓜';
var b = str.charCodeAt(0);
console.log(b);
# 字符串分割小案例
// b.com?id=1&name=2 实现的功能 var obj = { id:1, name: 2 }
var str = 'b.com?id=1&name=2';
var obj = {};
// ["b.com", "id=1&name=2"]
var arr1 = str.split('?');
// console.log(arr1);
// ["id=1", "name=2"]
var arr2 = arr1[1].split('&');
// console.log(arr2);
for (i = 0; i < arr2.length; i++) {
var arr3 = arr2[i].split('=');
var key = arr3[0];
obj[key] = arr3[1];
}
console.log(obj);
# 字符串的拼接截取
// 字符串.concat(字符串1,字符串2...) 有参 ,功能 拼接字符串 返回的是拼接之后的字符串
var str = '哈哈哈';
var str1 = '土豆';
var str2 = '西红柿';
var b = str.concat(str1, str2);
console.log(b);
var str = '我爱中华人民共和国';
//字符串 .substring (索引值 ,索引值)有参 (最少一个) 功能 截取字符串[索引值,索引值) 返回的是截取的字符串
var b = str.substring(3, 6);
console.log(b);
var str = '我爱中华人民共和国';
var a = str.slice(2, 5);
// 特殊情况 如果索引值出现负值 开始的长度(索引+字符串.length)
var a = str.slice(-10, 5);
console.log(a);
# 字符串出现的次数案例
var str = 'abccccccaaabbdet'
var obj = {
// 'a': 1,
}
for (var i = 0; i < str.length; i++) {
var chars = str.charAt(i);
// 判断对象中有没有chars属性
if (obj[chars]) {
obj[chars]++;
} else {
// 给对象添加属性和值
obj[chars] = 1;
}
}
var max = 0;
for (var key in obj) {
if (max < obj[key]) {
max = obj[key];
var zf = key;
}
}
console.log(max, zf);
let var cos
// let: 每次循环生成一个独立的块作用域 {i = 0}
// var 声明的变量,只要是函数外边,是全局变量,let 和 const 生效范围是块级作用域
// var 声明的变量可以重复声明,let 和 const 不可以 const 多次赋值都不行
// var 和 let 只声明,不赋值, undefined const 必须赋值,不赋值,会报错
// var 声明的在window有映射,let 和 const没有
// var 声明的变量会预解析提升,let 和 const 不会
// es6 函数里边和函数外边 块级作用域 {}
# 文档
MDN - https://developer.mozilla.org/zh-CN/ (opens new window) - 这个东西跟百度一样使用即可 - 最推荐 - 官方比较权威的,新且全;
百度
菜鸟 - https://www.runoob.com/ (opens new window) 也是跟普通的论坛一样使用即可
如何学习一个方法(对象)
- 1.方法的功能是什么
2.方法的参数有哪些
3.方法的返回值是什么