数组
1. 数组的概念
- 数组的定义:数组是指一组数据的集合,其中的每个数据被称作元素,在数组中可以存放任意类型的元素。数组是一种将一组数据存储在单个变量名下的优雅方式。
- 简而言之,数组可以把一组相关的数据一起存放,并提供方便的访问(获取)方式。
<script>
//普通变量一次只能存储一个值
var num = 10;
//数组一次可以存储多个值
var arr = [1,2,3,4,5];
</script>
2. 创建数组
2.1 数组的创建方式
JS中创建数组有两种方式:
- 利用 new 创建数组
- 利用数组字面量创建数组
2.2 利用 new 创建数组
<script>
var 数组名 = new Array();
var arr = new Array();//创建一个新的空数组
</script>
- 注意 Array(),A要大写;
2.3 利用数组字面量创建数组
<script>
//1. 使用数组字面量方式创建空的数组
var 数组名 = [];
//2. 使用数组字面量方式创建带初始值的数组
var 数组名 = ['小白','小黑','大黄','小绿'];
</script>
- 数组的字面量是方括号 [ ];
- 声明数组并赋值称为数组的初始化;
- 这种字面量方式是我们以后使用最多的方式;
2.4 数组元素的类型
数组中可以存放任意类型的数据,例如字符串、数字、布尔值等;
var 数组名 = [1,true,3.14,'小绿'];
3. 获取数组中的元素·
索引(下标):用来访问数组元素的序号(数组下标从零开始)。
数组可以通过索引来访问、设置、修改对应的数组元素,我们可以通过**“数组名[索引]’的形式来获取数组中的元素。
这里的访问**就是获取得到的意思;
<script>
//定义数组
var arr = [1,2,3];
//或取数组中的第2个元素
alert(arr[1]);
</script>
4. 遍历数组
4.1 遍历
遍历:就是把数组中的每个元素从头到尾都访问一次
<script>
var arr = ['red', 'green', 'blue'];
for (var i = 0; i < 3; i++) {
console.log(arr[i]);
}
</script>
4.2 数组长度
数组的长度:数组名.length
<script>
var arr = ['red', 'green', 'blue'];
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
console.log('----------');
for (var i = 0; i < 3; i++) {
console.log(arr[i]);
}
</script>
5. 数组中新增元素
5.1 通过修改 length 长度来实现数组扩容的目的;
-length 属性是可读写的
<script>
var arr = ['red', 'green', 'blue', 'pink'];
arr.length = 7;
console.log(arr);
console.log(arr[4]);
console.log(arr[5]);
console.log(arr[6]);
</script>
其中索引号是 4,5,6 的空间没有给值,就是声明变量未给值,默认就是underfined
5.2 通过修改索引号,追加数组元素,新增数组元素
<script>
var arr = ['red', 'green', 'blue', 'pink'];
arr[3] = 'yello';
console.log(arr);
arr[4] = 'blue';
console.log(arr);
arr[0] = 'pink';
console.log(arr);//替换原本数组中的元素
arr = 'color';
console.log(arr);//不要直接给数组名赋值,容易丢失原有元素
</script>
6. 数组案例
6.1 遍历数组案例
- 求数组 [2,6,1,7,4] 里面所有元素的 和 以及 平均值
<script>
//1. 声明一个求和变量 sum;
// 遍历这个数组,把里面每个数组元素加到 sum 里面;
// 用求和变量 sum 除以数组的长度就可以得到数组的平均值;
var arr = [2, 6, 1, 7, 4];
var sum = 0;
var average = 0;
for (var i = 0; i < arr.length;i++) {
sum += arr[i];//我们加的是数组元素 arr[i] 不是计数器 i
}
average = sum / arr.length;
console.log(sum, average);//想要输出多个变量,用逗号分隔即可
</script>
2. 将数组 [‘red’, ‘green’, ‘blue’, ‘pink’] 转换为字符串,并且用 | 或其它符号进行分割
<script>
//1. 需要一个新的变量用来存放转换完的字符串 str;
//2. 遍历原来的数组,分别把里面的数组取出来,加到字符串里面;
//3. 同时在后面多加一个分隔符;
var arr = ['red', 'green', 'blue', 'pink'];
var str = '';
var sep = '|';
for (var i = 0; i < arr.length; i++) {
str += arr[i] + sep;
}
console.log(str);
</script>
6.2 新增元素案例
- 新建一个数组,里面存放十个整数(1~10)
<script>
//核心原理:使用循环来追加数组
// 1. 声明一个空数组 arr;
//2. 循环中的计数器 i 可以作为数组元素存入;
//3. 由于数组的索引号是从 0 开始的,因此计数器从 0 开始更合适,存入的数组元素要 +1;
var arr = [];
for (var i = 0; i < 100; i++) {
arr[i] = i + 1;
}
console.log(arr);
</script>
- 筛选数组,将数组 [2,0,6,1,77,0,52,0,25,7] 中大于等于 10 的元素选出来,进入新数组。
<script>
// 1. 声明一个新的数组用于存放新数据 str
//2. 遍历原来的旧数组,找出大于等于 10 的元素;
//3. 依次追加给新数组 str
var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
var str = [];
var j = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i] >= 10) {
str[j] = arr[i];
j++;
}
}
console.log(str);
</script>
- 删除指定元素,将数组 [2,0,6,1,77,0,52,0,25,7] 中的 0 去掉后,形成一个不包含 0 的新数组。
<script>
//1. 需要一个新数组用于存放筛选之后的数据。
//2. 遍历原来的数组,把不是 0 的数据添加到新数组里面(此时要注意采用数组名 + 搜引号的格式接收数据)。
//3. 新数组里面的个数,用 length 不断累加
var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
var str = [];
for (var i = 0; i < arr.length; i++) {
if(arr[i] != 0) {
str[str.length] = arr[i];
}
}
console.log(str);
</script>
- 冒泡排序(从大到小)
<script>
var arr = [4, 5, 2, 1, 3];
for (var i = 0; i <= arr.length-1; i++) {//外层循环次数
for (var j = 0; j <= arr.length-i; j++) {//里面的循环管
if (arr[j] < arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
console.log(arr);
</script>
函数
1.函数的概念
- 概念:函数就是封装了一段可以被重复执行调用的代码块
- 目的:让大量代码重复使用
2.函数的使用
函数的使用分两步:声明函数;调用函数;
2.1 声明函数;
function 函数名(){
…//函数体
}
- function 声明函数的关键字,全部小写;
- 函数是做某件事情,函数名一般是动词;
- 函数不调用,自己不会执行
function sayHi() {
console.log('hi~~~~');
}
2.2 调用函数;
函数名();
sayHi();
- 调用函数时千万不要忘记加小括号
- 函数本身并不会执行代码,只有调用函数才会执行代码
2.3 函数的封装
- 函数的封装是把一个或者多个功能通过函数的方式封装起来,对外植体狗一个简单的函数接口;
简单函数使用例子
利用函数计算 1~100 之间的累加和
function getSum() {
var sum = 0;
for (var i = 1; i <= 100; i++){
sum += i;
}
console.log(sum);
}
getSum();
3.函数的参数
3.1 小结
- 函数可以带参数也可以不带参数;
- 声明函数时,函数括号里面的是形参,形参的默认值是 undefined;
- 调用函数时,函数名括号里面的是实参;
- 多个参数之间用逗号分隔;
- 形参的个数可以和实参不匹配,但是结果不可估计,我们要尽量匹配;
3.2 形参和实参的具体位置、
function 函数名(形参1, 形参2,...) {
函数体;
}
getSum(实参1,实参2,...);
3.3 函数形参和实参个数不匹配的问题
参数个数 | 说明 |
---|---|
实参个数 = 形参个数 | 输出正确结果 |
实参个数 > 形参个数 | 只取到形参个数 |
实参个数 < 形参个数 | 多的形参被定义为 underfined,结果为 NaN |
- 注意:在JavaScript中,形参的默认值是 undefined。
4.函数的返回值
4.1 return 语句
- return 语句可以实现将值返回给调用者;
- 返回值格式
function 函数名() {
…return 需要返回的结果;
}
函数名();
- 我们函数只是实现某种功能,最终的结果需要返回给函数的调用者函数名(),通过 return 实现的;
- 只要函数遇到 return,就把后面的结果返回给函数的调用者“函数名() = return 后面的结果;
- 代码验证
function getResult() {
return 666;
}
getResult(); //getResult() = 666
- 注意事项
- return 终止函数,return 后面的函数的代码不会执行;
- return 只能返回一个值(return num1,num2;——>最终返回最后一个值);
5.arguments的使用
当我们不确定有多少个参数传递的时候,可以用 arguments来获取。在JavaScript中,arguments 实际上它是当前函数的一个内置对象。所有函数都内置了一个 arguments 对象,arguments 对象中存储了传递的所有实参。
arguments展示形式是一个伪数组**,因此可以进行遍历。伪数组具有以下特点:
- 具有 length 属性;
- 按索引方法储存数据;
- 不具有数组的 push(),pop() 等方法;
例子:利用函数求任意个数的最大值
function getMax() {
var max = arguments[0];
for (var i = 1;i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
console.log(getMax(1,2,3));
console.log(getMax(1,2,3,4,5));
console.log(getMax(11,2,34,444,5,100));
6.函数的两种声明方式
- 利用函数关键字自定义函数(命名函数)
function fn() {
}
- 函数表达式(匿名函数)
var fun = function(aru) {
console.log('我是函数表达式');
console.log(aru);
}
fun(123)
- fun 是变量名,不是函数名;
- 函数表达式声明方式跟声明变量差不多,只不过变量里面存的是值,而函数表达式里面存的是函数;
- 函数表达式也可以进行传递函数;
7.函数的案例
利用函数封装方式,翻转任意一个数组
function reverse(arr) {
var newArr = [];
for (var i = arr.length - 1;i >= 0; i--) {
newArr[newArr.length] = arr[i];
}
return newArr;
}
var arr1 = reverse([1, 3, 4, 6, 9]);
console.log(arr1);
var arr2 = reverse(['red','yello','bule']);
console.log(arr2);
利用函数封装方式,对数组排序——冒泡排序
<script>
function sort(arr) {
for (var i = 0; i < arr.length - 1; i++) {
for (var j = 0; j < arr.length - i - 1; j--) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
var arr1 = sort([1, 4, 2, 9]);
console.log(arr1);
var arr2 = aort([11, 7, 22, 999]);
console.log(arr2);
</script>
判断闰年(能被 4 整除并且不能被 100 整除,或者能被 400 整除)
function run(year) {
var flag = false;
if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
flag = true;
}
return flag;
}
console.log(run(2000));
console.log(run(2022));
函数可以调用另外的一个函数
因为每个函数都是独立的代码块,用于完成特殊任务,因此经常会用到函数相互调用的情况
function fn1() {
console.log(11);
fn2();
}
fn1();
function fn2() {
console.log(22);
}
作用域
1. 作用域
1.1 作用域概述
- JavaScript作用域:通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用的代码范围局势这个名字的作用域。作用域提高了程序逻辑的局限性,增强了程序的可靠性,减少了名字冲突;
2. 变量的作用域
2.1 变量作用域的分类
- 全局变量
- 局部变量
2.2 全局变量
- 定义:在全局作用域下的变量,在全局下都可以使用
- 注意:如果在函数内部,没有声明直接赋值的变量也属于全局变量
var num = 10;
var num = 30;
console.log(num);//30
- 全局变量在代码的任意位置都可以使用;
- 在全局变量的作用下 var 声明的变量,是全局变量;
- 特殊情况下,在函数内不使用 var 声明的变量也是全局变量(不建议使用)
2.3 局部变量
- 定义:在局部作用域(比如函数)下的变量,只能在局部使用;
- 注意:函数的形参也可以看成局部变量;
function fn(){
//局部作用域
var num = 20;
console.log(num);
}
fn();//20
- 局部变量只能在该函数的内部使用;
- 在函数内部 var 声明的变量是局部变量;
- 函数的形参实际上就是局部变量;
2.4 全局变量和局部变量的区别
- 全局变量:在任何一个地方都可以使用,只有在浏览器关闭时才会被销毁,比较占内存;
- 局部变量:之在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块运行结束后,就会被销毁,因此更节省空间;
3. 作用域链
- 只要是代码,就至少有一个作用域;
- 写在函数内的局部作用域;
- 如果函数中还有函数,那么在这个作用域中就又可以生成一个作用域;
- 根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称为作用域链。
- 原则:就近原则
function fn(){
//局部作用域
var num = 20;
function fun(){
console.log(num);
}
fun();
}
fn();//20
预解析
1. 预解析
- JavaScript代码是由浏览器中的JavaScript解释器来执行的。JavaScript 解析器在运行JavaScript 过程中,分成两步:预解析和代码执行;
- 预解析:JavaScript 引擎会把 JavaScript 里面所有的 var 还有 function 提升到当前作用域的最前面;
- 代码执行:按照代码书写的顺序从上往下执行;
2. 变量预解析和函数预解析
- 预解析分成 变量与解析(变量提升)和 函数预解析(函数提升)
- 变量提升:就是把所有的变量声明提升到当前的作用域的最前面,不提升赋值操作;
- 函数提升:就是把所有的函数声明提升到当前作用域的前面,不调用函数;
3.预解析案例
var num = 10;
function fn() {
console.log(num);
var num = 20;
console.log(num);
}
fn();
对象
1. 对象
1.1 对象的定义
- 在JavaScript 中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等;
- 对象是由属性和方法组成的:
- 属性:事物的特征,在对象中用属性来表示(常用名词);
- 方法:事物的行为,在对象中用方法来表示(常用名词);
1.2 对象的作用
保存一个值时,可以使用变量,保存多个值(一组值)时,可以使用数组。如果要保存一系列信息,可以建立对象表达结构;
个人信息保存
var arr = ['张三丰','男',128,180];
更清晰的表达
person.name='张三丰';
person.name='男';
person.age='128';
person.height='180';
2. 创建对象的三种方式
- 利用字面量创建对象
- 利用** new Object **创建对象
- 利用构造函数创建对象
2.1 创建字面量创建对象
var obj = {};
——>创建了一个空对象
var obj = {
uname: '张三丰',
age: 18,
sex: '男',
sayHi: function() {
console.log('hi~~~');
}
}
- 里面的属性或者方法我们采用键值对的方式 (属性名:值);
- 多个属性或者方法中间用逗号隔开;
- 方法冒号后面跟的是一个匿名函数;
2.2 使用对象
- 调用对象的属性,我们采用(对象名. 属性名)
console.log(obj.uname);
- 调用属性还有一种方法(对象名[‘属性名’])
console.log(['age']);
- 调用对象的方法(对象名. 方法名())千万别忘记小括号
obj.sayHi();
2.3 变量、属性、函数、方法总结
- 变量:单独声明赋值,单独存在;
- 属性:对象里面的变量称为属性,不需要声明,用来描述该对象的特征;
- 函数单独存在的,通过“函数名()”的方式就可以调用;
- 方法:对象里面的函数称为方法,方法不需要声明,使用“对象.方法名()”的方式就可以调用,方法用来描述该对象的行为和功能;
- 变量和属性是相同的,他们都用来存放数据;
- 函数和方法的相同点,都是实现某种功能;
2.4 利用new Object 创建对象
var obj = new Object();//创建了一个空的对象
obj.uname = '张三丰';
obj.age = 18;
obj.sex = '男';
obj.sayHi = function() {
console.log('hi~~~');
}
//利用 = 赋值的方法,添加对象的属性和方法
//每个属性和方法之间用分号结束
console.log(obj.uname);
console.log(obj['sex']);
obj.sayHi;
2.5 利用构造函数创建对象
- 构造函数:是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与 new 运算符一起使用。我们可以把对象中一些公用的属性和方法抽取出来,然后封装到这个函数里面。
- 问社么要使用构造函数:因为前两种创建方式一次只能创建一个对象;
- 语法格式
function 构造函数名() {
this.属性 = 值;
this.方法 = function() {}
}
function Star(uname, age,sex) {
this.name = uname;
this.age = age;
this.sex = sex;
}
var ldh = new star('daming',18,'boy');
console.log(ldh.name);
console.log(ldh['sex']);
var sam = new Star('sam',17,'boy');
console.log(sam.name);
console.log(sam.age);
- 构造函数名字首字母要大写
- 我们构造函数不需要 return,就可以返回结果;
- 我们构造调用函数,必须使用 new;
- 我们只要 new Star() ,调用函数就创建一个对象;
- 我们的属性和方法前面必须添加 this;
2.6 构造函数和对象
- 构造函数:抽取了对象的公共部分,封装到了函数里面,泛指的某一大类;
- 对象:特指是一个具体的事物;
- 我们利用构造函数 new 创建对象的过程我们也称为对象的实例化;
3. new 关键字
new在执行时会做四件事情:
- 在内存中创建一个新的空对象;
- 让 this 指向这个新的对象;
- 执行构造函数里面的代码,给这个构造函数添加属性和方法;
- 返回这个新对象(搜易构造函数里面不需要 return)
4. 遍历对象属性
- 方法:
for ... in
语句用于对数组或者对象的属性进行循环操作; - 语法:
for (变量 in 对象) {...}
var obj = {
name: '廉颇',
type: '力量型',
blood: '500血量',
attack: '近战'
}
for (var k in obj) {
console.log(k);//k 为变量,输出得到:属性名;
}
for (var key in obj) {
console.log(obj[key]);//对象名[变量] 得到的是:属性值;
}
5. 小结:
- 对象可以让代码结构更加清晰;
- 对象复杂数据类型 object;
- 本质:对象就是一组无序的相关属性和方法的集合;
- 构造函数泛指某一大类;
- 对象实例特指一个事物;
- for… in语句用于对对象的属性进行循环操作;