JavaScript介绍
为什么要学JavaScript?
网页三部分
- html:控制网页的结构
- css:控制网页的样式
- js:控制网页的逻辑
最初的javascript
- 用于判断客户端的输入(表单校验)
- 后来一度被用作小广告
现在的JavaScript:
现在的JS无所不能
- 异步与服务器交互(AJAX)
- 网页和特效
- 服务端开发(nodejs)
- 命令行工具开发(nodejs)
- 桌面程序(Electron)
- app开发(Cordova)
- 控制硬件--物联网(Ruff)
- 游戏开发(cavans, cocos2d-js)
演示:
什么是JavaScript?
JavaScript是一种运行在浏览器端 的脚本语言 , 现在也可以运行在服务端
不同于HTML和css,JavaScript是一门编程语言,因此要比HTML和css复杂一些,学习的时间也更长。
JavaScript历史
- 1995年,Netscape(网景)公司的
Brendan Eich(布兰登·艾奇)
(伊利诺伊大学香槟分校),花了10天时间为Netscape Navigator2.0开发了一个位置为LiveScript
的脚本程序,目的是在浏览器中执行预检测程序(表单校验) - 后来Netscape在与Sun合作之后将其改名为JavaScript。目的是为了利用 Java 这个因特网时髦词汇。
- 微软发布了 IE 3.0 并搭载了一个 JavaScript 的克隆版,叫做 JScript(这样命名是为了避免与 Netscape 潜在的许可纠纷)
- 三足鼎立阶段:
- CEnvi的scriptEase
- Netscape的JavaScript
- IE的JScript
- 标准化阶段:1997年,ECMA(欧洲计算机制造商协会)邀请了Netscape、Sun、微软、Borland等公司的一些程序员组成了TC39,最终锤炼出来了ECMA-262,该标准定义了一门全新的脚本语言,名为
ECMAScript
。
javascript的组成
ECMAScript - JavaScript的核心
定义了JavaScript的语法规范
JavaScript的核心,描述了语言的基本语法和数据类型,ECMAScript是一套标准,定义了一种语言的标准与具体实现无关
BOM - 浏览器对象模型
一套操作浏览器功能的API
通过BOM可以操作浏览器窗口,比如:弹出框、控制浏览器跳转、获取分辨率等
DOM - 文档对象模型
一套操作页面元素的API
DOM可以把HTML看做是文档树,通过DOM提供的API可以对树上的节点进行操作
JavaScript入门
JavaScript书写位置
JavaScript的代码书写分为两种:
- 写在
script
标签中
<script>
alert('Hello World!');
</script>
- 引入一个js文件
<script src="main.js"></script>
注意:如果script标签指定了src属性,表示引入一个外部的文件,就不能在写javascript代码了
注释
注释代码不会被执行,仅仅起到一个提示的作用。注释可以对复杂的代码进行解释,方便后期的维护和开发。
- 单行注释
// 这是单行注释, 单行注释只能写一行代码
// 快捷键: ctrl + /
- 多行注释
/*
这是多行注释,在多行注释中可以
换行
快捷键 ctrl + shift + /
/*
【永无bug.js】
在写代码的时候,需要写注释,这是一个良好的习惯
输出语句
- 警告框
alert
//alert会弹出一个警告框
alert("hello world");
- 确认框
confirm
//confirm弹出一个确定框
confirm("你爱我吗?");
- 输入框
prompt
//prompt:弹出一个输入框,可以输入值
prompt("请输入你的银行卡密码");
- 在网页中输入内容
//可以识别标签
document.write("hello world");
document.write("<h1>hello world</h1>");
- 在控制台输入
//F12打开控制台,在console中可以看到打印的信息
console.log("hello word");
总结:alert、comfirm、prompt三个用户体验太差,只有在学习的时候会用到。console.log
经常用来打印日志,调试的时候非常有用。
变量
变量:可以变化的量。
变量的作用是:存储数据
如何使用变量
- var声明变量
var age;
- 变量的赋值
var age;
age = 18;
- 同时声明并且赋值
var age = 18;
- 同时声明多个变量并赋值
var age = 10, name = 'zs';
- 不声明变量,直接赋值(不会报错,但是不推荐)
age = 18;
console.log(age);
- 不声明变量,也不赋值变量,直接使用(会报错)
console.log(age);
结论:
- 变量需要声明之后,才能使用,养成一个良好的编程习惯。
- javascript代码一旦报错了,后面的代码就不再执行了。
变量的命名规则和规范
规则 - 必须遵守的,不遵守会报错
- 由字母、数字、下划线、$符号组成,不能以数字开头
- 不能是关键字和保留字,(不用死记,慢慢就见得多了)
- 区分大小写
规范 - 建议遵守的,不遵守不会报错
- 变量名必须有意义
- 遵守驼峰命名法。首字母小写,后面单词的首字母需要大写。例如:myName、userPassword
下面哪些变量名不合法
a 1 age18 18age 2b name $name _sex &sex theworld a b
关键字:
保留字:
变量的练习
- 交换两个变量的值
数据类型
javascript中数据类型分为简单数据类型和复杂数据类型,今天只学简单数据类型
number、string、boolean、undefined、null
number-数字类型
数字: 11 255 333 1024
浮点数
浮点数就是小数,,比如0.1
- 浮点数
var num = 0.1;
- 浮点数精度丢失问题
//在进行浮点数运算的时候,可能会出现精度丢失的问题
0.1 + 0.2 = 0.30000000000000004;
0.2 + 0.2 = 0.4;
//尽量少用浮点数进行运算,不要让浮点数进行比较。
字符串类型
字符串类型,使用双引号 "
或者 '
包裹起来的字符
//双引号和单引号必须成对出现
var str = 'hello world';
var str = "hello world";
字符串长度
每一个字符串都有一个length属性,可以获取到字符串中字符串的个数
var str = "akdjflksjdflk";
console.log(str.length);
转义字符
思考,如何打印?
//我是一个"老实"的人.
//选择"好看"的外表,还是'有趣'的灵魂
字符串拼接
+
号具有字符串拼接功能,它能将两个字符串拼接成一个字符串。+
号同时具有算术加法的功能,它能将两个数字进行相加- 如果
+
号两边有一个是字符串,那么就是拼串的功能,如果都是数字,那么就是算数的功能。
var a = "hello";
var b = "itcast";
console.log(a + b);//字符串拼接功能
var a = "100";
var b = 100;
console.log(a + b);//字符串拼接功能
var a = 100;
var b = 100;
console.log(a + b);//加法功能
布尔类型
布尔类型:true 和 false
//布尔类型只有两个值
true:表示真
false:表示假
注意:区分大小写,不要写成True或者是False了
undefined和null
- undefined表示一个没有赋值的变量
- null表示一个空的对象
字面量与变量
- 字面量,也叫直接量,值是固定不变的,浏览器能够直接识别的量,比如
11, "abc", true, false, undefined, null
等都是字面量,可以直接会使用。 - 变量:浏览器必须要经过声明之后,才认识变量,如果没有声明,直接使用变量是会报错的。
操作符
变量可以存储数据,我们还需要学习操作符来操作这些数据
算术运算符
//快速的说出以下的结果?
console.log(123 + 123);
console.log("123" + 123);
console.log(123 - 123);
console.log(123 - "123");
console.log(12 * "12");
console.log(12 / 12);
console.log(10 % 2);
赋值运算符
赋值运算符有: = , +=, -=, *=, /=, %=
var num = 10;
num += 1; //num = num + 1;
num -= 1; //num = num - 1;
num *= 2; //num = num * 2;
num /= 2; //num = num / 2;
num % = 2; //num = num % 2;
一元运算符
一元运算符:只有一个操作数的运算符
二元运算符:有两个操作数的运算符,比如算术运算符、赋值运算符
自增运算符:++
- 先自增:
++i
- 后自增:
i++
//先自增:
var num = 1;
console.log(++num); //先自增:表示先加1,后返回值
//后自增:
var num = 1;
console.log(num++);// 后自增:表示先返回值,后+1
自减运算符:--
- 先自减:
--i
- 后自减:
i--
练习:
//1. 思考思考
var num = 5;
console.log(num++);
console.log(++num);
//2. 猜猜看
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);
逻辑运算符
&&
:与运算符,表示且,只有当两个操作数都为true
的时候,结果才是true
||
:或运算符,表示或,只要有其中一个操作数是true
,结果就是true
!
:非运算符,取反
console.log( true && true );
console.log( false && true );
console.log( true && false );
console.log( false && false );
console.log( true || true );
console.log( false || true );
console.log( true || false );
console.log( false || false );
console.log(!true);
console.log(!false);
比较运算符
比较运算符也叫关系运算符, < > >= <= == != === !==, 关系运算符的结果是布尔类型
var a = 5;
var b = 6;
console.log(a > b);//大于
console.log(a < b);//小于
console.log(a >= b);//大于等于
console.log(a <= b);//小于等于
console.log(a == b); //相等,只比较值,不比较类型
console.log(a === b); //全等,比较类型和值
console.log(a != b); // 不等, 只判断值,不判断类型
console.log(a !== b); // 不全等 判断值,且判断类型
运算符优先级
()
的优先级最高- 一元运算符(++, --, !)
- 算术运算符(先
*/%
, 后+-
) - 关系运算符 (先
> < >= <=
, 后== === != !==
) - 逻辑运算符(先
&&
后||
)
不用死记,如果不确定的时候,使用()增加优先级
//猜猜看
var result = ((4 >= 6) || ("人" != "狗")) && !(((12 * 2) == 144) && true);
console.log(result);
//蒙一下
var num = 10;
console.log(5 == num / 2 && (2 + 2 * num).toString() === "22");
类型转换
查看变量的类型
typeof关键字可以查看数据的类型
var num = 11;
console.log(typeof num);
num = "abc";
console.log(typeof num);
**小技巧:在控制台可以根据颜色来判断数据的类型哦(^__^) **
转换成字符串
- toString()
var num = 5;
console.log(num.toString());// 把数值5变成字符串5
//将来所有的数据都会有toString()方法,除了null和undefined
- String()
var num = 5;
num = String(num);
console.log(num);
- 拼串,使用起来最方便
var num = 5;
num = num + "";
console.log(num);
转换成数字类型
- Number()
console.log(Number('55'));
Number()可以把任意值转换成数值类型,但是如果字符串中有不是数字的字符,返回NaN
- parseInt()
var num1 = parseInt("12.3abc"); // 返回12,如果第一个字符是数字会解析知道遇到非数字结束
var num2 = parseInt("abc123"); // 返回NaN,如果第一个字符不是数字或者符号就返回NaN
- parseFloat()
parseFloat()把字符串转换成浮点数
parseFloat()和parseInt()非常相似,不同之处在与
parseFloat会解析第一个. 遇到第二个.或者非数字结束
如果解析的内容里只有整数,解析成整数
- 算术运算
var str = '500';
console.log(+str); // 取正
console.log(-str); // 取负
console.log(str - 0);
转换成布尔类型
所有的值都可以转换成布尔类型
其中,""
,NaN
,undefined
,null
,0
,false
这几个值会转换成false,其他值都会转换成true
- Boolean()
console.log(Boolean(1));
console.log(Boolean(0));
- !!
var a = "abc";
console.log(!!a);
NaN
NaN: not a number, 表示一个非数字
在js中,NaN用来表示一个非数字的特殊值,当发现无法进行运算时,js不会报错,而是会返回一个NaN
NaN的注意事项:
- NaN的类型是number类型的,表示一个非数字
- NaN不等于任何值,包括NaN本身
- 通过isNaN()可以判断是否是一个数字,返回false的时候,表示是一个数字。
var num = 5;
console.log(isNaN(5));
流程控制
程序的三种基本结构
顺序结构
从上到下执行的代码就是顺序结构
程序默认就是由上到下一行一行的顺序执行的
console.log("哈哈1");
console.log("哈哈2");
console.log("哈哈3");
分支结构
分支结构,也叫选择结构,根据不同的情况,执行对应代码
循环结构
循环结构:重复做一件事情
分支结构
if语句
- 单独的if语句
//语法
if (条件){
//只有当条件为 true 时执行的代码
}
var age = 8;
if(age < 12) {
console.log("不准玩王者荣耀");
}
- if..else语句
if (条件){
//当条件为 true 时执行的代码
} else {
//当条件不为 true 时执行的代码
}
var age = 8;
if(age < 12) {
console.log("不准玩王者荣耀");
}else {
console.log("可以玩王者荣耀");
}
- if..else if..else语句
if (条件 1){
//当条件 1 为 true 时执行的代码
} else if (条件 2) {
//当条件 2 为 true 时执行的代码
} else {
//当条件 1 和 条件 2 都不为 true 时执行的代码
}
var age = 8;
if(age < 12) {
console.log("不准玩王者荣耀");
}else if(age < 18){
console.log("可以玩王者荣耀2个小时");
}else {
console.log("可以玩王者荣耀一天");
}
案例:
1. 判断一个数是偶数还是奇数
2. 判断年龄大于16,并且是个男孩,就可以开始撩妹了
3. 如果你有钱 或者 你很帅 ,就可以很快找到女朋友
3. 素质教育,把百分制分数转换成ABCDE
A: 90-100
B: 80-89
C: 70-79
D: 60-69
E: 0-59
三元运算符
用法1:
var 结果 = 判断条件 ? 值1 : 值2
如果判断条件为true, 结果就是值1, 如果为false, 结果就是 值2
案例:
//思考1:求两个数的最小值
//思考2:判断成年还是未成年
//思考3:求三个数的最小值
switch语句
if..else适用于范围的判断,switch..case适用于具体的值的判断
语法格式:
switch (变量) {
case 值1:
语句1;
break;
case 值2:
语句2;
break;
case 值3:
语句3;
break;
…
default:
默认语句;
break;
}
注意:
break可以省略,如果省略,代码会继续执行下一个case
switch 语句在比较值时使用的是全等操作符, 因此不会发生类型转换(例如,字符串'10' 不等于数值 10)
案例:
输入一个数字,显示星期几
素质教育(把分数变成ABCDE)千万不要写100个case哟
//测试题:
var num = "10";
switch (num) {
case 10:
console.log("10");
case 20:
console.log("20");
case 30:
console.log("30");
default:
console.log("lalala");
}
使用场景
- 如果是范围性的判断,使用if..else会更加方便
- 如果是对具体值的判断,使用switch..case语句会更加方便,当然用if..else也是可以的。
- 如果if..else比较简单,可以使用三元运算符进行替代。
//练习1:土豪的儿子, 输入ABCDE
//如果考了A: 买玛莎拉蒂
//如果考了B: 买宝马
//如果考了C: 买三轮
//如果考了D: 买摩拜自行车
//如果考了E: 断绝父子关系
//如果是其他值,提示代码有bug
//练习2: 买手机,输入自己的工资
//如果超过30000: 买苹果手机
//如果10000-30000: 买vivo手机
//如果5000-10000 : 买魅族手机
//如果低于5000 : 还买个锤子
//练习3: 输入自己的银行卡金额
//如果超过1000W : 高富帅
//如果不超过 :穷矮丑
循环语句
在javascript中,循环语句有三种,while、do..while、for循环。
while循环
基本语法:
//当循环条件为true时,执行循环体,
//当循环条件为false时,结束循环。
while(循环条件){
//循环体:需要循环执行的语句
}
代码示例:
//计算1-100之间所有数的和
//1. 初始化变量
var i = 1;
var sum = 0;
while(i <= 100){//判断条件
sum += i;//循环体
i++;//自增,修改循环条件(不能省略)
}
console.log(sum);
练习:
//1. 计算所有偶数的和
//2. 循环表白案例
//3. 循环登录案例,只有当用户输入admin的时候才能登录成功,否则一直弹框
do..while循环
do..while循环和while循环非常像,二者经常可以相互替代,但是do..while的特点是不管条件成不成立,都会执行一次。
基础语法:
do{
//循环体;
}while(循环条件);
代码示例:
//初始化变量
var i = 1;
var sum = 0;
do{
sum += i;//循环体
i++;//自增
}while(i <= 100);//循环条件
思考:
// 1. 计算所有偶数的和
// 2. 循环输入账号密码的案例用do..while怎么写?
// 3. 循环表白的案例用do..while怎么写?
思考:
// while循环与do..while循环的区别是啥?
断点调试
断点调试是指自己在程序的某一行设置一个断点,调试时,程序运行到这一行就会停住,然后你可以一步一步往下调试,调试过程中可以看各个变量当前的值,出错的话,调试到出错的代码行即显示错误,停下。
调试步骤:
浏览器中按F12-->sources-->找到需要调试的文件-->在程序的某一行设置断点
调试中的相关操作:
Watch:监视,通过watch可以监视变量的值的变化,非常的常用。
F10:程序单步执行,让程序一行一行的执行,这个时候,观察watch中变量的值的变化。
F8:跳到下一个断点处,如果后面没有断点了,则程序执行结束。
苦口婆心一下:
- 代码调试的能力非常重要,只有学会了代码调试,才能学会自己解决bug的能力。初学者不要觉得调试代码麻烦就不去调试,知识点花点功夫肯定学的会,但是代码调试这个东西,自己不去练,永远都学不会。
- 今天学的代码调试非常的简单,只要求同学们记住代码调试的这几个按钮的作用即可,后面还会学到很多的代码调试技巧。
for循环(重点)
写while循环的经常会忘记自增,for循环其实是while循环演化过来的,语法更加的简洁明了,使用非常的广泛。
for循环语法:
//1. for循环使用分号分隔
//2. for循环有2个分号,两个分号不能少
for(初始化语句;判断语句;自增语句){
//循环体
}
执行顺序:1243 ---- 243 -----243(直到循环条件变成false)
- 初始化语句
- 判断语句
- 自增或者自减
- 循环体
for循环代码示例:
//计算1-100之间所有数的和
var sum = 0;
for(var i = 1; i <= 100; i++){
sum += i;
}
思考1:
//1 求1-100之间所有数的和、平均值
//2 求1-100之间所有数的乘积
//3 计算1-100之间能3整除的数的和
思考2:
//1 计算1-100之间不能被7整除的数的和
//2 求1-100之间所有偶数的和
//3 同时求1-100之间所有偶数和奇数的和
思考3(双重for循环):
//1 打印正方形
//2 打印直角三角形
//3 打印9*9乘法表
break和continue
break:立即跳出整个循环,即循环结束,开始执行循环后面的内容(直接跳到大括号)
continue:立即跳出当前循环,继续下一次循环(跳到i++的地方)
思考:
//1. 找到1-100之间第一个能被7整除的数
//2. 打印1-10之间所有的数,除了5这个数
思考1:
//输出结果是什么?
for(var i = 1; i <=10; i++) {
if(i == 5){
continue;
}
if(i == 7){
break;
}
console.log(i);
}
思考2:
//1. 求1-100之间不能被7整除的整数的和(用continue)
//2. 求200-300之间所有的奇数的和(用continue)
//3. 求200-300之间第一个能被7整数的数(break)
总结
循环有很多种,但是以后用得最多的是for循环
当不明确循环次数的时候,可以使用while循环
当无论如何都要执行一次代码的时候,可以使用do..while循环。
循环可以相互替代。
数组
所谓数组,就是将多个元素(通常是同一类型)按一定顺序排列放到一个集合中,那么这个集合我们就称之为数组。
数组:多个元素的集合,这个集合有顺序,有长度。用途是存储大量的数据。可以存储任意类型的值,包括复杂数据类型。
思考:
//为什么要有数组?
//1. 我们知道,一个变量能够存储一个值,当我们想要存储多个值的时候,就可以使用数组。比如存储一个班级里面所有学生的姓名。
//2. 使用数组可以对多个相同类型的值统一的管理,存储起来方便,操作的时候也会很方便。
数组初体验
在javascript数组是一个有序的列表,可以在数组中存放任意的数据
创建数组,通过数组的构造函数可以创建一个数组
var arr = new Array();//new表示新的 Array:表示数组 new Array表示创建一个数组。
注意:var arr=new Array(123);//声明一个长度为123的空数组
通过数组的下标可以操作数组,数组类似于火车车厢
//给数组设置值,数组中可以存放任意的值
//数组名[下标] = "值"
arr[0] = "张三";//在下标0的地方存放张三
arr[1] = 111; //在下标1的地方存放111
arr[2] = true; //在下标2的地方存放true
//获取数组中的值
//数组名[下标]
console.log(arr[0]);//打印下标0的值
创建数组
通过构造函数创建数组
var arr = new Array();//创建了一个空数组
var arr = new Array("zs","ls","ww");//创建了一个数组,里面存放了3个字符串
var arr = new Array(1,2,3,4);//创建了一个数组,里面存放了4个数字
通过数组字面量创建数组
var arr1 = []; //创建一个空数组
var arr2 = [1, 3, 4]; //创建一个包含3个数值的数组,多个数组项以逗号隔开
var arr3 = ["a", "c"]; // 创建一个包含2个字符串的数组
数组的下标与长度
数组的下标:数组是有序的,数组中的每一个元素都对应了一个下标,下标是从0开始的
var arr = ["zs", "ls", "ww"];
数组的长度:跟字符串一样,数组有一个length属性,指数组中存放的元素的个数。
var arr = ["zs", "ls", "ww"];
arr.length;//这个数组的长度是3
//空数组的长度是0
下标与长度的关系:最大的下标 = length - 1
数组的赋值与取值
数组的取值
//格式:数组名[下标]
//功能:获取数组对应下标的那个值,如果下标不存在,则返回undefined。
var arr = ["red", "green", "blue"];
arr[0];//red
arr[2];//blue
arr[3];//这个数组的最大下标为2,因此返回undefined
数组的赋值
//格式:数组名[下标] = 值;
//如果下标有对应的值,会把原来的值覆盖,如果下标不存在,会给数组新增一个元素。
var arr = ["red", "green", "blue"];
arr[0] = "yellow";//把red替换成了yellow
arr[3] = "pink";//给数组新增加了一个pink的值
思考:如何给一个数组增加新的元素?
- 数组名[数组名.length] = 值
- 数组名.push(值) 注意:工作中常用
//1. 把1-100之间所有的数,放到数组中
//2. 把1-100之间所有的奇数,放到数组中
//3. 把1-100之间能被3整数的数字,存到数组中
数组的遍历
遍历:遍及所有,对数组的每一个元素都访问一次就叫遍历。
数组遍历的基本语法:
for(var i =0; i < arr.length; i++) {
//数组遍历的固定结构
}
思考1:
var arr = [298, 1, 3, 4, 6, 2, 23, 88,77,44];
//1 求一组数中的所有数的和跟平均值
//2 求一组数中的最大值
//3 求一组数中的最小值和最小值所在的位置
//4 求一组数中的最大值和最小值以及所在位置
思考2:
var arr = ["a", "bb","ccc","dddd"];
//1.让一个数组倒叙保存另一个数组中的每一项
//2 将字符串数组用|或其他符号分割
//3 有一个字符串数组,求字符串数组中每项的长度,并把长度的数值存储到新的数组中
//4 将数组中值为0的项去掉,将不为0的值存入一个新的数组
冒泡排序
- 初级版本
- 中级版本
- 高级版本(思路)
声明:我们今天主要是学习数组遍历的语法,对于这种数学烧脑类的题目,想不到是很正常的
//思路:判断,如果一趟下来,一次交换都没有做,说明就已经排好序,就不需要继续比
//var arr = [65, 97, 76, 13, 27, 49, 58];
var arr = [1, 2, 3, 4, 5, 6, 7];
var tang = 0;
var ci = 0;
for (var i = 0; i < arr.length - 1; i++) {
tang++;
var count = 0;//记录交换的次数
//思路: 两两比较,如果前面的大于后面的,交换位置
for (var j = 0; j < arr.length - 1 - i; j++) {
ci++;
if (arr[j] > arr[j + 1]) {
count++;
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
console.log(count);
if (count == 0) {
//说明,没有进行交换
break;
}
}
console.log(arr);
console.log(tang, ci);
函数
函数基础知识
为什么要有函数
在写代码的时候,有一些常用的代码需要书写多次,如果直接复制粘贴的话,会造成大量的冗余代码。
函数可以封装一段重复的JavaScript代码,它只需要声明一次,就可以被多次调用。
重复代码、冗余代码的缺点:
- 代码重复,可阅读性差
- 不易维护,如果代码逻辑改变了,所有地方的代码都要跟着改变,效率太低。
函数的声明与调用
声明函数的语法:
function 函数名(){
//函数体
}
调用函数的语法:
函数名();
特点:
1. 函数声明的时候,函数体并不会执行,函数体只有在调用的时候才会执行,
2. 可以调用多次
代码示例:
//声明函数
function sayHi(){
console.log("吃了没?");
}
//调用函数
sayHi();
思考:
1. 封装一个打招呼的函数
2. 封装一个函数,计算两个数的和
3. 封装一个函数,计算1-100之间所有数的和
函数的参数
- 形参(形式参数):在函数声明时,设置的参数。作用是占位置。
- 实参(实际参数):在函数调用时,传入的参数。作用:函数调用时,会把实参的值赋值给形参,这样形参就有了值。
语法:
//带参数的函数声明
function 函数名(形参1, 形参2, 形参...){
//函数体
}
//带参数的函数调用
函数名(实参1, 实参2, 实参3);
思考:
1. 计算1-n之间所有数的和
2. 计算两个数的和
3. 计算m-n之间所有数的积
注意:
- 形参在声明时,值不固定,只有在调用的时候,形参的值才确定,形参的值会跟着函数调用时的实参不一样而不一样。
- 如何确定形参:在声明函数的时候,碰到不确定的值的时候,就可以定义成形参。
函数的返回值
当函数执行完的时候,我们期望函数给我一些反馈(比如计算的结果),这个时候可以让函数返回一些东西。也就是返回值。函数通过return返回一个返回值
返回值语法:
//声明一个带返回值的函数
function 函数名(形参1, 形参2, 形参...){
//函数体
return 返回值;
}
//可以通过变量来接收这个返回值
var 变量 = 函数名(实参1, 实参2, 实参3);
思考:
1. 计算1-n之间所有数的和,并且返回结果
2. 计算两个数的和,并且返回结果
3. 计算m-n之间所有数的积,并且返回结果
注意:
- 函数的调用结果就是返回值,因此我们可以直接对函数调用结果进行操作。
函数三要素
函数三要素包括:函数名、参数、返回值
function getArea (r) {
return Math.PI * r * r;
}
思考1:
1. 求任意半径的圆的面积
2. 求任意半径的圆的周长
3. 求任意2个数中的最大值
思考2:
1. 求任意数组中的最大值
2. 求任意数组中的最小值
3. 翻转任意数组,返回一个新的数组
4. 对任意数组从小到大排序
函数高级知识
函数调试
断点调试:
1. F8:跳到下一个断点,如果后面没有断点了,那么代码直接执行完。
2. F10:单步调试(跳过函数调用)
3. F11:单步调试(进入函数调用)
4. shift+F11:跳出函数调用
函数内部可以调用函数
在函数内部是可以继续调用别的函数的。
function fn1() {
console.log("fn1开始...");
fn2();
console.log("fn1结束...");
}
function fn2 () {
console.log("执行fn2的代码");
console.log("执行fn2的代码");
console.log("执行fn2的代码");
}
//在函数1中调用了函数2
fn1();
全局变量与局部变量
全局变量:在最函数外,script标签内声明的变量就是全局变量,全局变量在任何地方都能访问的到。
局部变量:在函数中声明的变量,就是局部变量,局部变量只有在当前函数体内能够访问。
隐式全局变量:没有使用var定义的变量也是全局变量。
var num = 11;//全局变量
function fn() {
var num1 = 22;//局部变量
num2 = 33;//隐式全局变量
console.log(num1);
}
fn();
变量的查找规则:
- 自己有就用自己的,自己没有就用外面的。
var num = 11;
function fn() {
var num = 22;
console.log(num);//22
}
fn();
console.log(num);//11
预解析
js执行代码分为两个过程:
- 预解析过程(变量与函数提升)
- 代码一行一行执行
预解析过程:
- 函数优先,先提升function,后提升var
- 遇到重名的var会被忽略。
- 遇到重名的function会被覆盖。
思考:
//1. getCool
//2
console.log(a);
function a() {
console.log("aaaaa");
}
var a = 1;
console.log(a);
面试题:
//1.
var num = 10;
fn1();
function fn1() {
console.log(num);
var num = 20;
}
//2.
var a = 18;
fn2();
function fn2() {
var b = 9;
console.log(a);
console.log(b);
}
//3.
fn3();
console.log(c);
console.log(b);
console.log(a);
function fn3() {
a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
声明函数的两种方式
函数声明(命名函数):
function 函数名(){
//函数体
}
函数表达式(匿名函数):
var 函数名 = function(){
//函数体
}
这两种函数声明的区别:
- 命名函数可以先调用,在声明,因为预解析
- 函数表达式必须先声明,再调用(在DOM中注册事件的时候用的非常的多)
匿名函数
匿名函数:没有名字的函数
匿名函数如何使用:
1. 将匿名函数赋值给一个变量,这样就可以通过变量进行调用
2. 匿名函数自调用
关于自执行函数(匿名函数自调用)的作用:防止全局变量污染。
对象
对象的基本概念
为什么要学习对象?
数组:是有序的元素集合 ,数组用于存放一组数据,比如一个班级所有人的名字,一个班级所有人的成绩。
函数:封装一段重复的代码,只要声明一次,就可以多次调用。
思考1:如果要存储一个人的信息,应该怎么办?
var name = "张三";
var age = 18;
var sex = "男";
var hobby = "上网";
思考2:这么做的缺点是什么?
这些变量都是属于一个人的,应该跟数组一样,使用一个集合把所有的信息都存储起来。
什么是对象
对象:是一组无序的键值对的集合。
//数组多个元素之间使用,隔开
//对象中多个键值对之间也用,隔开,,,键值对的格式: 键:值
var obj = {
name:"张三",
age:18,
sex:"男",
hobby:"上网"
}
- 事物的特征在对象中用属性来表示。
- 事物的行为在对象中用方法来表示。
创建对象
对象字面量
字面量:11 “abc” true [] {}等
var o = {};
var o = {
name : "zs",
age : 18,
sex : true,
sayHi : function() {
console.log(this.name);
}
};
通过Object构造函数创建
var hero = new Object();//创建一个空的对象
操作对象的属性
设置对象的属性
//语法 对象名.属性 = 值;
var obj = new Object();
obj.name = "zs";
obj.age = 18;
obj.gender = "男";
//给对象设置添加一个方法
obj.sayHi = function() {
console.log("大家好,我是"+obj.name);
}
获取对象的属性
//语法: 对象名.属性
console.log(obj.name);
console.log(obj.age);
console.log(obj.gender);
//如果是方法,可以调用
obj.sayHi();
操作对象的属性
.语法
// 获取对象属性的语法:
// 对象.属性:对象的属性
// 1. 如果有这个属性,直接返回属性值
// 2. 如果没有这个属性,返回undefined
// 设置对象的属性的语法
// 对象.属性 = 值
// 1. 如果对象有这个属性,修改这个属性
// 2. 如果对象没有这个属性,添加这个属性
[]语法
也叫关联数组的方式,其实说白了就是把对象当成数组看待。在中括号中可以是一个变量或者是字符串。
//获取对象属性
// 对象['下标'] :把对象的属性当成下标
//设置对象的属性
// 对象['下标'] = "值";
二者的区别:当属性名是一个字符串存储在变量中的时候,只能使用关联数组的方式。
遍历对象
通过for..in语法可以遍历一个对象
for(var key in obj) {
console.log(key + "==" + obj[key]);
}
批量创建对象
在实际开发中,经常需要创建多个相同类型的对象,比如游戏中的怪物,班级的学生等。
使用工厂函数创建对象
优点:可以同时创建多个对象
缺点:创建出来的没有具体的类型,都是object类型的
function 工厂函数名(属性名-形参,方法-形参){
var 对象名={
对象名.属性值;
对象名.方法;
};
return 对象名;
}
工厂函数名();//通过工厂函数创建了对象
构造函数
构造函数 ,是一种特殊的函数。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。
创建同一类型的对象:
function 首字母大写函数名(属性名-形参,方法-形参){
this.属性值;
this.方法;
//自带return返回值
}
var 函数名 = new 首字母大写函数名(属性名-实参,方法-实参参);
- 构造函数首字母要大写(推荐做法)。
- 构造函数要和new一起使用才有意义。
- 构造函数的作用是用于实例化一个对象,即给对象添加属性和方法。
new在执行时会做四件事情
new会做4件事情
1. new会创建一个新的空对象,类型是Teacher
2. new 会让this指向这个新的对象
3. 执行构造函数 目的:给这个新对象加属性和方法
4. new会返回这个新对象
总结:创建对象的几种方式
1. new Object()
2. 对象字面量
3. 工厂函数
4. 自定义构造函数
值类型与引用类型
值类型:简单类型,变量在存储的时候,存储的是值本身。
引用类型:复杂类型,变量在存储的时候,存储的是复杂数据的地址。
值类型与引用类型 内存分布图
(画图说明)
简单类型+复杂类型
值类型与引用类型 赋值
特征(画图说明)
// 值类型
var num1 = 10;
var num2 = num1;
num2 = 99;
console.log(num1);
console.log(num2);
// 引用类型
var obj1 = {
name:"zs",
age:18
}
var obj2 = obj1;
obj2.name = "ls";
console.log(obj1.name);
console.log(obj2.name);
值类型与引用类型参数传递(画图说明)
var num = 10;
function fn(a) {
a = 99;
console.log(a);
}
fn(num);
console.log(num);
// --------------------------------------
var obj = {
name:"zs",
age:18
}
function fn(a) {
a.name = "ls";
console.log(a.name);
}
fn(obj);
console.log(obj.name);
值类型与引用类型练习
//面试题1 :
// a -> x
function fn(a, b) {
// 相当于
// var a = 10;
// var b = 20;
// 函数的参数 其实就是函数内部的局部变量
a = a + 1;
b = b + 1;
console.log(a);
console.log(b);
}
var x = 10;
var y = 20;
fn(x, y);
console.log(x);
console.log(y);
//面试题2 :
var p = {
name:"zs",
age:18
}
function fn(person) {
person.name = 'ls';
console.log(person.name);
}
fn(p);
console.log(p.name);
结论:简单类型存储的是值本身,复杂类型存储的是地址,引入如果把第一个对象赋值给另一个变量,此时两个变量会指向同一个对象。
内置对象
JS内置对象就是指Javascript自带的一些对象,供开发者使用,这些对象提供了一些常用的的功能。
常见的内置对象有Math、String、Array、Date等
JavaScript中的对象分为3种:内置对象、浏览器对象、自定义对象
JavaScript 提供多个内置对象:Math/Array/Number/String/Boolean...
对象只是带有属性和方法的特殊数据类型。
学习一个内置对象的使用,只要学会其常用的成员的使用(通过查文档学习)
可以通过MDN/W3C来查询
内置对象的方法很多,我们只需要知道内置对象提供的常用方法,使用的时候查询文档。
MDN
Mozilla 开发者网络(MDN)提供有关开放网络技术(Open Web)的信息,包括 HTML、CSS 和万维网及 HTML5 应用的 API。
- MDN
- 通过查询MDN学习Math对象的random()方法的使用
如何学习一个方法?
- 方法的功能
- 参数的意义和类型
- 返回值意义和类型
- demo进行测试
Math对象
Math对象中封装很多与数学相关的属性和方法。
属性PI
Math.PI
最大值/最小值
Math.max();
Math.min();
取整(★)
Math.ceil();//天花板,向上取整
Math.floor();//地板,向下取整
Math.round();//四舍五入,如果是.5,则取更大的那个数
随机数(★)
Math.random();//返回一个[0,1)之间的数,能取到0,取不到1
取随机整数: parseInt(Math.random()*(n+1));
绝对值
Math.abs();//求绝对值
次幂和平方
Math.pow(num, power);//求num的power次方
Math.sqrt(num);//对num开平方
练习
随机生成一个rgb颜色?
function randomRGB(){
var colorA = parseInt( Math.random() * 256 );
var colorB = parseInt( Math.random() * 256 );
var colorC = parseInt( Math.random() * 256 );
return 'rgb('+ colorA + "," + colorB + ',' + colorC +')';
}
document.body.style.backgroundColor('rgba('+colorA+','+colorA+','+colorA+')')
Date对象
Date对象用来处理日期和时间
创建一个日期对象
var date = new Date();//使用构造函数创建一个当前时间的对象
var date = new Date("2017-03-22 8:00:00");//创建一个指定时间的日期对象
var date = new Date("2017-03-22 00:52:34");//创建一个指定时间的日期对象
var date = new Date(2017, 2, 22, 0, 52, 34);
var date = new Date(1523199394644);//参数:毫秒值
Date构造函数的参数
1. 毫秒数 1498099000356 new Date(1498099000356)
2. 日期格式字符串 '2015-5-1' new Date('2015-5-1')
3. 年、月、日…… var date = new Date(2017, 2, 22, 0, 52, 34);月份从0开始
日期格式化(了解)
date.toString();//默认的日期格式
date.toLocaleString();//本地风格的日期格式(兼容性)
date.toDateString();//只显示日期
date.toTimeString();//只显示时间
//以下有兼容性问题
date.toLocalDateString();//只显示本地风格的日期,谷歌不兼容
date.toLocalTimeString();//只显示本地风格的时间,谷歌不兼容
获取日期的指定部分
getMilliseconds();//获取毫秒值
getSeconds();//获取秒
getMinutes();//获取分钟
getHours();//获取小时
getDay();//获取星期,0-6 0:星期天
getDate();//获取日,即当月的第几天
getMonth();//返回月份,注意从0开始计算,这个地方坑爹,0-11 ,正常的月份需要加1
getFullYear();//返回4位的年份 如 2019
//思考:
//封装一个函数,返回当前的时间,格式是:yyyy-MM-dd HH:mm:ss
// 年 月 日
var year = getFullYear(),mouth=getMonth()+1,day=getDate();
// 时 分 秒
var hour = getHours(),minutes=getMinutes(),second=getSeconds();
// 获取指定月份有多少天
var days = new Date(year, month, 0).getDate();
// 日期时间加0函数
function addZero(n){
return n < 10 ? '0' + n : n;
}
function addZero(n){
return n.toString().padStart(2,'0')
}
// 操作日期追加函数
function add(date,num,type) {
const dateCopy = new Date(date)
if(type==='days'){
dateCopy.setDate(date.getDate() + num)
} else if (type==='months'){
dateCopy.setDate(date.getMonth() + num)
} else if (type==='years'){
dateCopy.setDate(date.getFullYear() + num)
}
return dateCopy
}
时间戳
时间戳是日期的数字形式用于计算时间差
1、统计系统执行时间
//1. 统计代码的执行时间 (可以用于性能优化)
var start = new Date();
var sum = 0;
for (var i = 1; i < 1e7; i++) {
sum += i;
}
var end = new Date();
console.log(sum);
console.log(end - start);
2、秒杀时间
//时间差 单位毫秒
var time = +new Date('结束时间') - +new Date();
//小时
var hour =parseInt(time / 1000 / 3600);
//分
var minutes =parseInt(time / 1000 / 60) % 60;
//秒
var second =parseInt(time / 1000 % 60);
//倒计时
var cutTime = hour+'' + minutes+'' + second;
//老师的写法
// 2. 秒杀倒计时 需要知道倒计时多少时间 = 秒杀时间 - 当前时间
// 距离下课, 还有多长时间 = 下课时间 - 当前时间
var future = new Date('2019-7-24 18:30:00');
var now = new Date();
var time = parseInt((future - now) / 1000); // 得到秒数
// 转换成 时 分 秒
var hour = parseInt(time / 3600);
// 分钟, 先求总计多少分钟, 超过60的进位了, 不要了
var minutes = parseInt(time / 60) % 60;
// 秒数, 超过60的都进位了
var seconds = time % 60;
var str = '距离下课, 还有'+ hour +'时' + minutes + '分'+ seconds +'秒';
console.log(str);
var date = +new Date();//1970年01月01日00时00分00秒起至现在的总毫秒数
//思考
//1. 如何统计一段代码的执行时间?
//2. 倒计时,计算距离下课还有多长时间
Array对象
数组对象在javascript中非常的常用
数组转换(★)
//语法: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 = ["赵云","马超","刘备","关羽","张飞"];
//把数组的最后一个元素变成数组的第一个元素
arr.unshift(arr.pop());
//把数组的第一个元素变成数组的最后一个元素
array.push(array.shift(););
数组的翻转与排序
array.reverse();//翻转数组
array.sort();//数组的排序,默认按照字母顺序排序
//默认把数组的第一项转换成字符串,取第一位排序
//sort方法可以传递一个函数作为参数,这个参数用来控制数组如何进行排序
//从小到大
arr.sort(function(a, b){
//如果返回值>0,则交换位置
return a - b;
});
//从大到小
arr.sort(function(a, b){
//如果返回值>0,则交换位置
return b - a;
});
练习
//思考:
//将[3, 6, 1, 5, 10, 2,11]从小到大排列
array.sort();
//将字符串数组按照字符长度从小到大排列
arr.sort(function(a,b){
return a.length-b.length;
});
//将学生数组按照年龄从小到大排列
//a,bs是对象
arr.sort(function(a,b){
return a.age - b.age;
})
数组的合并与截取
//concat:数组合并,不会影响原来的数组,会返回一个新数组。
//可以一次合并一个或多个数组
var newArray = array.concat(array2);
//slice:数组截取,复制数组的一部分到一个新数组,并返回这个数组
//array.slice();默认从头截到尾
var newArray = array.slice(begin, end);//注意:原来的数组不受影响,包含begin,不包含end
//splice:删除数组或者增加数据元素
//start:开始位置 deleteCount:删除的个数 items:替换的内容
array.splice(start, deleteCount, [items]);
//练习:
var arr = ["赵云","马超","刘备","关羽","张飞"];
//截取["刘备","关羽"]
//在马超后面增加 马腾
//删除关羽
splice方法
splice可以在数组的任意位置,添加 删除 替换 (会改变原数组)
arr.splice(start,delnum,itme1,itme2)
//删除
arr.splice(1,1);//删除第二个元素,第一参数下标,第二参数删除个数
//替换
arr.splice(1,1,'李白')//删除第二个元素,替换为别人,可以写多个元素
//添加
arr.splice(2,0,'马云')//在第二个元素,添加元素,可以写多个元素
数组查找元素
常用语判断一个值在数组中是否存在,不存在返回值为-1。
注意:查找所有的位置,使用原始方法遍历
//indexOf方法用来查找数组中某个元素第一次出现的位置,如果找不到,返回-1
arr.indexOf('XXX');
array.indexOf(search, [fromIndex]);
//astIndexOf()从后面开始查找数组中元素出现位置,如果找不到,返回-1
arr.indexOf('XXX');
array.lastIndexOf(search, [fromIndex]);
清空数组
//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出现的位置
//2. 找到数组中最后一个a出现的位置
//3. 找到数组中每一个a出现的位置
//4. 数组去重,返回一个新数组
//5. 获取数组中每个元素出现的次数
基本包装类型
简单数据类型是没有方法的。为了方便操作基本数据类型,JavaScript还提供了三个特殊的引用类型:String/Number/Boolean。
基本包装类型:把基本类型包装成复杂类型。
var str = “abc”;
//浏览器获取简单类型的属性和方法时,在JS内部,浏览器将简单类型包装成复杂类型
var result = str.indexOf(“a”);
//发生了三件事情
1. 把简单类型转换成复杂类型:var s = new String(str);
2. 调用包装类型的indexOf方法:var result = s.indexOf(“a”);
3. 销毁刚刚创建的复杂类型
Number对象
Number对象是数字的包装类型,数字可以直接使用这些方法
toFixed(2)//保留2位小数
toString();//转换成字符串
Boolean对象
Boolean对象是布尔类型的包装类型。
toString( );//转换成字符串
undefined和null没有包装类型,所以调用toString方法会报错
String对象
字符串可以看成是一个字符数组(伪数组)。因此字符串也有长度,也可以进行遍历。String对象很多方法的名字和和Array的一样。可以少记很多的单词。
查找指定字符串
//indexOf:获取某个字符串第一次出现的位置,如果没有,返回-1
//lastIndexOf:从后面开始查找第一次出现的位置。如果没有,返回-1
去除空白
str.trim();
trim();//去除字符串两边的空格,内部空格不会去除
大小写转换
str.toUpperCase();
str.toLowerCase();
//toUpperCase:全部转换成大写字母
//toLowerCase:全部转换成小写字母
字符串拼接与截取
//字符串拼接
//可以用concat,用法与数组一样,但是字符串拼串我们一般都用+
//字符串截取的方法有很多,记得越多,越混乱,因此就记好用的就行
//slice :从start开始,end结束,并且取不到end。
//substring :从start开始,end结束,并且取不到end
//substr :从start开始,截取length个字符。
字符串切割
//split:将字符串分割成数组(很常用)
//功能和数组的join正好相反。
var str = "张三,李四,王五";
var arr = str.split(",");
//可以根据空串,把字符串拆分数组
var arr = str.split("");
字符串替换
replace(searchValue, replaceValue)//将str中第一次出现的值替换
str=str.replace('你妹','**');
//参数:searchValue:需要替换的值 replaceValue:用来替换的值
//将所有值替换可以使用正则表达式
str=str.replace(/你妹/g,'**');
练习
//1. 截取字符串"我爱中华人民共和国",中的"中华"
var str = "我爱中华人民共和国";
console.log(str.slice(2, 4));
console.log(str.substring(2, 4));
console.log(str.substr(2, 2));
//2. "abcoefoxyozzopp"查找字符串中所有o出现的位置
var str = "abcoefoxyozzopp";
for (var i = 0; i < str.length; i++) {
if (str[i] === 'o') {
console.log(i);
}
}
//3. 把字符串中所有的o替换成!
var str = "abcoefoxyozzopp";
str = str.replace(/o/g, '!');
console.log(str);
//4. 把一个字符串中所有的空格全部去掉
//将所有的 " " => ""
var str = ' aa bb '; // 首尾空格, str.trim()
str = str.replace(/ /g, '');
console.log(str);
//5. 统计一个字符串中每个字符出现的次数
// var str = 'my_name_is_jim_green';
// 需求: 变成驼峰命名 myNameIsJimGreen
var str = 'my_name_is_jim_green';
var arr = str.split('_');
for (var i = 1; i < arr.length; i++) {
// 让每个单词, 首字母大写
// console.log(arr[i]);
arr[i] = arr[i][0].toUpperCase() + arr[i].slice(1);
}
// 将数组, 转成字符串
str = arr.join("");
console.log(str);