这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战
函数
函数的基本格式
// 定义函数
function 函数名(){
函数体
}
//调用函数
函数名()
//函数体的代码不会自动执行,需要等到函数被调用才会执行函数体代码。调用一次,就执行一次
函数的参数
//带参数的函数声明
function 函数名(形参){
//函数体
}
//带参数的函数调用
函数名(实参)
形参 = 实参
形参和实参
1. 形式参数:在声明一个函数的时候,为了函数的功能更加灵活,有些值是固定不了的,对于这些固定不了的值。
我们可以给函数设置参数。这个参数没有具体的值,仅仅起到一个占位置的作用,
我们通常称之为形式参数,也叫形参。
2. 实际参数:如果函数在声明时,设置了形参,那么在函数调用的时候就需要传入对应的参数,
我们把传入的参数叫做实际参数,也叫实参。
函数的返回值
//语法格式
function 函数名(形参){
return 值
}
var 变量 = 函数名(实参)
小结
如果函数没有return语句或者return语句后面没有返回值,则函数返回undefined值,如果return后面有值,则返
回该值,return除了能返回指定的值,还能结束函数。
推荐的做法是要么让函数始终都返回一个值,要么永远都不要返回值。
函数arguments的使用
//定义函数
function f1(){
//获取函数调用,传入的参数
console.log(arguments.length)
}
f1(10, 20, 30, 40)
匿名函数
没有函数名字的函数称作匿名函数
var fn = function(){}
语法格式
//定义匿名函数
var fn = function(){
console.log('hello')
}
//调用匿名函数
fn()
作用域
作用域相关概念
作用域 -> 全局作用域和局部作用域
全局作用域 -> 网页一打开就形成的全局作用域
全局变量 -> 在全局作用域下形成的变量加全局变量(除了函数里面定义的变量都可以叫全局变量)
局部作用域 -> 函数的执行形成的一个局部作用域
局部变量 -> 在局部作用域下形成的变量叫局部变量
var num = 1 //全局变量
function fun(){
var num = 2 //局部变量
return num
}
console.log(fun()) //2
块级作用域 -> 了解 -> 扩展
//块级作用域:一对大括号就可以看成是一块,在这块区域中定义的变量,只能在这个区域中使用,但是在js中在
//这个块级作用域中定义的变量,外面也能使用;说明:es5没有块级作用域,只有函数除外
{
var num =10
console.log(num)
}
console.log(num) -> 10
作用域链
作用域链:从局部作用域往上级一级一级查找
var num = 10;
function f1() {
//var num = 20;
function f2() {
//var num = 30;
function f3() {
//var num = 50;
console.log(num);
}
f3();
}
f2();
}
f1();
函数中定义的变量称为局部变量,它只属于当前函数的作用域及其嵌套函数的作用域中,外界无法访问。
也就是一种由内而外的访问,反之则不行。
预解析 -> 变量提升
提升变量声明 -> 变量声明提升到当前作用域最前面 -> 只提升声明,不提升赋值
提升函数声明 -> 函数的声明提升到当前作用域的最前面 -> 只提升声明,不会提升调用
console.log(a);
var a = 123;
console.log(a);
console.log(f);
f();
function f() {
console.log("函数声明提升");
}
预解析处理
var a;
function f() {
console.log("函数声明提升");
}
console.log(a);// undefined
a = 123;
console.log(a);// 123
console.log(f);// f函数
f();// "函数声明提升"
调用执行:自上而下的执行代码
变量提升和作用域的关系
例
f();
function f() {
console.log("1");
}
f();
function f() {
console.log("2");
}
f();
function f() {
console.log("3");
}
预解析
function f(){
console.log("3")
}
fn()
fn()
fn()
为什么解析之后只剩下一个函数,而且是最后一个呢?
因为三个函数的名称一样,后面的将前面的覆盖了,所以最后只剩下最后一个函数
例
console.log(a);
var a = 123;
console.log(a);
function f1() {
console.log(a);
var a = 456;
console.log(a);
}
f1();
console.log(a);
预解析
var a;//变量声明提升
function f1() {//函数声明提升
var a;//变量声明提升
console.log(a);//undefined
a = 456;
console.log(a);//456
}
console.log(a);//undefined
a = 123;
console.log(a);//123
f1();
console.log(a);//123
总结:同一个作用域下,函数内部的局部变量也会在函数内部进行变量提升
声明提升规则
变量和变量同名,解析之后只存在一个当前变量的声明
console.log(a)
var a = 123
console.log(a)
var a = 456
console.log(a)
var a ]
console.log(a) undefined
a = 123
console.log(a) 123
a = 456
console.log(a) 456
函数和变量同名,函数声明提升,忽略变量的声明
console.log(a)
var a = 123
console.log(a)
function a(){}
console.log(a)
function a(){}
console.log(a)
解析
var a
function a(){}
console.log(a) //函数a
a = 123
console.log(a) 123
console.log(a) 123
console.log(a) 123
如果是匿名函数,则只将前面的变量声明提升,函数不动
function fn1() {
}
console.log(fn1);
console.log(fn2);
var fn2 = function () {
};
console.log(fn2);
预解析
function fn1(){}
var fn2
console.log(fn1) //函数fn1
console.log(fn2) //undefined
fn = function(){}
console.log(fn2) //函数2
练习
console.log(num, str);
var num=18;
var str="lily";
function fn2() {
console.log(str, num);
num=19;
str="candy";
var num=14;
console.log(str, num);
}
fn2();
console.log(str, num);
内置对象
Math对象提供了一些和数学相关的运算的功能,如 取绝对值,取随机数,取最大、最小值等等
- Math.abs() -> 取指定数的绝对值
console.log(Math.abs('-1'));//1
console.log(Math.abs('-2'));//2
console.log(Math.abs(null));//0
console.log(Math.abs("string"));//NaN
console.log(Math.abs());//NaN
- Math.random() -> 获取一个 0 到 1之间的随机数浮点数,包括0不包括1,可以用 (0, 1) 表示
console.log(Math.random());
- Math的其他方法 -> 了解
//Math.ceil() 向上取整
console.log(Math.ceil(12.03));
// Math.floor() 向下取整
console.log(Math.floor(12.92));
// Math.max()/Math.min() // 取最大和最小值
console.log(Math.max(10,1,9,100,200,45,78));
console.log(Math.min(10,1,9,100,200,45,78));
//Math.round()四舍五入
console.log(Math.round(20.49));
console.log(Math.round(20.5));
// 保留2位小数
var num =12.365
console.log(num.toFixed(2)); //12.37 四舍五入
console.log(Math.floor(num*100)/100); // 不四舍五入
Date对象
- 获取指定部分日期
var now = new Date(); // 获取当前时间对象
// getSeconds() 根据本地时间,返回一个指定的日期对象的秒数。 0-59
console.log(now.getSeconds());
// getMinutes() 根据本地时间,返回一个指定的日期对象的分钟数。 0-59
console.log(now.getMinutes());
// getHours() 根据本地时间,返回一个指定的日期对象的小时数 0-23
console.log(now.getHours());
// getDay() 返回星期几 *** 0 表示周日,6 表示周六 ***
console.log(now.getDay());
// getDate() 返回当前月的第几天
console.log(now.getDate());
// getMonth() 返回月份,***从0开始***
console.log(now.getMonth());
// getFullYear() 返回4位的年份 如 2021
console.log(now.getFullYear());
- 时间对象的应用
var timestamp = new Date().getTime() // 获取一个时间戳
var now = new Date(timestamp) // 通过时间戳获取当前时间对象
// 通过当前时间对象获取时分秒
var year=now.getFullYear();
var month=now.getMonth()+1;
var date=now.getDate();
var hour=now.getHours();
var minute=now.getMinutes();
var second=now.getSeconds();
// 拼接成网页中展示的字符串
var timeStr = year+"-"+month+"-"+date+" "+hour+":"+minute+":"+second;
字符串常用方法 -> 熟悉
.length ----->字符串的长度
var str = "hello word";
console.log(str.length);//10
.charAt(索引),返回值是指定索引位置的字符串,超出索引,结果是空字符串
var str="hello word";
var result=str.charAt(1);
var result = str.charAt(100);//这个超出了输出空字符串
console.log(result);
.fromCharCode(数字值,可以是多个参数),返回的是ASCII码对应的值
var str = String.fromCharCode(97,98,99);
console.log(str);
.concat(字符串1,字符串2,...);返回的是拼接之后的新的字符串
var str = "小明";
console.log(str.concat("喜欢", "凤姐", "这是", "真的"));
.indexOf(要找的字符串,从某个下标开始) 返回的是这个字符串的索引值,没找到返回-1,第二个参数可以不要
var str = "我们今天真开心";
var index = str.indexOf("真",5);
console.log(index);//返回-1,因为从第5个开始后面就没有真,如果不写后面的5结果就是4正好是真的索引位置
.lastIndexOf(要找的字符串) 从后往前找,但是索引仍然是从左向右的方式,找不到则返回-1
var str="hello word";
var index=str.lastIndexOf("o");
console.log(index);//返回结果7,从后面往前找到后面的那个o(返回的是后面的那个的下标)
.replace("原来的字符串","新的字符串");用来替换字符串的
var str = "小明真的好帅哦,真的好勇敢哦";
if(str.indexOf("帅") != -1){
str = str.replace("帅","丑");
}else{
console.log("不存在");
}
console.log(str);
.slice(开始的索引,结束的索引) -> 不包含结束位置
var str = "如果有一天我邪恶了,请记住,我曾纯洁过";
//从索引5的位置开始提取,到索引为10的前一个结束,不包含第10个字符,并返回这个提取后的字符串
str=str.slice(5,10);
console.log(str);
.split("以什么字符串拆分",拆分后留下的字符个数) 后面参数可以省略
var str="乔峰|慕容|凤姐|梅超风|小苏|大蛇丸";
var arr=str.split("|");
console.log(arr);//["乔峰", "慕容", "凤姐", "梅超风", "小苏", "大蛇丸"]
.substr(开始的位置,个数) 返回的是截取后的新的字符串,个数也可以省略,就是从什么位置开始截取到最后
var str="哈哈,小明真的是好帅哦";
str=str.substr(5,5);
console.log(str);//真的是好帅
.substring(开始的索引,结束的索引),返回截取后的字符串,不包含结束的索引字符串
var str="哈哈,小明真的是好帅哦";
str=str.substring(5,9);
console.log(str);
.toLocaleLowerCase() 转小写字母
.toLowerCase();转小写,两个方法都是转小写。
var str="HELLO";
//str=str.toLocaleLowerCase();
str=str.toLowerCase();
console.log(str);
.toLocaleUpperCase()转大写
.toUpperCase() 转大写
var str="hello";
//str=str.toLocaleUpperCase();
str=str.toUpperCase();
console.log(str);
.trim() 删除两端空格,中间的空格是删除不了的
var str=" 哦,这 是一个神奇的一天 ";
str=str.trim();
console.log("===="+str+"====");
Array对象
创建Array对象
//如何创建一个数组
//方式一:数组字面量
var numbers = [1, 2, 3];
console.log(numbers);
//方式二:构造函数,使用构造函数创建对象,跟以前不同的是,此处使用的是数组的构造函数
var array = new Array(3,2,1);
console.log(array); // [3, 2, 1]
//创建一个长度为5的空数组
var array1 = new Array(5);
console.log(array1);
判断变量是否是Array
//判断对象是不是数组类型有两种方式:
//1、instanceof关键字
var arr=[];
console.log(arr instanceof Array);//结果是true
//2、Array.isArray(对象)---->判断这个对象是不是数组
console.log(Array.isArray(arr));//结果是true
Array对象的常用方法
//.push(值1,值2...);把值往数组后面添加、返回值是追加数据之后的数组长度,参数的数据类型不限;
var arr1=[10,20,30,40,50];
var result = arr1.push(100,200);
console.log(result,arr1);//返回结果:7、[10, 20, 30, 40, 50, 100, 200]
//.unshift(值1,值2...)往数组前面添加,返回的是改变后的数组的长度参数数据类型不限;
var arr2=[10,20,30,40,50];
var result = arr2.unshift(100,200);
console.log(result,arr2);//返回结果:7、[100, 200, 10, 20, 30, 40, 50]
//pop()删除数组的最后一项,参数无 返回值是删除的那一项;
var arr3=[10,20,30,40,50];
var result=arr3.pop();
console.log(result,arr3);//返回结果:50和[10, 20, 30, 40]
//shift()删除数组的第一项,参数无 返回值是删除的那一项;
var arr4=[10,20,30,40,50];
var result=arr4.shift();
console.log(result,arr4);//返回结果:10和[20, 30, 40, 50]
数组一些其他方法
//.indexOf(元素值)查看某个元素在数组里面的索引,如果没有这个元素返回值是-1
var arr2=[10,20,30,40,50];
var index=arr2.indexOf(30);
console.log(index);
/*
* 返回值是该元素在数组中的索引值,如果没有返回-1
indexOf(n,m)从索引m开始查看n在数组里面的索引值
lastIndexOf()从后往前看
* */
//join("字符串")把数组按照指定的字符串拼接成一个字符串,如果没有参数就按默认的逗号拼接成字符串,如果有参数就按照指定的字符串拼接成字符串
var arr2=["小白","小黑","小红","小芳","小绿","小花"];
var str = arr2.join("|");
console.log(str);
//reverse() 数组反转 参数无 返回值是反转后的数组,(改变原有数组)
var arr3=[10,20,30,40,50];
var temp=arr3.reverse();//反转
console.log(temp,arr3);//[50, 40, 30, 20, 10]两个结果一样
//sort()数组排序 返回值是排好序的数组,改变原有数组。参数可传可不传,如果传参数,参数是回调函数。如果不传参数的时候只能排10以内的数字
//不传参数的sort()排序----从小到大
var ary=[1,2,3,6,5,4];
var temp=ary.sort();
console.log(temp); //结果:[1, 2, 3, 4, 5, 6]
console.log(ary); //结果:[1, 2, 3, 4, 5, 6]
//sort()带有参数的升序和降序
//1、从小到大排序 a-b
var ary=[1,2,3,6,5,4,13,12,15,16];
var temp=ary.sort(function (a,b) {
return a-b;//把原数组升序排 从小到大
});
console.log(temp);//结果:[1, 2, 3, 4, 5, 6, 12, 13, 15, 16]
//2、从大到小排列 b-a
var temp=ary.sort(function (a,b) {
return b-a;
});
console.log(temp);//结果:[16, 15, 13, 12, 6, 5, 4, 3, 2, 1]
//slice(n,m)从索引n开始获取到索引m(不包含m)返回值是获取到的元素组成的新数组
var ary=[10,20,30,40,50,60,70,80,90,100];
var temp=ary.slice(2,6);
console.log(temp); //结果是[30, 40, 50, 60] 从索引2开始获取到索引6不包括索引6
//注意:slice();和slice(0);都是把原数组复制一份
//--------------------------------------------------------------------------------------------
//splice(n,m,x/y/z...) 把数组从索引n开始删除m个元素,用x,y...替换删除的m项。返回值是删除的m项组成的新数组
var ary=[1,2,3,4,5,6];
var temp=ary.splice(1,2,7,8,9,10);
console.log(temp);//返回结果是:[2, 3]这个是删除的项组成的新数组,就是删除了2,3
console.log(ary);//返回结果是:[1, 7, 8, 9, 10, 4, 5, 6]
//当m项是0的时候,它把x,y...替换项放到索引n的前面
var ary=[1,2,3,4,5,6];
var temp=ary.splice(1,0,7,8,9,10);
console.log(temp);//[] 返回空数组,因为没有删除
console.log(ary); //结果:[1, 7, 8, 9, 10, 2, 3, 4, 5, 6]
//当不写x、y替换项的时候代表删除数组的元素
var ary=[1,2,3,4,5];
var temp=ary.splice(1,2);
console.log(temp);//结果:[2, 3]
console.log(ary);//结果:[1, 4, 5]
//当splice()里面什么都不写的时候,代表没有对数组做任何操作,返回一个空数组
var ary=[1,2,3,4,5];
var temp=ary.splice();
console.log(temp); //结果:[]
console.log(ary);//结果:[1, 2, 3, 4, 5]
//当splice(0) 里面是0 的时候,代表删除整个数组,返回的是原数组的数据,原数组变为空数组
var ary=[1,2,3,4,5];
var temp=ary.splice(0);
console.log(temp); //结果: [1, 2, 3, 4, 5]
console.log(ary);//结果:[]原数组变为空数组