14 (H5*) JS第4天 函数、作用域、预解析
目录
1:函数的其他定义
2:函数作为参数
3:函数作为返回值
4:作用域
5:作用域链
6:预解析
7:预解析分段
复习
<script> /* * 复习: * 函数:把一些重复的代码封装在一个地方,在需要的时候直接调用这个地方的代码就可以了 * * 函数作用:代码重用 * * 函数的参数: * 1.形参:函数定义的时候,函数名字后面的小括号里的变量 * 2.实参:函数调用的时候,函数名字后面的小括号里的变量或者值 * * 返回值: * 函数中有return,函数有返回值 * 函数中没有return,函数没有返回值 * 没有明确返回值:函数中没有return或者return后面没有任何内容 * 如果一个函数没有明确的返回值,接收这个函数,结果是undefined * * 无参数无返回值的函数 * 无参数有返回值的函数 * 有参数无返回值的函数 * 有参数有返回值的函数 * * arguments----->可以获取函数调用的时候,传入的实参的个数 * arguments是一个对象,是一个伪数组 * arguments.length--->是实参的个数 * arguments[索引]---->实参的值 * * 作用域:变量的使用范围 * 全局作用域:全局变量在任何位置都可以使用的范围 * 局部作用域:局部变量只能在某个地方使用---函数内 * 作用域链:在一个函数中使用一个变量,先在该函数中搜索这个变量,找到了则使用,找不到则继续向外面找这个变量,找到则使用,一直找到全局作用域,找不到则是undefined * 全局变量:只要是在函数外面声明的变量都可以看成或者是理解成是全局变量 * 局部变量:在函数中定义的变量 * * 预解析:在执行代码之前做的事情 * 变量的声明和函数的声明被提前了,变量和函数的声明会提升到当前所在的作用域的最上面 * 函数中的变量声明,会提升到该函数的作用域的最上面(里面) * 如果有多对的script标签都有相同名字的函数,预解析的时候是分段的,互不影响 * * */ </script>
内容
1:函数的其他定义
<script> /* * 命名函数:函数如果有名字,就是命名函数 * * 匿名函数:函数如果没有名字,就是匿名函数 * * 函数的另一种定义方式 * 函数表达式: * 把一个函数给一个变量,此时形成了函数表达式 * var 变量=匿名函数; * 例子: * var f1=function (){ * * }; * 如果是函数表达式,那么此时前面的变量中存储的就是一个函数,而这个变量就相当于是一个函数,就可以直接加小括号调用了 * f1(); * * 注意: * 函数表达式后面,赋值结束后,要加分号 * * * * 函数定义: * 1. 函数声明--函数定义 * function 函数名(){ * 函数体 * } * * */ // var f1=function(){console.log("阿涅哈斯诶呦");}; // f1(); //函数的自调用,没有名字,调用---声明的同时,直接调用 //一次性的-------- // (function(){console.log("阿涅哈斯诶呦");})(); // (function(){console.log("嘎嘎")})(); // // function f1() { // console.log("哈哈,我又变帅了"); // } // f1();//函数调用 // //如果一个函数能够调用: 函数的代码(); // // //函数表达式 // var f2 = function () { // console.log("哈哈,真的好帅哦"); // }; // //匿名函数不能直接调用 // f2(); // // // var f4 = function () { // console.log("我是一个函数"); // }; // f4(); // // // // var num=10; //函数声明 function f1() { console.log("助教好帅哦"); } f1(); function f1() { console.log("小苏好猥琐哦"); } f1(); //函数表达式 var f2 = function () { console.log("助教没有小杨帅"); }; f2(); f2 = function () { console.log("小杨真的很帅"); }; f2(); //函数自调用 (function () { console.log("阿涅哈斯诶呦"); })(); (function () { console.log("嘎嘎") })(); // var num=10; // console.log(num); // num=100; // console.log(num); </script>
2:函数作为参数
<script> //函数可以作为参数使用,如果一个函数作为参数,那么我们说这个参数(函数)可以叫回调函数 //只要是看到一个函数作为参数使用了,那就是回调函数 function sayHi(fn) { console.log("您好啊"); fn();//fn此时应该是一个函数 } function suSay() { console.log("我猥琐,我邪恶,我龌龊,小苏说"); } sayHi(suSay); // function f1(x,y) { // console.log(x+y); // } // f1(10,20); // // function f2(x,y) { // console.log(x+y); // } // f2("小苏","猥琐"); // function f3(x) { // console.log(x); // } // f3(true); //函数声明,fn是变量,fn是参数, // function f1(fn) { // fn();//函数调用---说明fn这个变量中存储的是一个函数 // } // // function f2() { // console.log("哦,这也可以"); // } // f1(f2); // var f1=function () { // console.log("哈哈"); // }; </script>
3:函数作为返回值
<script> //结论:函数是可以作为返回值使用的: function f1() { console.log("f1函数调用了"); return function () { console.log("这是一个函数"); }; } var ff=f1();//调用 //ff就是一个函数了 ff(); </script>
4:作用域
<script> //作用域:使用范围 /* * * 全局变量:声明的变量是使用var声明的,那么这个变量就是全局变量,全局变量可以在页面的任何位置使用 * 除了函数以外,其他的任何位置定义的变量都是全局变量 * 局部变量:在函数内部定义的变量,是局部变量,外面不能使用 * 全局变量,如果页面不关闭,那么就不会释放,就会占空间,消耗内存 * * 全局作用域:全局变量的使用范围 * 局部作用域:局部变量的使用范围 * * 块级作用域:一对大括号就可以看成是一块,在这块区域中定义的变量,只能在这个区域中使用,但是在js中在这个块级作用域中定义的变量,外面也能使用; * 说明:js没有块级作用域,只有函数除外 * * 隐式全局变量:声明的变量没有var,就叫隐式全局变量 * 全局变量是不能被删除的,隐式全局变量是可以被删除的 * 定义变量使用var是不会被删除的,没有var是可以删除的 * * * */ // function f1() { // number=1000;//是隐式全局变量 // } // f1(); // console.log(number); // var num1=10; // num2=20; // delete num1;//把num1删除了 // delete num2;//把num2删除了 // console.log(typeof num1); // console.log(num1+10); // console.log(typeof num2); // num=100; // console.log(num); //扩展:隐式 // function f1() { // var num=100; // num+=10; // } // f1();//这个函数结束之后 // { // var num=10; // console.log(num);//10 // } // console.log(num); // if(true){ // var num=10; // } // console.log(num); // for(var i=0;i<5;i++){ // var number=20; // } // console.log(number); // var i=0; // while (i<5){ // var num=100; // i++; // } // console.log(num); // function f1() { // var num=10; // } // f1(); // console.log(num); // var num=10; // console.log(num);//10 </script>
5:作用域链
<script> var num=10; function f1() { var num=20; function f2() { var num=30; function f3() { var num=50; console.log(num); } f3(); } f2(); } f1(); </script>
6:预解析
<script> //预解析:提前解析代码 /* * * 预解析:就是在解析代码之前 * 预解析做什么事? * 把变量的声明提前了----提前到当前所在的作用域的最上面 * 函数的声明也会被提前---提前到当前所在的作用域的最上面 * * * */ //函数调用的时候,把会函数的声明提升到作用域的上面 // f1();//调用 // var num=20;//这个变量的声明会提升到变量使用之前 // function f1() { // console.log(num); // //var num=10; // } // function f1() { // console.log("小苏好猥琐"); // } // // // f1(); // function f1() { // console.log("小苏没有助教猥琐"); // } // f1(); //把变量的声明提前了 // var num; // console.log(num); // num=10; // function f1() { // console.log("哈哈,助教好猥琐哦"); // } //f1();//报错 </script>
7: 预解析分段
<script> //预解析中,变量的提升,只会在当前的作用域中提升,提前到当前的作用域的最上面 //函数中的变量只会提前到函数的作用域中的最前面,不会出去 //预解析会分段(多对的script标签中函数重名,预解析的时候不会冲突) // function f1() { // // console.log(num);//undefined // var num=10; // } // f1(); // console.log(num);// function f1() { console.log("哈哈"); } </script>
注意