为什么要使用函数
用函数来解决代码重用的问题。
函数的意义
函数其实就是封装,把可以重复使用的代码放到函数中,如果需要多次使用同一段代码,就可以把封装成一个函数。这样的话,在你需要再次写这些代码的时候,你只需要调用一次函数就行了。
定义函数的方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 1.字面量法
// function 函数名(传递的参数){
// 函数体,执行的代码
// }
function fun1(){
console.log("函数fun1");
}
// 调用函数
fun1();
// 函数传递参数
function sumFun(a,b){ // 形参 形式参数
var sum = a + b;
console.log(sum);
}
sumFun(1,2); // 实参 实际参数
// 2.匿名函数
var fun2 = function (){
console.log("匿名函数");
}
fun2();
// 3.构造函数
var fun3 = new Function("a","b","console.log(a+b);console.log('123')")
fun3(1,2);
// 4.自执行函数
(function (){
console.log("abc");
})()
</script>
</body>
</html>
函数的返回值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function fun(num1, num2) {
var sum = num1 + num2;
// 返回值
return sum;
console.log("已返回");
}
// 调用函数
fun(1,2);
var sum2 = fun(1,2);
console.log(sum2);
// 函数最终返回什么,函数本身就代表什么
// return之后,后面的代码将不再被执行
</script>
</body>
</html>
arguments对象
arguments 是一个对应于传递给函数的参数的类数组对象。
可以使用arguments
对象在函数中引用函数的参数。此对象包含传递给函数的每个参数,第一个参数在索引 0 处
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function fun(a,b,c){
// arguments对象 伪数组(假的数组,可以使用数组的某些属性,但是不能使用数组的操作方法)
// 包含了传递的参数 组成数组形式
console.log(arguments);
console.log(arguments.length);
console.log(arguments[0]);
console.log(arguments[1]);
console.log(arguments[2]);
// arguments.push(4);
}
// fun(1,2,3);
function fun2(){
console.log(arguments);
var sum=0;
for(var i=0;i<arguments.length;i++){
sum+=arguments[i]
}
return sum;
}
console.log(fun2(1,2,3,4,5,6));
</script>
</body>
</html>
函数是一种数据类型
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function fun() {
console.log("函数function");
}
console.log(typeof fun); // function
// 函数也可以作为参数进行传递
function fun2(f){
f();
console.log("自己的打印");
}
fun2(fun);
// typeof返回值 undefined boolean string number object function
</script>
</body>
</html>
作用域
作用域:指一个变量的作用范围。
目前的学习中,在Javascript将作用域分为 全局作用域 和 函数作用域(局部作用域)。
全局作用域
代码在程序的任何地方都能被访问,window 对象的内置属性都拥有全局作用域。
函数作用域(局部作用域)
在固定的代码片段才能被访问
全局变量和局部变量
-
全局变量:
在最外层声明的变量叫全局变量。
在函数体内部,没有使用var关键字声明的变量也是全局变量。(不推荐)
-
局部变量:
在函数体内部,使用var关键字声明的变量叫作局部变量。
作用域规则
-
函数允许访问函数外的数据。
-
整个代码结构中只有函数可以限定作用域。
-
作用域规则首先使用提升规则分析。
-
如果当前作用规则中有名字了, 就不考虑外面的名字。
作用域链
-
只有函数可以制造作用域结构, 那么只要是代码,就至少有一个作用域, 即全局作用域。凡是代码中有函数,那么这个函数就构成另一个作用域。如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域。
-
将这样的所有的作用域列出来,可以有一个结构:在当前作用域中没有查到值,就会向上级作用域去查,直到查到全局作用域,这么一个查找过程形成的链条就叫做作用域链。
-
作用域链:采取就近原则的方式来查找变量最终的值。
面试题
什么是作用域和作用域链,请解释一下?
作用域(scope)
在 Javascript 中,作用域分为 全局作用域 和 局部作用域
全局作用域:代码在程序的任何地方都能被访问,window 对象的内置属性都拥有全局作用域。
局部作用域:在固定的代码片段才能被访问。
作用域链(scope chain)
在当前作用域中没有查到值,就会向上级作用域去查,直到查到全局作用域,这么一个查找过程形成的链条就叫做作用域链。
函数的预解析
函数提升: 函数的声明会被提升到当前作用域的最上面,函数声明代表函数整体,所以函数提升后,函数名代表整个函数。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 变量的预解析
console.log(num);
var num;
num=10;
// 调用函数
fun();
fun2(); // fun2 is not a function
// 函数的预解析
// 字面量方式
function fun(){
console.log("唧唧复唧唧");
}
// 匿名函数
var fun2 = function (){
console.log("木兰当户织");
}
</script>
</body>
</html>