函数
函数总结
一、声明函数
1.有名函数
顾名思义: 有名字的函数
a.加括号自执行
function foo(){//函数名 : foo
//即将执行的代码
console.log( "小郭" );
}
foo();//主动在合适的位置加()执行
document.onclick = foo; //充当事件函数,事件触发时才执行,不能加()
b.事件触发执行
document.onclick = foo;
//充当事件函数,事件触发时才执行,不能加()
//加上括号就是立即执行,刷新页面时就会立马执行
2.匿名函数
没有名字的函数
a.没有参与任何表达式的匿名函数
报错!!!
function (){
console.log( "小张" );
}
b.参与任何表达式的匿名函数
document.onmouseenter = function(){
console.log( "小张" );
};
c.注意!!!
document.onmouseleave = function foo_b(){//参与表达式的函数没必要加名字
console.log( "123" );
};
foo_b();//被赋值的函数不可以主动调用,会报错
二、作用域
当前的变量起作用的范围
1.全局作用域
全局变量 = 全局作用域 = 直接写在script标签第一层的变量
let a = 10;//直接写在<script></script>里面最外层
2.局部作用域
函数能产生局部作用域
let a = 20
function foo_x(){
let b = 10;
console.log( a );//局部作用域可以找全局 => 20
}
foo_x();
console.log( b );//报错 => 局部作用域的东西不能被外层使用
3.局部变量名和全局变量名一样是否有影响?
没有影响,局部变量名和全局变量名一样不冲突
a.取值
let c = 10;
function foo_d(){
let c = 20;
console.log( c );//20 => 就近原则
}
foo_d();
b.赋值
let d = 10;
function foo_e(){
let d = 20;
d = 30;
}
foo_e();
console.log( d );//10 => 就近原则
let e = 10;
function foo_f(){
e = 30;
}
foo_f();
console.log( e );//30
4.函数嵌套作用域
作用域链 : 在某一个作用域使用变量时,先从自身的作用域找起,自身作用域有用自身的,自身作用域没有用上一层作用域的,上一层没有再用上一层的上一层的,直到全局作用域为止,找不到报错.
全局作用域 => GO => Global Object
局部作用域 => AO => Activation Object
let f = 10;
function foo_g(){
let f = 20;
function foo_h(){
console.log( f );//20
}
foo_h();
}
foo_g();
三、函数声明和函数表达式的区别
1.提前调用
函数声明允许提前调用,不报错
aa();//提前调用 不报错
function aa(){
console.log( "aa函数" );
}
通过var let const 定义的函数,不允许提前调用,会报错
//bb();//提前调用 报错
let bb = function(){
console.log( "bb函数" );
};
bb();//不报错
2.立即执行
函数声明立即执行
function cc(){
console.log( "cc函数执行了" );
}//() <= 在这里加括号执行会报错
cc();//不报错
函数表达式,可以加()自执行
let dd = function(){
console.log( "dd函数执行了" );
}();// <= 自执行
四、IIFE 函数表达式自执行
1.把函数用()括起来,再加上括号
(function ee(){
console.log( "111" );
})();//把函数用()括起来,再加上括号就可以自执行了
// 把功能模块化,产生自己的作用域,在不同模块可以使用相同变量名
2. !
! function(){
console.log( "222" );
}();
3. +
+ function(){
console.log( "222" );
}();
4. -
- function(){
console.log( "222" );
}();
5. ~
~ function(){
console.log( "222" );
}();
五、参数
1.形参
定义函数的时候规定好的变量名,作用域于函数内部
该变量名在当前的局部作用域
function ff( a , b ){//a b 为形参,且在当前局部作用域
alert( a+b );
}
ff();
2.实参
调用函数的时候传入的实际数据
function ff( a , b ){//a b 为形参,且在当前局部作用域
alert( a+b );// 6 42
}
ff( 2 , 4 );//实参
ff( 2 , 40);//实参
3.不定参
实参个数不确定时,形参无法预设好一一对应的变量,使用arguments
//求乘积
function gg(){
console.log( arguments );
//可以通过访问arguments的方式来找到所有的实参
//所有实参的集合 => 没有实参时为一个空数组
let t = 1;
for( let i = 0; i<arguments.length; i++ ){
t *= arguments[i];
console.log( t );
}
}
gg( 1,2,3,4,5);
六、return返回值
1.默认
一个函数执行完之后,默认的返回值是undefined
2.return
function hh( x , y ){
let z = x + y;
return z;//返回的是一个数据
}
let s = hh(4,5);
console.log( "hh的返回值",s );//9
七、应用及不定参注释写法
//传入数字,得到这些数字的和
/*
* @params => 参数
* 告诉使用这个函数的人,应该要传入什么实参
* @return => 返回
* 告诉使用这个函数的人,我会返回什么数据
* */
/*
* @params
* 传入一个或多个数字
* number,number,number,...
* @return
* 返回参数的总和
* number
* */
function all(){
let result = 0;
for( i = 0; i < arguments.length; i++ ){
result += arguments[i];
}
return result;
}
let q = all( 1,2,3,4 );
let w = all( 1,2 );
console.log( q );//10
console.log( w );//3
八、提问
let wrap = document.getElementById("wrap");
//返回的是节点对象
九、笔记源代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="keywords" content="">
<meta name="description" content="">
<title></title>
</head>
<body>
<script>
//声明一个函数
/*************************************************************/
//有名函数
function foo(){
//即将执行的代码
console.log( "小郭" );
}
//主动在合适的位置加()执行
foo();
//充当事件函数,事件触发时才执行,不能加()
document.onclick = foo;
/*************************************************************/
//匿名函数 => 没有名字的函数
//没有参与任何表达式的匿名函数是错误的
/*function (){
console.log( "小张" );
}*/
document.onmouseenter = function(){
console.log( "小张" );
};
document.onmouseleave = function foo_b(){//参与表达式的函数没必要加名字
console.log( "123" );
};
//foo_b();//被赋值的函数不可以主动调用,会报错
/*************************************************************/
//作用域 => 当前的变量起作用的范围
//全局变量 => 全局作用域 => 直接写在script标签第一层的变量
let a = 10;
//局部作用域 => 函数能产生局部作用域
function foo_x(){
let b = 20;
console.log( a );//局部作用域可以找全局 => 10
}
foo_x();
//console.log( b );//报错 => 局部作用域的东西不能被外层使用
//局部变量名可以和全局一样,没有冲突
//取c的值
let c = 10;
function foo_d(){
let c = 20;
console.log( c );//20 => 就近原则
}
foo_d();
//给d赋值
let d = 10;
function foo_e(){
let d = 20;
d = 30;
}
foo_e();
console.log( d );//10 => 就近原则
let e = 10;
function foo_f(){
e = 30;
}
foo_f();
console.log( e );//30
/*************************************************************/
//函数嵌套作用域
//作用域链 => 在某一个作用域使用变量时,先从自身的作用域找起,自身作用域有用自身的,自身作用域没有用上一层作用域的,上一层没有再用上一层的上一层的,直到全局作用域为止,找不到报错
//全局作用域 => GO => Global Object
//局部作用域 => AO => Activation Object
let f = 10;
function foo_g(){
let f = 20;
function foo_h(){
console.log( f );//20
}
foo_h();
}
foo_g();
/*************************************************************/
//函数声明和函数表达式 区别
//函数声明 => 允许提前调用,不报错
aa();
function aa(){
console.log( "aa函数" );
}
//函数表达式 => 通过 var let const定义的函数,不允许提前调用,会报错
//bb();//报错
let bb = function(){
console.log( "bb函数" );
};
bb();
//函数声明 立即执行
function cc(){
console.log( "cc函数执行了" );
}//() <= 在这里加括号执行会报错
cc();
//函数表达式,可以加()自执行
let dd = function(){
console.log( "dd函数执行了" );
}();
//还有哪些写法能把函数变成函数表达式?
//函数表达式自执行 => IIFE
(function ee(){
console.log( "111" );
})();//把函数用()括起来,再加上括号就可以自执行了 => 把功能模块化,产生自己的作用域,在不同模块可以使用相同变量名
!function(){
console.log( "222" );
}();
+function(){
console.log( "333" );
}();
-function(){
console.log( "444" );
}();
~function(){
console.log( "555" );
}();
/*************************************************************/
/*
* 参数
* 形参 => 定义函数的时候规定好的变量名,作用域于函数内部
* 实参 => 调用函数的时候传入的实际数据
* 不定参 => arguments
* */
//声明函数的时候,定义好形参 => 变量名 => 在当前的局部作用域
function ff( a , b ){
alert( a+b );
}
//函数调用的时候传 => 实参
ff( 2 , 4 );
ff( 2 , 40);
//实参个数不确定时,形参无法预设好一一对应的变量
function gg(){
console.log( arguments );//可以通过访问arguments的方式来找到所有的实参 => 所有实参的集合 => 没有实参时为一个空数组
let t = 1;
for( let i = 0; i<arguments.length; i++ ){
t *= arguments[i];
console.log( t );
}
}
gg( 1,2,3,4,5);
/*************************************************************/
//return => 返回值
//一个函数执行完之后,默认的返回值是undefined
function hh( x , y ){
let z = x + y;
return z;//返回的是一个数据
}
let s = hh(4,5);
console.log( "hh的返回值",s );//9
//传入数字,得到这些数字的和
/*
* @params => 参数
* 告诉使用这个函数的人,应该要传入什么实参
* @return => 返回
* 告诉使用这个函数的人,我会返回什么数据
* */
/*
* @params
* 传入一个或多个数字
* number,number,number,...
* @return
* 返回参数的总和
* number
* */
function all(){
let result = 0;
for( i = 0; i < arguments.length; i++ ){
result += arguments[i];
}
return result;
}
let q = all( 1,2,3,4 );
let w = all( 1,2 );
console.log( q );//10
console.log( w );//3
let wrap = document.getElementById("wrap");//返回的是节点对象
</script>
</body>
</html>