学习内容:函数的介绍,函数参数,函数返回值,变量作用域,逻辑运算符短路运算,arguments关键字的了解,自调用函数(立即执行函数),回调函数。
函数语法 :
1 声明函数 : 代码存入函数中 (声明函数只是存储过程,不会执行函数体)
function 函数名() {
函数体代码
};
2 调用函数 : 执行函数体中代码
函数名();
//1.声明函数 : 声明函数只是把代码存入函数中,并不会执行函数体代码
function fn(){
console.log("1. 代码写久了,肩颈开始酸痛了");
console.log("2. 我要去中医馆保养身体");
console.log("3. 你好,我是本次服务的1号技师");
console.log("4. 不知不觉中,两个小时过去了……快乐的时光总是短暂的");
console.log("5. 您好,本次消费2888元,请喝杯雪碧压压惊");
console.log("6. 我结束了");
};
console.log('这里又写了300行代码');
//郭少(调用者)
console.log('a少也有保养需求');
//2.调用函数
fn();
// console.log("1. 代码写久了,肩颈开始酸痛了");
// console.log("2. 我要去中医馆保养身体");
// console.log("3. 你好,我是本次服务的1号技师");
// console.log("4. 不知不觉中,两个小时过去了……快乐的时光总是短暂的");
// console.log("5. 您好,本次消费1888元,请喝杯雪碧压压惊");
// console.log("6. 我结束了");
console.log('这里又写了500行代码');
//吴少(调用者)
console.log('b少也有保养需求');
//2.调用函数
fn();
函数参数
1 作用:‘调用者’ 传递数据给 ‘函数’
2 语法
传递数据 : 调用者
* 函数名(实参);
接收数据 : 函数
* function 函数名(形参){ 函数体代码 };
3 函数传参本质 : 实参给形参赋值
4 注意点: 实参和形参顺序可以不一致
(1)实参和形参赋值是按照一一对应赋值的
(2)每一个调用者传参是独立的互不干扰,如果没有传,此时默认实参就是undefined
代码如下(示例):
//1.写一个函数: 求任意半径圆的面积
function getArea(r){
let area = Math.PI * Math.pow(r, 2);
console.log(area);
};
//调用
getArea(5);
getArea(10);
//2.写一个函数:求1-任意数字的累加和
function getSum(num){
let sum = 0;
for(let i = 1;i <= num;i++){
sum += i;
};
console.log(sum);
};
//调用
getSum(10);
getSum(100);
//3.写一个函数,求任意数组最大值
function getMax(arr){
let max = -Infinity;
for(let i = 0;i<arr.length;i++){
if(arr[i]>max){
max=arr[i];
};
};
console.log(max);
};
getMax([20,60,88,50]);
getMax([20,60,98,70]);
函数返回值
1 作用:‘函数’ 传递数据给 ‘调用者’
2 语法:
传递数据: 函数
* function 函数名(形参){ 函数体代码; return 返回值;}
接收数据 : 调用者
* let 变量名 = 函数名()
3 注意点:
(1)如果函数没有return,则默认返回值是undefined
(2)如果函数有return,但是return后面没有值,此时默认返回值也是undefined
(3)return可以结束整个函数体。 (类似于循环中的break,只是break用于结束循环,return用于结束函数)
//1.声明函数
function getSum(num){
let sum = 0;
for(let i = 1;i <= num;i++){
sum += i;
};
return 1;
return 2;//不执行,遇到return函数已经结束
};
//2.调用函数
/* 每一个调用者可能对函数的运算结果处理方式不同
(1)在函数外部是无法获取函数内部结果
(2)要想获取函数内部结果,则需要使用函数返回值语法
*/
//调用者A
let res1 = getSum(10);//把返回值存入变量 ,接下来对变量进行操作
console.log( res1 );
// document.write(`${sum}`);//报错
//调用者B
console.log( getSum(100) );//直接打印返回值
js中函数有两种声明方式
// 具名函数
函数声明: function 函数名(){}
// 匿名函数
表达式声明: let 函数名 = function(){}
//1.函数声明 : function 函数名(){ 函数体代码 }
//具名函数:有名字的函数 function 函数名(){}
function fn(){
console.log(1111);
};
fn();
let a = fn;//函数本质是一个变量(存储的是代码),也可以拷贝赋值
a();
//2.表达式声明
//匿名函数:没有名字的函数 function(){}
let fn1 = function(){
console.log(22222);
};
1.变量作用域 : 变量可以起作用(取值/赋值)的范围
全局作用域(全局变量) :函数外面声明变量, 页面任何地方都可以使用
局部作用域(局部变量) :函数里面声明变量,只能在函数内部使用
2.作用域链 : 默认情况下,代码是全局作用域(0级链),当我们声明一个函数之后,这个函数内部形成一个局部作用域(1级),在函数内部又声明函数一个函数,此时就会形成一个新的局部作用域(2级链),以此类推,这种拉链结构称之为作用域链。
变量访问作用域链规则 : 就近原则
当在某一个作用域访访问变量的时候,会先看这个作用域有没有声明,如果有则访问。如果没有则访问上级作用域,如果上级没有,则继续往上找,一直找到作用域最顶端0级还没有找到,此时就会报错 xxx is not defined
//全局作用域 : 全局变量
let num = 10;
function fn(){
//只有函数内部声明的才是局部的,函数本身还是全局的
//全局
num = 20;
console.log('函数内' + num);
//局部
let num1 = 50;
console.log( num1 );
};
fn();
console.log( '函数外' + num );
// console.log( num1 );
//全局作用域(0级链)
let num = 10;
function fn(){
//函数本身还是0级
//1级
let num = 20;
console.log('1级' + num );//20
function fn1(){
//1级
//2级链
// let num = 30;
console.log( '2级' + num );//30
};
fn1();
};
fn();
//0级链
console.log( '0级' + num );//10
下级作用域(2级)可以对上级作用域(0级,1级)的变量进行赋值等操作,但是上级作用域(0级,1级)不能操作下级作用域(2级)的变量。
1.逻辑运算符
&& 逻辑与 : 一假则假
|| 逻辑或 : 一真则真
! 逻辑非 : 取反 true变false,false变成true
2.逻辑运算符短路运算 :如果左边的式子就可以决定逻辑表达式结果,则右边的式子不执行。(为了提高代码解析效率)
3.逻辑运算符短路规则
逻辑与: 找假,左边式子可以转成false,则无条件返回左边式子的值。反正无条件返回右边式子的值。
逻辑或:找真,左边式子可以转成true,则无条件返回左边式子的值。反正无条件返回右边式子的值。
// let num = 10;
// let res = num > 20 && num++;
// console.log( res );//false
// console.log( num );//10
/* 逻辑表达式的结果不一定是布尔类型,也可以是其他的值
// let res = 10 && 20;
// console.log( res );//20
//1.逻辑与口诀 : 一假则假
//短路规则 :找假: 如果左边式子可以转成false,则无条
let res = 1 && undefined;
console.log( res );
//2.逻辑或口诀 : 一真则真
//短路规则 : 找真 : 如果左边式子可以转成true,则无条
let res1 = 1 || undefined;
console.log( res1 );
//3.逻辑非 : 没有短路运算
//原因: 逻辑非只有一个式子
//小测试
let res2 = 10 && undefined && null && 0;
console.log( res2 );//undefined
let res3 = '' || 1 || 10 || undefined || null || 0;
console.log( res3 );//10
/* 短路运算场景:函数默认参数 */
function add(a,b){
/* a默认值是10,b默认值是20 */
a = a || 10;
b = b || 20;
console.log(a,b);
console.log(a + b );
};
add();//undefined,undefined
add(15);//15,undefined
add(25,35);//25,35
1.arguments作用: 获取函数所有的实参
2.arguments是一个伪数组(只有数组三要素:元素,下标,长度。 不能使用数组其他方法)
3.场景: 可以让函数 根据参数数量不同而实现不同的功能
function fn(a,b){
console.log(a,b);
console.log( arguments );
if(arguments.length == 1){
console.log('功能1');
}else if( arguments.length == 2){
console.log('功能2');
}else{
console.log('功能3');
};
};
//js中函数的实参和形参 数量可以不一致
fn(10);//a = 10,b = undefined
fn(10,20);//a = 10,b=20
fn(10,20,30);//a = 10,b=20
1.自调用函数 : 函数自己来调用自己
* 一般用于 匿名函数自调用
2.语法: (function(){})();
(function(){
//局部作用域
let num = 10;
console.log(num);
})();// 函数会立刻执行
/* 自调用语法其实 具名函数也可以使用,只是一般用于匿名函数自调用
函数调用其实有两种语法
函数调用 : 函数名()
自调用 : (function(){})()
*/
(function fn(){
console.log(6666);
})();
回调函数 :如果一个函数的参数也是函数,则这个参数函数称之为回调函数
function fn(a){
console.log(a);
a();//调用回调函数
};
fn(function(){
console.log(666);
});
// function fn(){
// console.log(1111);
// };
// console.log( fn );//变量取值,打印fn中存储的代码
// console.log( fn() );//执行fn,打印返回值
// let a = fn;//变量赋值 fn中存储的数据拷贝一份给变量a
// let b = fn();//调用fn,把fn的返回值存入b
书犹药也,善读之可以医愚
加油,一起进步!