一、函数的声明和函数的表达式
(1)函数的声明:通过function来声明一个函数叫作函数的声明。(有名函数)
function fn(){
//...code
}
fn();
- 此为函数的声明,声明的后面不需要加分号,函数在声明的时候并没有执行。只是把自己的内部作为一块存了起来,当我们调用的时候执行。
- 函数的执行,采用函数名加()表示执行,执行不分场合,只要是函数名加()就表示函数的执行。
- 函数的声明不是一条语句,后边不能加(),不能使用
function fn(){}();
- 匿名函数:不能莫名奇妙的出现,除非是在赋值、传参的场景下出现。否则会报错。
(2)函数的表达式:通过var来定义一个匿名函数。(匿名函数)
var fn = function(){//把函数作为值传递
//...code
};
fn();
- 此为把一个函数作为值来进行传递,此时需要加分号,因为这是一个语句。
- 函数想要执行,也是用变量名加()。
- 函数表达式可以在末尾加()去执行,即可以使用
var fn = function(){}();
- 把函数的声明转换成为函数表达式,将函数的声明用()包起来,
(function(){alert(1);})();
(3)函数声明与函数表达式的区别:函数声明可以提前解析,函数表达式不可以提前解析,要先定义后执行。
fn1();//正常
function fn1(){
console.log(1);
}
fn2();//报错,fn2此时是undefined,undefined后不能加()
var fn2 = function(){
console.log(1);
}
(4)匿名函数立即执行(IIFE)
- 节省变量
- 私有属性的问题
(function(){
alert(1);
})();
!function(){
alert(1);
}();
+function(){
alert(1);
}();
~function(){
alert(1);
}();
(function(){
alert(1);
}());
二、函数的作用
- 代码的重复使用(复用)。
- 独立代码块,不影响其他变量(作用域)
var a = 123;
function fn(){
var a = 456;//如果没有变量声明,会去函数外面找,但是函数外面不能影响函数内部的变量声明,函数内部的变量声明也不去影响外面
console.log(a);
}
fn();
console.log(a);
三、参数传递
- 函数声明的时候,默认给形参undefined。
- 函数形参个数如果小于实参个数,那多余的实参会被忽略。
- 函数形参个数如果大于实参个数,那多余的形参默认是undefined。
- 函数没有重载,如果声明两次同名函数,后声明的函数会覆盖前面声明的函数。
function fn(a, b){//小括号里面可以放东西,我们称之为形参,可以看做var a;
console.log(a + b);
}
fn(2, 3);//5 实参传递数据给形参赋值,形参和实参一一对应
fn("2");//2undefined 没有给形参传递实参的形参默认是undefined
fn(1, 2, 3);//3 最后的3被自动忽略
四、arguments
- arguments是一个类数组,它仅仅只存在于函数当中,用于保存所有的实参。
- arguments.callee指的是当前函数本身。
- arguments.length指的是实参的个数。
function add(){
var length = arguments.length;
var sum = 0;
for(var i = 0; i < length; i++){
sum += arguments[i];
}
console.log(sum);
console.log(arguments.callee);
}
add(1, 2, 3, 4, 5);
五、函数的返回值
- 凡是运算都有返回值,函数的执行也是一种运算,也应该有返回值。默认情况下,函数运算的返回值就是undefined。
- 用return改变返回值,return的值就是函数运行的返回值。
- 除了能够确定函数的返回值以外,还能阻断函数的执行。
- return只能在函数中使用,是跳出函数,break是for循环跳出。
function fn(){
return 10;//跳出函数
console.log(1);//永远不能执行
}
console.log( fn() );
//体会下面两个函数的区别:
var i = 0;
function fn1(){
for(; i < 100; i++){
if( i === 50 ){
break;
}
}
i++;
}
fn();
console.log(i);
var i = 0;
function fn2(){
for(; i < 100; i++){
if( i === 50 ){
return;
}
}
i++;
}
fn();
console.log(i);
六、函数的自执行与他执行
- 自执行:函数名加括号。
- 他执行:必须被其他东西来触发,比如触发事件。
//函数自执行
function fn(){
console.log(1);
}
fn();
//函数他执行
var oBox = document.getElementById("box");
oBox.onclick = function(){
console.log(1);
}
七、函数里的this
- 如果在script标签中直接打印this,this指向window对象,window是script标签中最顶层的对象。
- 函数如果是被调用,那么this指向调用对象。
console.log(this);//window
function fn(){
console.log(this);
}
fn();//window,因为是window调用的fn,其实是window.fn();
var oBox = document.getElementById("box");
oBox.onclick = function(){
console.log(this);//指向oBox对象
}
八、函数的综合运用
function fn(x){
console.log(x);
}
document.onclick = function(){
fn(2);
};//正确调用
document.onclick = fn(2);//错误调用,会直接执行fn(2);因为函数名加括号就表示执行。
//把函数当做参数传递
function x(y){//相当于var y;
y(10);
}
x(
function(a){//y = function(a){console.log(a)}
console.log(a);
}
)
//赋值操作的返回值是等号右边的数据
var x;
(x = function(){console.log(1)})();
console.log(x);
var a;
console.log(a = 100);
document.onclick = fn();
function fn(){
return function(){
console.log(1);
}
}
//写一个函数,传入数值,返回1一直加到该数字的值
var sum = (function(num){
if( num > 1 ){
return num + arguments.callee(num-1);
}else{
return num;
}
})(100);
console.log(sum);
//递归,自身调用自身,尽量不要去用。
网友评论