|
主题设置

卡片式面板通常用于非白色背景色的主体内

JS 函数

函数把一些重复的代码封装在一起,在需要的时候直接调用。

函数的参数

  • 形参:函数定义的时候,函数名字后面的小括号里的变量。
  • 实参:函数调用的时候,函数名字后面的小括号里的变量或者值。
  • 形参和实参的个数:调用函数时,实参的个数可以比形参多,函数最终会按照形参的个数取用传入的实参。

返回值

  • 函数中有 return,函数有返回值。
  • 函数中没有 return,函数没有返回值。
  • 没有明确返回值:函数中没有 return,或者 return 后面没有任何内容。
  • 如果一个函数没有明确的返回值,接受这个函数时,结果就是 undefined 。

作用域

  • 全局作用域:全局变量在任何位置都可以使用的范围。
  • 局部作用域:局部变量只能在某个地方使用,比如函数内。
  • 作用域链:在一个函数中使用一个变量,先在该函数中搜索这个变量,找到了则使用,找不到则继续向外面找这个变量,找到了则使用,一直找到全局作用域,找不到则是 undefined 。
  • 全局变量:只要是在函数外面声明的变量都可以看成或者是理解成是全局变量。
  • 局部变量:只有在函数中定义的变量才是局部变量。其他所有的,比如在非函数的大括号中定义的变量,不是局部变量,在大括号外也能调用。
全局变量(在函数外用 var 声明的)是不能被删除的,但是隐式全局变量(不用 var 声明的)是可以被删除的(用 delete 直接删除)。

函数的使用

// 静态函数
// 声明
function getSum1(){
    var num1 = 10;
    var num2 = 20;
    var sum = num1 + num2;
    console.log(sum);
}
// 调用 1
getSum1();
// 调用 2,得到 undefined
var result = getSum1();	// 如果一个函数没有返回值,但是用变量接收了,则变量值是 undefined


// 有参数的函数
function getSum2(num1,num2){
    var sum = num1 + num2;
    console.log(sum);
    return arguments.length;	// 返回接收到的参数的个数
}
// 调用 1
getSum2(40,50);
// 调用 2
getSum2(40,50,60,70);	// 实参的个数可以和形参不一样,最后以前两个实参做计算


// 有返回值的函数
function getSum3(num1,num2){
    var sum = num1 + num2;
    return sum;
}
var result = getSum3(50,50);
console.log(result);


// 匿名函数(把一个函数给一个变量,叫函数表达式,后面 function 开始的部分叫匿名函数)
var sayHi = function(){	// 因为是匿名函数,所以需要定义一个变量来接收函数值
    console.log("hello world!");
};	// 函数表达式赋值以后(即给 sayHi 赋值),必须加分号,否则会出现未知的错误
sayHi();	// 调用匿名函数


// 有隐式全局变量的函数
function variable(){
    dog = "小狗";	// 变量前面没有 var,就是隐式全局变量
    console.log(dog);
}
variable();


// 函数的预解析 1
// 将函数调用,放在函数声明前面,仍能正常执行,这就叫函数的预解析(会将函数提前到当前作用域的最上面)
pre();
function pre(){
    console.log("我是预解析函数!");
}


// 函数的预解析 2(里面存在变量的预解析)
// 这里利用函数的预解析调用 f1 函数,最终输出的是 undefined 。
// 因为输出 num 时,会先在函数 f1 里寻找 num ,这时候会将下面的'var num' 提前,但是并不会赋值,所以是先输出 undefined ,输出后 num 被赋值为 10 。
f1();
var num = 20;
function f1(){
    console.log(num);
    var num = 10;
}


// 函数的预解析 3
// 这里调用 f1 会报错(Uncaught TypeError: f1 is not a function),因为此时 f1 不是函数,里面存储的是表达式的返回值 undefined 。
f1();	
var f1 = function(){
    console.log(a);
    var a = 10;
}


// 函数的自调用(声明的同时直接调用)
// 一次性的
(function(){console.log("我是函数自调用!");})();


// 函数可以作为参数被调用
// 声明函数 f1
f1(fn){
    fn();	// 这行是执行 fn 函数
}
// 声明函数 f2
f2(){
    console.log("我是函数!");
}
// 调用
f1(f2);	// 将函数 f2 传入函数 f1


// 函数作为返回值使用
function f1(){
    return function(){
    	console.log("我是函数,作为返回值返回!");
    }
}


// 函数的嵌套(函数的作用域链)
var num = 10;	// 函数外面是 0 级作用域
function f1(){	// f1 里面是 1 级作用域
    var num = 20;
    function f2(){	// f2 里面是 2 级作用域
    	var num = 30;
    	function f3(){	// f3 里面是 3 级作用域
    		var num = 50;
    		console.log(num);
    	}
    	f3();	// f2 里面调用 f3
    }
    f2();	// f1 里面调用 f2
}
// 调用 f1,最后输出 num 的值为 50:因为输出 num 时,首先会在 console.log 当前的作用域找,找不到才会往上找。
f1();


// 函数的方法
// 1
function nums(){
    console.log(arguments);		// 输出传入的所有参数
    console.log(arguments[0]);	// 输出第一个参数
    console.log(arguments.length);	// arguments.length,获取函数一共传入了几个参数
}
nums(10,20,30,40,50,60);	// 输出:所有参数、第一个参数、参数个数(6)


// 2
console.log(typeof nums);	// 输出 function,函数是有数据类型的,数据类型是 function 。

有用的提示

  • 函数的名字(后面不跟括号)直接输出,就是函数代码。
  • 函数表达式(即匿名函数)赋值结束后,必须要加分号,否则会出现未知的错误。