JavaScript学习笔记(二)
文章目录
第4章 控制语句
4.1 代码块
- 我们的程序是由一条一条语句构成的
- 语句是按照自上向下的顺序一条一条执行的
- 在JS中可以使用{}来为语句进行分组,同一个{}中的语句我们称为是一组语句,它们要么都执行,要么都不执行,一个{}中的语句我们也称为叫一个代码块在代码块的后边就不用再编写了
- JS中的代码块,只具有分组的的作用,没有其他的用途,代码块内容的内容,在外部是完全可见的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>代码块</title>
<script>
/*
* 我们的程序是由一条一条语句构成的
* 语句是按照自上向下的顺序一条一条执行的
* 在JS中可以使用{}来为语句进行分组,
* 同一个{}中的语句我们称为是一组语句,
* 它们要么都执行,要么都不执行,
* 一个{}中的语句我们也称为叫一个代码块
* 在代码块的后边就不用再编写;了
*
* JS中的代码块,只具有分组的的作用,没有其他的用途
* 代码块内容的内容,在外部是完全可见的
*/
{
var a = 10;
alert("hello");
console.log("你好");
document.write("语句");
}
console.log("a = "+a);
</script>
</head>
<body>
</body>
</html>
4.2 if语句
-
流程控制语句
- JS中的程序是从上到下一行一行执行的
- 通过流程控制语句可以控制程序执行流程,使程序可以根据一定的条件来选择执行
-
语句的分类:
- 1.条件判断语句
- 2.条件分支语句
- 3.循环语句
-
条件判断语句:
- 使用条件判断语句可以在执行某个语句之前进行判断,如果条件成立才会执行语句,条件不成立则语句不执行。
-
if语句 1
/* * if(条件表达式){ * 语句... * } */
-
if语句在执行时,会先对条件表达式进行求值判断,
- 如果条件表达式的值为true,则执行if后的语句,
- 如果条件表达式的值为false,则不会执行if后的语句。
-
if语句只能控制紧随其后的那个语句,
- 如果希望if语句可以控制多条语句,可以将这些语句统一放到代码块中
-
if语句后的代码块不是必须的,但是在开发中尽量写上代码块,即使if后只有一条语句
-
if语句 2
/* * if(条件表达式){ * 语句... * }else{ * 语句... * } */
-
if…else…语句
-
当该语句执行时,会先对if后的条件表达式进行求值判断,
- 如果该值为true,则执行if后的语句
- 如果该值为false,则执行else后的语句
/* * if(条件表达式){ * 语句... * }else if(条件表达式){ * 语句... * }else if(条件表达式){ * 语句... * }else{ * 语句... * } */
-
if…else if…else…语句
-
当该语句执行时,会从上到下依次对条件表达式进行求值判断
- 如果值为true,则执行当前语句。
- 如果值为false,则继续向下判断。
- 如果所有的条件都不满足,则执行最后一个else后的语句
-
该语句中,只会有一个代码块被执行,一旦代码块执行了,则直接结束语句
练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>if练习</title>
<script>
/*
* 从键盘输入小明的期末成绩:
* 当成绩为100时,'奖励一辆BMW'
* 当成绩为[80-99]时,'奖励一台iphone15s'
* 当成绩为[60-80]时,'奖励一本参考书'
* 其他时,什么奖励也没有
*/
/**
* prompt()可以弹出一个提示框,该提示框带一个文本框
* 该函数需要一个字符串作为参数,返回一个输入的值
*/
var num = prompt("请输入一个数字:");
if(num == 100){
alert("奖励一辆BMW");
}else if(num >= 80){
alert("奖励一台iphone15");
}else if(num >= 60){
alert("奖励一本参考书");
}else{
alert("什么奖励也没有");
}
</script>
</head>
<body>
</body>
</html>
4.3 Switch 语句
条件分支语句也叫switch语句
语法:
/*
* switch(条件表达式){
* case 表达式:
* 语句...
* break;
* case 表达式:
* 语句...
* break;
* default:
* 语句...
* break;
* }
*/
- 执行流程:
- switch…case…语句
- 在执行时会依次将case后的表达式的值和switch后的条件表达式的值进行全等比较,如果比较结果为true,则从当前case处开始执行代码。
- 当前case后的所有的代码都会执行,我们可以在case的后边跟着一个break关键字,这样可以确保只会执行当前case后的语句,而不会执行其他的case
- 如果比较结果为false,则继续向下比较
- 如果所有的比较结果都为false,则只执行default后的语句
- switch语句和if语句的功能实际上有重复的,使用switch可以实现if的功能,同样使用if也可以实现switch的功能,所以我们使用时,可以根据自己的习惯选择。
练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
// 输入一个数,判断是否合格
var num = prompt("请输入一个数(1-7):");
//输入的数组为字符串
num = Number(num);
switch(num){
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("输入的不是数字!或者不在(1-7)中")
}
</script>
</head>
<body>
</body>
</html>
4.4 while循环
循环语句: 通过循环语句可以反复的执行一段代码多次
语法一:(while循环)
/*
* while循环
* - 语法:
* while(条件表达式){
* 语句...
* }
*/
- while语句在执行时,先对条件表达式进行求值判断,
- 如果值为true,则执行循环体,循环体执行完毕以后,继续对表达式进行判断
- 如果为true,则继续执行循环体,以此类推
- 如果值为false,则终止循环
语法二:(do…while循环)
/*
* - 语法:
* do{
* 语句...
* }while(条件表达式)
*/
- 执行流程:
- do…while语句在执行时,会先执行循环体,循环体执行完毕以后,在对while后的条件表达式进行判断:
- 如果结果为true,则继续执行循环体,执行完毕继续判断以此类推
- 如果结果为false,则终止循环
- 实际上这两个语句功能类似,不同的是while是先判断后执行,而do…while会先执行后判断,do…while可以保证循环体至少执行一次,而while不能
4.5 for循环
-
for语句,也是一个循环语句,也称为for循环
-
在for循环中,为我们提供了专门的位置用来放三个表达式:
- 1.初始化表达式
- 2.条件表达式
- 3.更新表达式
-
语法
/* * for循环的语法: * for(①初始化表达式;②条件表达式;④更新表达式){ * ③语句... * } */
-
for循环的执行流程:
- ①执行初始化表达式,初始化变量(初始化表达式只会执行一次)
- ②执行条件表达式,判断是否执行循环。
- 如果为true,则执行循环
- 如果为false,终止循环
- ③执行更新表达式,更新表达式执行完毕继续重复②
第5章 对象和函数
5.1 对象的介绍
- JS中数据类型
* String 字符串
* Number 数值
* Boolean 布尔值
* Null 空值
* Undefined 未定义 - 以上这五种类型属于基本数据类型,以后我们看到的值只要不是上边的5种,全都是对象
* Object 对象 - 基本数据类型都是单一的值"hello" 123 true,值和值之间没有任何的联系。
- 在JS中来表示一个人的信息(name gender age):
*var name = "孙悟空";
*var gender = "男";
*var age = 18;
- 如果使用基本数据类型的数据,我们所创建的变量都是独立,不能成为一个整体。
* 对象属于一种复合的数据类型,在对象中可以保存多个不同数据类型的属性。
*
* 对象的分类:
* 1.内建对象
* 由ES标准中定义的对象,在任何的ES的实现中都可以使用
* 比如:Math String Number Boolean Function Object…
* 2.宿主对象
* 由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象
* 比如 BOM DOM
* 3.自定义对象
* 由开发人员自己创建的对象
相关代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>对象介绍</title>
<script>
//写法一
//创建一个对象
var obj = new Object();
//向对象中添加一个属性
obj.name = "张三";
obj.age = 18;
//输出
console.log(obj);
//写法二,创建字面量创建对象,在04节介绍
var obj02 = {
name:"李四",
age:18
};
console.log(obj02);
//修改,删除对象
obj.age = 28;
//对象的字段
delete obj.name;
console.log(obj);
</script>
</head>
<body>
</body>
</html>
5.2 对象的属性名和属性值
1.向对象中添加属性
- 属性名:
- 对象的属性名不强制要求遵守标识符的规范
- 什么乱七八糟的名字都可以使用
- 但是我们使用是还是尽量按照标识符的规范去做
相关代码
var obj = new Object();
obj.name = "hello";
- 2.如果要使用特殊的属性名,不能采用.的方式来操作
* 需要使用另一种方式:
* 语法:对象[“属性名”] = 属性值
* 读取时也需要采用这种方式
* 使用[]这种形式去操作属性,更加的灵活,在[]中可以直接传递一个变量,这样变量值是多少就会读取那个属性
相关代码
var obj = new Object();
obj["123"] = 789;
obj["nihao"] = "你好";
console.log(obj);
console.log(obj["123"],obj["nihao"])
var n = "nihao";
//中括号可以传变量
console.log(obj[n]);
3.属性值
- JS对象的属性值,可以是任意的数据类型,甚至也可以是一个对象
相关代码
var obj = new Object();
obj.test01 = true;
obj.test02 = null;
obj.test03 = undefined;
console.log(obj);
4.in 运算符
- 通过该运算符可以检查一个对象中是否含有指定的属性,如果有则返回true,没有则返回false
- 语法:
- “属性名” in 对象
相关代码
console.log("检查obj对象中是否包含属性:","test01" in obj);
console.log("检查obj对象中是否包含属性:","test08" in obj);
5.3 数据的引用类型
- 基本数据类型
* String Number Boolean Null Undefined - 引用数据类型
* Object - JS中的变量都是保存到栈内存中的,
* 基本数据类型的值直接在栈内存中存储,值与值之间是独立存在,修改一个变量不会影响其他的变量
* 对象是保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟出一个新的空间,而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用,当一个通过一个变量修改属性时,另一个也会受到影响
相关代码
var a = 123;
var b = a;
a++;
//值与值之间是独立存在,修改一个变量不会影响其他的变量
console.log("a = " + a);//124
console.log("b = " + b);//123
var obj = new Object();
obj.name = "孙悟空";
//直接赋值
var obj2 = obj;
//修改obj的name属性
obj.name = "猪八戒";
//如果两个变量保存的是同一个对象引用,当一个通过一个变量修改属性时,另一个也会受到影响
console.log(obj.name);//猪八戒
console.log(obj2.name);//猪八戒
//设置obj2为null
obj2 = null;
//obj2 断开连接不会印象 obj
console.log(obj);//对象信息
console.log(obj2);//null
var c = 10;
var d = 10;
//基本数据类型,比较值
console.log("c == d",c == d);//true
console.log("c == '10'",c == '10');//true
var obj3 = new Object();
var obj4 = new Object();
obj3.name = "沙和尚";
obj4.name = "沙和尚";
//创建对象,保存在不同的堆中,属性也不相同
console.log(obj3);
console.log(obj4);
/*
* 当比较两个基本数据类型的值时,就是比较值。
* 而比较两个引用数据类型时,它是比较的对象的内存地址,
* 如果两个对象是一摸一样的,但是地址不同,它也会返回false
*/
console.log("对象比较:",obj3 == obj4);
5.4 对象的字面量
- 使用对象字面量,可以在创建对象时,直接指定对象中的属性
* 语法:{属性名:属性值,属性名:属性值…} - 对象字面量的属性名可以加引号也可以不加,建议不加
* 如果要使用一些特殊的名字,则必须加引号
* 属性名和属性值是一组一组的名值对结构,名和值之间使用:连接,多个名值对之间使用,隔开
* 如果一个属性之后没有其他的属性了,就不要写
相关代码
// 通过字面量创建对象
var obj2 = {
name:"猪八戒",
age:13,
gender:"男",
test:{name:"沙僧"}
};
console.log(obj2);
console.log(obj2.test);
简单比较
-
字面量创建对象,不会调用 Object 构造函数, 简洁且性能更好;
-
new Object () 方式创建对象本质上是方法调用,涉及到在 proto 链中遍历该方法,当找到该方法后,又会生产方法调用必须的 堆栈信息,方法调用结束后,还要释放该堆栈,性能不如字面量的方式。
5.5 函数
- 函数 function
* 函数也是一个对象
* 函数中可以封装一些功能(代码),在需要时可以执行这些功能(代码)
* 函数中可以保存一些代码在需要的时候调用
* 使用typeof
检查一个函数对象时,会返回function
相关代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>函数</title>
<script>
//1.我们在实际开发中很少使用构造函数来创建一个函数对象
//创建一个函数对象
//可以将要封装的代码以字符串的形式传递给构造函数
//不推荐使用
var fun = new Function("console.log('Hello 这是我的第一个函数');");
//2.封装到函数中的代码不会立即执行
//函数中的代码会在函数调用的时候执行
//调用函数 语法:函数对象()
//当调用函数时,函数中封装的代码会按照顺序执行
fun();
/*
* 使用 函数声明 来创建一个函数
* 语法:
* function 函数名([形参1,形参2...形参N]){
* 语句...
* }
*/
function fun2(){
console.log("这是我的第二个函数~~~");
}
//3.匿名函数对象,和上面的区别不大
var fun3 = function(){
console.log("这是我的第三个函数~~~");
}
/*
* 4.使用 函数表达式 来创建一个函数
* var 函数名 = function([形参1,形参2...形参N]){
* 语句....
* }
*/
var fun4 = function(num01,num02){
console.log(num01+num02);
}
/*
* 5.调用函数时解析器不会检查实参的类型,
* 所以要注意,是否有可能会接收到非法的参数,如果有可能则需要对参数进行类型的检查
* 函数的实参可以是任意的数据类型
*/
/*
* 6.调用函数时,解析器也不会检查实参的数量
* 多余实参不会被赋值
* 如果实参的数量少于形参的数量,则没有对应实参的形参将是undefined
*
*/
/*
* 7.创建一个函数,用来计算三个数的和
*
* 可以使用 return 来设置函数的返回值
* 语法:
* return 值
*
* return后的值将会会作为函数的执行结果返回,
* 可以定义一个变量,来接收该结果
*
* 在函数中return后的语句都不会执行
*
* 如果return语句后不跟任何值就相当于返回一个undefined,
* 如果函数中不写return,则也会返回undefined
*
* return后可以跟任意类型的值
*
*/
function sum(a , b , c){
var d = a + b + c;
return d;
//默认返回
//return undefined;
}
//调用函数
//变量result的值就是函数的执行结果
//函数返回什么result的值就是什么
var result = sum(4,7,8);
//var result = alert("hello");//返回undefined
console.log("result = "+result);
/**
* 返回值可以是任意的数据类型也可以是一个对象,也可以是一个函数
* 函数中可以定义一个函数
*/
function fun5(){
//在函数内部再声明一个函数
function fun6(){
alert("我是fun6");
}
//将fun4函数对象作为返回值返回
return fun6;
}
var temp = fun5();
//a();
//调用返回值
fun5()();
</script>
</head>
<body>
<button onclick="javascript:fun();">第一个函数</button>
<button onclick="javascript:fun2();">第二个函数</button>
<button onclick="javascript:fun3();">第三个函数</button>
<button onclick="javascript:fun4(3,4);">第四个函数</button>
</body>
</html>
5.6 立即执行函数
-
立即执行函数
-
函数定义完,立即被调用,这种函数叫做立即执行函数
-
立即执行函数往往只会执行一次
相关代码
// 案例一
(function(){
alert("我是一个匿名函数~~~");
})();
// 案例二
(function(a,b){
console.log("a = "+a);
console.log("b = "+b);
})(123,456);
5.7 对象添加函数
相关代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>对象方法</title>
<script>
/*
* 创建一个对象
*/
var obj = new Object();
//向对象中添加属性
obj.name = "孙悟空";
obj.age = 18;
//对象的属性值可以是任何的数据类型,也可以是个函数
obj.sayName = function(){
console.log(obj.name);
};
//调用对象的方法
obj.sayName();
/*
* 函数也可以称为对象的属性,
* 如果一个函数作为一个对象的属性保存,
* 那么我们称这个函数时这个对象的方法
* 调用这个函数就说调用对象的方法(method)
* 但是它只是名称上的区别没有其他的区别
*
*/
var obj2 = {
name:"猪八戒",
age:18,
sayName:function(){
console.log(obj2.name);
}
};
obj2.sayName();
</script>
</head>
<body>
</body>
</html>
5.8 对象的属性遍历
相关代码
//枚举对象中的属性
//使用for ... in 语句
/*
* 语法:
* for(var 变量 in 对象){
*
* }
*
* for...in语句 对象中有几个属性,循环体就会执行几次
* 每次执行时,会将对象中的一个属性的名字赋值给变量
*/
//定义一个对象
let user = {
name:"张三",
age:18,
salary:"50k",
job:"全栈工程师"
};
//遍历读取属性
for(var value in user){
//读取对象中的信息
//不能通过点读取信息,value是变量,要通过[]读取
console.log("对象的字段:"+value+": ",user[value]);
}
5.9 作用域
作用域
- 作用域指一个变量的作用的范围
- 在JS中一共有两种作用域:
- 1.全局作用域
- 直接编写在script标签中的JS代码,都在全局作用域
- 全局作用域在页面打开时创建,在页面关闭时销毁
- 在全局作用域中有一个全局对象window,它代表的是一个浏览器的窗口,它由浏览器创建我们可以直接使用
- 在全局作用域中:
- 创建的变量都会作为window对象的属性保存
- 创建的函数都会作为window对象的方法保存
- 全局作用域中的变量都是全局变量,
- 在页面的任意的部分都可以访问的到
- 2.函数的作用域(后面介绍)
- 1.全局作用域
相关代码
//第一部分 属性
var a = 10;
var b = 20;
var c = "hello";
console.log("window对象中的属性:",window.a,window.b,window.c);
//第二部分 方法
function fun(){
console.log("我是fun函数");
}
window.fun();
//第三部分 var变量会在全部代码执行前被声明
/*
* 变量的声明提前
* - 使用var关键字声明的变量,会在所有的代码执行之前被声明(但是不会赋值),
* 但是如果声明变量时不适用var关键字,则变量不会被声明提前
* 函数的声明提前
* - 使用函数声明形式创建的函数 function 函数(){}
* 它会在所有的代码执行之前就被创建,所以我们可以在函数声明前来调用函数
* 使用函数表达式创建的函数,不会被声明提前,所以不能在声明前调用
*/
//不加var,则声明为window的属性,当顺序不能变(d 在调用的时候声明)
d = 18;
console.log(d);
//加上var,会在所有的代码执行之前被声明(但是不会赋值),输出undifined
console.log(f);
var f = 58;
//第四部分 函数提前创建
fun();
//函数声明,会被提前创建
function fun(){
console.log("我是一个fun函数");
}
//fun2();//报错
//函数表达式,不会被提前创建
var fun2 = function(){
console.log("我是fun2函数");
};
函数作用域
- 调用函数时创建函数作用域,函数执行完毕以后,函数作用域销毁
- 每调用一次函数就会创建一个新的函数作用域,他们之间是互相独立的
- 在函数作用域中可以访问到全局作用域的变量,在全局作用域中无法访问到函数作用域的变量
- (特殊、重点)当在函数作用域操作一个变量时,它会先在自身作用域中寻找,如果有就直接使用
- 如果没有则向上一级作用域中寻找,直到找到全局作用域,
- 如果全局作用域中依然没有找到,则会报错
ReferenceError
- (特殊、重点)在函数中要访问全局变量可以使用
window
对象
相关代码
//创建一个变量
var a = 10;
function fun(){
//在函数中定义同名属性,要加上var,否则为全局变量
var a = "我是fun函数中的变量a";
var b = 20;
//输出函数内的同名变量
console.log("a = "+a);
function fun2(){
//使用window.a 可以访问全局变量
console.log("a = "+window.a);
}
//调用函数内的函数
fun2();
}
fun();
/*
* 在函数作用域也有声明提前的特性,
* 使用var关键字声明的变量,会在函数中所有的代码执行之前被声明
* 函数声明也会在函数中所有的代码执行之前执行
*/
function fun3(){
//在函数中,也有函数提前声明定义
fun4();
//两种情况
//第一种,在函数中,没用定义同名属性,则找全局属性
//第二种,在函数中,定义同名属性,如果没有在输出前,则输出undefined
console.log(a);
var a = 35;
function fun4(){
console.log("在函数中,也有函数提前声明定义");
}
}
fun3();
/*
* (重点)在函数中,不适用var声明的变量都会成为全局变量
*/
function fun5(){
//d没有使用var关键字,则会设置为全局变量,调用会修该全局变量
a = 100;
}
fun5();
console.log(a);
函数中要访问全局变量可以使用window
对象
相关代码
//创建一个变量
var a = 10;
function fun(){
//在函数中定义同名属性,要加上var,否则为全局变量
var a = "我是fun函数中的变量a";
var b = 20;
//输出函数内的同名变量
console.log("a = "+a);
function fun2(){
//使用window.a 可以访问全局变量
console.log("a = "+window.a);
}
//调用函数内的函数
fun2();
}
fun();
/*
* 在函数作用域也有声明提前的特性,
* 使用var关键字声明的变量,会在函数中所有的代码执行之前被声明
* 函数声明也会在函数中所有的代码执行之前执行
*/
function fun3(){
//在函数中,也有函数提前声明定义
fun4();
//两种情况
//第一种,在函数中,没用定义同名属性,则找全局属性
//第二种,在函数中,定义同名属性,如果没有在输出前,则输出undefined
console.log(a);
var a = 35;
function fun4(){
console.log("在函数中,也有函数提前声明定义");
}
}
fun3();
/*
* (重点)在函数中,不适用var声明的变量都会成为全局变量
*/
function fun5(){
//d没有使用var关键字,则会设置为全局变量,调用会修该全局变量
a = 100;
}
fun5();
console.log(a);