JavaScript学习第3天
1. 断点调试
2. 循环
2.1 一行打印五个小星星
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
var str='';
// 这里需要字符串拼接,否则会打出一个⭐,前面一个5
for(var i=0;i<5;i++){
str+='⭐';
}
console.log(str);
</script>
</head>
<body>
</body>
</html>
- 效果图
3. 数组
3.1 数组的定义
- 数组:一组数据的集合,其中的每个数据被称为元素,在数组中可以存放任意类型的元素
3.2 创建数组
- 利用new创建数组
- 利用数组字面量创建数组
3.2.1 new创建数组
// 创建一个空数组
var arr=new Array();
####3.2.2 字面量创建数组
// 创建空数组
var arr0=[];
// 创建并初始化数组
var arr1=[1,2,3,4,true,'k'];
3.3 数组访问
- 当数组下标超过可见数组长度时,不会数组越界,而是提示undefined
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
var arr=[1,2,true];
// 数组中没有第3个元素
// 访问后为undefined
console.log(arr[3]);
</script>
</head>
<body>
</body>
</html>
- 效果图
3.4 数组长度
- 使用数组名.length可以访问数组元素的数量(数组长度)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
var arr=[1,2,3];
alert(arr.length);
</script>
</head>
<body>
</body>
</html>
- 效果图
3.5 新增数组元素
- 通过修改length长度来实现数组扩容的目的
- 通过修改数组索引实现数组扩容(常用方式)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
var arr=[1,2,3];
// 通过修改数组长度来实现扩容
//未赋值的元素类型为undefined
arr.length=9;
console.log(arr);
// 修改数组索引来实现扩容
var arr1=[1,3];
arr1[2]='8';
arr1[3]='9';
console.log(arr1);
// 不要直接给数组名赋值,否则该变量不为数组
arr1='666';
console.log(arr1);
</script>
</head>
<body>
</body>
</html>
- 效果图
4. 函数
4.1 声明函数
<script>
// 声明函数
function 函数名(){
函数体;
}
</script>
- function是声明函数的关键字
- 函数名一般为动词
4.2 调用函数
// 调用函数
函数名();
4.3 函数的形参和实参
<script>
function 函数名(形参1,形参2,....){
函数体;
}
// 调用函数
函数名(实参1,实参2,...);
</script>
- 在声明那里为形参
- 在调用那里为实参
注意点
- 形参不需要类型
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
function getSum(num1,num2){
console.log(num1+num2);
}
getSum(1,2);
</script>
</head>
<body>
</body>
</html>
- 效果图
4.4 函数形参和实参个数不匹配问题
参数个数 | 说明 |
---|---|
实参个数等于形参个数 | 输出正确结果 |
实参个数多余形参个数 | 只取到形参个数 |
实参个数少于形参个数 | 多的形参被定义为undefined,结果为NaN |
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
function getSum(num1,num2){
console.log(num1+num2);
}
// 实参个数多余形参,只取到形参个数
getSum(1,2,3);
// 实参个数少于形参,多余形参被定义为undefined,结果为NaN
getSum(1);
</script>
</head>
<body>
</body>
</html>
- 效果图
4.5 函数的返回值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
function getMax(arr){
var max1=arr[0];
for(var i=1;i<arr.length;i++){
if(arr[i]>max1){
max1=arr[i];
}
}
return max1;
}
var arr1=[1,2,3];
var result=getMax(arr1);
console.log(result);
</script>
</head>
<body>
</body>
</html>
- 效果图
注意点
- return只能返回一个值,如果用逗号隔开多个值,以最后一个为准
- 要想返回多个值,可以考虑使用数组返回
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
function fn1(num1,num2){
// 返回的值逗号分隔,只会返回最后一个
return num1,num2;
}
// 返回多个值,使用数组
function fn2(num1,num2){
return [num1,num2];
}
console.log(fn1(1,2));
console.log(fn2(1,2));
// 不加return语句,返回值undefined
function fn3(num1,num2){
}
console.log(fn3(1,2));
</script>
</head>
<body>
</body>
</html>
- 效果图
4.6 arguments的使用
- 当我们不确定有多少个参数传递的时候,可以用arguments来获取,在JavaScript中,arguments实际上是当前函数的一个内置对象,arguments对象中存储了传递的所有实参
- arguments的展示形式是一个伪数组,因此可以遍历,特点:
- 具有length属性
- 按索引方式存储
- 不具有数组的push,pop方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
// arguments的使用
function fn1(){
console.log(arguments);
console.log(arguments.length);
}
fn1(1,23,45,55,5);
</script>
</head>
<body>
</body>
</html>
- 效果图
4.7 匿名函数(函数表达式)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
var fn=function(){
console.log('我是匿名函数(函数表达式)');
}
fn();
</script>
</head>
<body>
</body>
</html>
- 效果图
-
fn是变量名,不是函数名
-
fn中存放的不是值,而是函数
-
可以传参
5. 作用域
5.1 全局作用域
- 作用于所有代码执行的环境(整个script标签内部)或者一个独立的js文件
5.2 局部作用域
- 函数内的代码环境,函数作用域
5.3 全局变量
- 在全局作用域下的变量
- 在局部作用域下的未声明直接赋值的变量
5.4 局部变量
- 函数内部使用的
- 函数内部var声明的
- 函数形参
5.5 全局变量和局部变量的区别
- 全局变量:在任何地方都可使用,只有在浏览器关闭时才会被销毁,占内存
- 局部变量:函数内部使用,在函数代码块结束后,会被销毁,节省空间
5.6 js没有块级作用域
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
if(true){
var num=10;
}
// 输出num
console.log(num);
</script>
</head>
<body>
</body>
</html>
- 效果图
- 块级作用域为{}包起来的代码块
- es6中新增块级作用域,现阶段没有
5.7 作用域链
- 如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
- 根据内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
var num=10;
function fn1(){
var num=100;
function fn2(){
// num根据就近原则找到外部变量
console.log(num);
}
fn2();
}
fn1();
</script>
</head>
<body>
</body>
</html>
- 效果图
- 查找机制:就近原则
6.JavaScript预解析
- js引擎解析Javascript代码是分为两步:预解析和代码执行
- 预解析:在当前作用域下,js代码执行前,浏览器会默认把带有var和function声明的变量在内存中提前声明或者定义
- 代码执行:从上到下执行代码
6.1 变量提升
-
预解析也叫做变量、函数提升
-
变量提升:变量的声明会被提升到当前作用域的最上面,变量的赋值不会提升
6.2 函数提升
- 函数的声明会被提升到作用域的最上面,但是不会调用函数
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
// 变量提升,声明提升,赋值不提升
console.log(num);
var num=10;
fn();
var fn=function(){
console.log('666');
}
// 函数提升
fn1();
function fn1(){
console.log('fn1');
}
</script>
</head>
<body>
</body>
</html>
- 效果图
预解析特殊案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
fn1();
console.log(c);
console.log(b);
console.log(a);
function fn1(){
// 变量提升,var a 声明提升
// b,c 作为全局变量 b=9,c=9
var a=b=c=9;
console.log(a);
console.log(b);
console.log(c);
}
</script>
</head>
<body>
</body>
</html>
- 效果图
7. 对象
7.1 什么是对象
-
对象是一个具体的事物
-
在JavaScript中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串,数值,数组,函数。
-
对象有属性和方法组成
- 属性:事物的特征,在对象中用属性来表示
- 方法:事物的行为,在对象中用方法来表示
-
图解
7.2 为什么需要对象
- 可以将某个具体的事物表达的更清晰,更强大
7.3 对象的创建
7.3.1 创建对象的三种方式
- 利用字面量来创建对象
- 利用 new Object 创建对象
- 利用构造函数创建对象
7.3.2 根据字面量创建对象
- 对象字面量:就是花括号{}里面包含表达这个具体事物(对象)的属性和方法
- {}里面采取键值对的形式表示
- 对象调用另一种形式:对象[‘属性名’];
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
// 根据字面量创建对象
var adog={
uname:'keke',
age:5,
color:'blue',
habit:'play',
playGame: function(){
console.log('playgame');
}
};
// 使用对象
console.log(adog.age);
console.log(adog.color);
adog.playGame();
</script>
</head>
<body>
</body>
</html>
- 效果图
7.3.3 变量、属性、函数、方法总结
- 变量:单独声明赋值,单独存在
- 属性:对象里面的变量称为属性,不需要声明,用来描述该对象的特征
- 函数:单独存在的,通过函数名()就可以调用
- 方法:对象里面的函数,方法不需要声明,使用对象.方法名就可以调用,方法用来描述该对象的行为和功能
7.3.4 利用new Object创建对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
var mingren=new Object();
mingren.uname='鸣人';
mingren.age=18;
mingren.sex='男';
mingren.playgame=function(){
console.log('666');
}
mingren.playgame();
console.log(mingren.age);
</script>
</head>
<body>
</body>
</html>
- 效果图
7.3.5 利用构造函数创建对象
- 前面两种方法一次只能构造一个对象,使用构造函数可以批量构造对象
- 构造函数:一种特殊的函数,主要用于初始化对象,里面封装的是对象的一些公共属性和方法
- 构造函数用于创建某一类对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
// 构造函数
function Person(age,name,sex){
this.age=age;
this.name=name;
this.sex=sex;
this.playgame=function(game){
console.log(game);
}
}
// 调用构造函数
var p1= new Person(18,'aaa','男');
var p2=new Person(19,'bbb','女');
console.log(p1.age);
p1.playgame('wzry');
console.log(p2.name);
p2.playgame('yylm');
</script>
</head>
<body>
</body>
</html>
- 效果图
注意点
- 构造函数约定首字母大写
- 函数内的属性和方法前需要添加this,表示当前对象的属性和方法
- 构造函数不需要return返回结果
- 当我们创建对象时,必须用new来调用构造函数
7.3.6 new关键字
- new在执行时会做四件事情
- 在内存中创建一个新的空对象
- 让this指向这个新的对象
- 执行构造函数里面的代码,给这个新对象添加属性和方法
- 返回这个新对象(所有构造函数里面不需要return)
7.3.7 构造函数和对象
- 构造函数:对象的公共部分,泛指某一大类
- 创建对象:通过new关键字创建对象的过程称为对象实例化