SEO外包-2222222222-2222222222 JavaScript-8函数、2222222222

SEO外包

当前位置:SEO外包>SEO资讯>

2222222222 JavaScript-8函数

发布时间:2021-05-17 11:58   来源:网络 关键词:2222222222

2222222222

函数
  1. 什么是函数?
    函数是专门用于封装代码的, 函数是一段可以随时被反复执行的代码块
  2. 函数格式
function 函数名称(形参列表){      被封装的代码;}
  1. 不使用函数的弊端
  • 冗余代码太多
  • 需求变更, 需要修改很多的代码
  1. 使用函数的好处
  • 冗余代码变少了
  • 需求变更, 需要修改的代码变少了
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title></title>    <script>        // 定义向左变道的函数        function toLeft(){            console.log("打左转向灯");        }        // 定义向右变道的函数        function toRight(){            console.log("打右转向灯");        }        // 向左变道        // 以下代码的含义: 找到名称叫做toLeft的函数, 执行这个函数中封装的代码        toLeft();        // 向右变道        toRight();        // 向左变道        toLeft();    </script></head><body></body></html>
函数的定义方式
  1. 书写函数的固定格式
function 函数名称(形参列表){     被封装的代码;}
  1. 给函数起一个有意义的名称
  • 函数名称也是标识符的一种, 所以也需要遵守标识符的命名规则和规范
  • 为了提升代码的阅读性
  1. 确定函数的形参列表
  • 看看使用函数的时候是否需要传入一些辅助的数据
  1. 将需要封装的代码拷贝到{}中

  2. 确定函数的返回值

  • 可以通过return 数据; 的格式, 将函数中的计算结果返回给函数的调用者
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title></title>    <script>        function getSum(a, b) { // a = num1, b = num2;            let res = a + b; // let res = 10 + 20; let res = 30;            // 将res返回给函数的调用者            return res;        }        /*        // 需求: 要求计算两个变量的和        let num1 = 10;        let num2 = 20;        let res = num1 + num2;        console.log(res);        let value1 = 30;        let value2 = 20;        let res2 = value1 +value2;        console.log(res2);        */        let num1 = 10;        let num2 = 20;        let result = getSum(num1, num2); // let result = res; let result = 30;        console.log(result);    </script></head><body></body></html>

函数注意点

  1. 一个函数可以有形参也可以没有形参(零个或多个)
  • 什么是形参? 定义函数时函数()中的变量我们就称之为形参
name就是形参function say(name) {    console.log("hello " + name);}//无参函数function say() {    console.log("hello ");}
  1. 一个函数可以有返回值也可以没有返回值
 // 没有返回值的函数function say() {  console.log("hello ");}say(); // 有返回值的函数function getSum(a, b) {    return a + b;}let res = getSum(10 , 20);console.log(res);
  1. 函数没有通过return明确返回值, 默认返回undefined
function say() {  console.log("hello ");}let res = say();console.log(res);        undefined
  1. return的作用和break相似, 所以return后面不能编写任何语句(永远执行不到)
  • break作用立即结束switch语句或者循环语句
  • return作用立即结束当前所在函数
 // 有返回值的函数function getSum(a, b) {    return a + b;  console.log("AAAA");}let res = getSum(10 , 20);console.log(res);AAAA不会输出
  1. 调用函数时实参的个数和形参的个数可以不相同
  • 什么是实参? 调用函数时传入的数据我们就称之为实参
function getSum(a, b) {    return a + b;  console.log("AAAA");}let res = getSum(10 , 20);10、20就是实参
  1. JavaScript中的函数和数组一样, 都是引用数据类型(对象类型)
  • 既然是一种数据类型, 所以也可以保存到一个变量中
  • 将一个函数保存到一个变量中
  • 将来可以通过变量名称找到函数并执行函数
 let say = function () {         console.log("hello world");}say();
函数arguments
  1. 因为console.log();也是通过()来调用的, 所以log也是一个函数
  2. log函数的特点
  • 可以接收1个或多个参数
  1. 为什么log函数可以接收1个或多个参数
  • 内部的实现原理就用到了arguments
  1. arguments的作用
  • 保存所有传递给函数的实参
  • 每个函数中都有一个叫做arguments的东东
  • arguments其实是一个伪数组
function getSum() {    // 注意点: 每个函数中都有一个叫做arguments的东东    // arguments其实是一个伪数组    let sum = 0;    for (let i = 0; i < arguments.length; i++){         let num = arguments[i];         // console.log(num); // 10 20 30         // sum = 0 + 10; sum = 10;        // sum = 10 + 20; sum = 30;       // sum = 30 + 30; sum = 60;       sum += num; // sum = sum + num;    }     return sum;   }let res = getSum(10, 20, 30, 40);console.log(res);          60function say(){//打印结果  Arguments(4) [11, 12, 13, 14, callee: ƒ, Symbol(Symbol.iterator): ƒ]    console.log(arguments);}say(11,12,13,14);
JavaScript-函数扩展运算符
  1. 扩展运算符是...
  2. 扩展运算符在等号左边, 将剩余的数据打包到一个新的数组中
  • 注意点: 只能写在最后
let [a, ...b] = [1, 3, 5]; a = 1; b = [3, 5];
  1. 扩展运算符在等号右边, 将数组中的数据解开
let arr1 = [1, 3, 5];let arr2 = [2, 4, 6];let arr = [...arr1, ...arr2]; let arr = [1, 3, 5, 2, 4, 6];
  1. 扩展运算符在函数的形参列表中的作用
  • 将传递给函数的所有实参打包到一个数组中
  • 和在等号左边一样, 也只能写在形参列表的最后
 function getSum(a, ...values) {     console.log(a);            //10     console.log(values);  //[20,30]}getSum(10, 20 , 30);
JavaScript-函数形参默认值

在ES6之前可以通过逻辑运算符来给形参指定默认值,
格式: 条件A || 条件B
如果条件A成立, 那么就返回条件A
如果条件A不成立, 无论条件B是否成立, 都会返回条件B

function getSum(a, b) {   a = a || "嗨";   b = b || "一开熏";   console.log(a, b);}getSum(123, "abc");

从ES6开始, 可以直接在形参后面通过=指定默认值

  • ES6开始的默认值还可以从其它的函数中获取
function getSum(a = "嗨", b = getDefault()) {    console.log(a, b);      //a 嗨 b是栗子}getSum();function getDefault() {    return "栗子"}
JavaScript-函数作为参数和返回值
  1. 函数作为参数
let say = function () {    console.log("hello world");}// say();  直接打印hello worldfunction test(fn) {     fn();}test(say);
  1. 函数作为返回值
function test() {   let say = function () {     console.log("hello world");  }  return say;}let fn = test(); // let fn = say;fn();
JavaScript-匿名函数
  1. 什么是匿名函数?
  • 匿名函数就是没有名称的函数
function() {    console.log("hello lnj");}
  1. 匿名函数的注意点
  • 匿名函数不能够只定义不使用
  1. 匿名函数的应用场景
  • 作为其他函数的参数
function test(fn) { // let fn = say;    fn();}test(function () {    console.log("hello world");}输出 hello world"
  • 作为其他函数的返回值
function test() {     return function () {        console.log("hello world");    }}test();输出 hello world"
  • 作为一个立即执行的函数
(function () {     console.log("hello it666");})();

如果想让匿名函数立即执行, 那么必须使用()将函数的定义包裹起来才可以

JavaScript-箭头函数
  1. 什么是箭头函数?
  • 箭头函数是ES6中新增的一种定义函数的格式
  • 就是为了简化定义函数的代码
let 函数名称 = (形参列表) =>{    需要封装的代码;}
  1. 在ES6之前如何定义函数
function 函数名称(形参列表){    需要封装的代码;}let 函数名称 = function(形参列表){     需要封装的代码;}
  1. 从ES6开始如何定义函数
let 函数名称 = (形参列表) =>{    需要封装的代码;}
  1. 箭头函数的注意点
  • 在箭头函数中如果只有一个形参, 那么()可以省略
let say = name =>{ console.log("hello  " + name);}say("it666");
  • 在箭头函数中如果{}中只有一句代码, 那么{}也可以省略
let say = name => console.log("hello  " + name);say("it666");
JavaScript-递归函数
  1. 什么是递归函数?
  • 递归函数就是在函数中自己调用自己, 我们就称之为递归函数
  • 递归函数在一定程度上可以实现循环的功能
    2.递归函数的注意点
  • 每次调用递归函数都会开辟一块新的存储空间, 所以性能不是很好
function login() {  //1. 接收用户输入的密码  let pwd = prompt("请输入密码");//2.判断密码是否正确  if(pwd !== "123456"){    login();  }  // 3.输出欢迎回来  alert("欢迎回来");}login();   

逻辑说明

上面代码输入2次错误的,输入1次正确的,最后会弹出3次alert

上面执行代码,会开辟一块内存(地址1),你第一次输入123,之后,会重新输入值,这时候代码进入判断,重新开辟一块内存(地址2),这块内存里是login函数的所有代码,这时候重新走一遍函数,当你输入321的时候,又会进入判断,重新开辟一块内存(地址3),这块内存里是login函数的所有代码,这时候你输入123456,判断通过,弹出alert,点击alert上面的确认按钮之后,会走完这个函数,这个函数走完,地址3就结束任务了,这时候内存回到地址2,地址2里面判断也走完了,这时候弹出alert,点击alert上面的确认按钮之后,会走完这个函数,这个函数走完,地址2结束任务了,这时候内存回到地址1,这时候,接着弹出alert,点击alert上面的确认按钮之后,地址1的函数也就走完了。

JavaScript-变量作用域
  1. 在JavaScript中定义变量有两种方式
  • ES6之前: var 变量名称;
  • ES6开始: let 变量名称;
  1. 两种定义变量方式的区别
    2.1 是否能够定义同名变量
  • 通过var定义变量,可以重复定义同名的变量,并且后定义的会覆盖先定义的
var num = 123;var num = 456;console.log(num);    //456

2.2 如果通过let定义变量, "相同作用域内"不可以重复定义同名的变量

let num = 123;let num = 456; // 报错

2.2 是否能够先使用后定义

  • 通过var定义变量, 可以先使用后定义(预解析)
console.log(num);var num = 123;
  • 通过let定义变量, 不可以先使用再定义(不会预解析)
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>Document</title></head><script>    {        let num = 678  //全局变量    }    console.log(num);    报错</script><body></body></html>

2.3 是否能被{}限制作用域

  • 无论是var还是let定义在{}外面都是全局变量
var num = 123;let num = 123;
  • 将var定义的变量放到一个单独的{}里面, 还是一个全局变量
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>Document</title></head><script>    {        var num = 123    }    console.log(num);    123    </script><body>    </body></html>
  • 将let定义的变量放到一个单独的{}里面, 是一个局部变量
{  let num = 123;}console.log(num);  //会报错

1.在JavaScript中{}外面的作用域, 我们称之为全局作用域
2.在JavaScript中函数后面{}中的的作用域, 我们称之为"局部作用域"
3.在ES6中只要{}没有和函数结合在一起, 那么应该"块级作用域"
4.块级作用域和局部作用域区别
4.1在块级作用域中通过var定义的变量是全局变量
4.2在局部作用域中通过var定义的变量是局部变量

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>Document</title></head><script>    {        var num = 123    }    console.log(num);        function age(){        var value = 666    }    console.log(value);     //报错</script><body>    </body></html>

5.无论是在块级作用域还是在局部作用域, 省略变量前面的let或者var就会变成一个全局变量

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>Document</title></head><script>    {        num = 678  //全局变量    }    console.log(num);    //678</script><body></body></html>
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>Document</title></head><script>   function test() {      var  num = 678  //局部变量      //let   num = 678  //局部变量    }    console.log(num); 报错,外部访问不到 无论是let还是var</script><body></body></html>
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>Document</title></head><script>   function test() {        num = 678  //全局变量    }    test();     //得调用下函数    console.log(num);    输出678</script><body></body></html>
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>Document</title>    <script>        {            //块级元素        }        for(){         //块级元素      }      switch(){  //块级元素 }      function haha(){            //局部作用域      }      </script></head><body>    </body></html>
  1. 在不同的作用域范围内, 是可以出现同名的变量的
  • {}没有和函数结合起来的,都是块级作用域
  • 和函数结合的,是局部作用域
  1. 只要出现了let, 在相同的作用域内, 就不能出现同名的变量
let num = 123;var num = 456; // 会报错

上面练习

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>练习</title>    <script>        // 1.找出下列哪些是全局变量,哪些是局部变量        /*        var num1 = 123; // 全局变量        function test() {            var num2 = 456; // 局部变量        }        {            var num3 = 789; // 全局变量        }        function test() {            num4 = 666; // 全局变量        }        */        // 2.找出下列哪些是全局变量,哪些是局部变量        /*        let num1 = 123; // 全局变量        function test() {            let num2 = 456; // 局部变量        }        {            let num3 = 789; // 局部变量        }        function test() {            num4 = 666; // 全局变量        }        */        // 3.下列代码运行是否会报错        /*        var num = 123;        var num = 456; // 不会报错        */        /*        {           var num = 123;            {                var num = 456; // 不会报错            }        }        */        /*        console.log(num); // 不会报错        var num = 123;        */        // 4.下列代码运行是否会报错        /*        let num = 123;        let num = 456; // 会报错        */        /*        {           let num = 123;            {            // 注意点: 在不同的作用域范围内, 是可以出现同名的变量的                let num = 456; // 不会报错            }        }        */        /*        console.log(num); // 会报错        let num = 123;        */        // 5.下列代码运行是否会报错        /*        // 注意点: 只要出现了let, 在相同的作用域内, 就不能出现同名的变量        let num = 123;        var num = 456; // 会报错        */        /*        var num = 123;        let num = 456; // 会报错        */    </script></head><body></body></html>
JavaScript-作用域链

初学者在研究作用域的时候最好将ES6之前和ES6分开研究

  1. 需要明确:
    1.1 ES6之前定义变量通过var
    1.2 ES6之前没有块级作用域, 只有全局作用域和局部作用域
    1.3 ES6之前函数大括号外的都是全局作用域
    1.4 ES6之前函数大括号中的都是局部作用域
  2. ES6之前作用域链
    2.1 全局作用域我们又称之为0级作用域
    2.2 定义函数开启的作用域就是1级/2级/3级/...作用域
    2.3 JavaScript会将这些作用域链接在一起形成一个链条, 这个链条就是作用域链
 0  --->  1 ---->  2  ---->  3 ----> 4

2.4 除0级作用域以外, 当前作用域级别等于上一级+1

  1. 变量在作用域链查找规则
    3.1 先在当前找, 找到就使用当前作用域找到的
    3.2 如果当前作用域中没有找到, 就去上一级作用域中查找
    3.3 以此类推直到0级为止, 如果0级作用域还没找到, 就报错
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>83-JavaScript-作用域链上</title>    <script>        // 全局作用域 / 0级作用域       var num = 123;        function demo() {            // 1级作用域            var num = 456;            function test() {                // 2级作用域               var num = 789;                console.log(num);            }            test();        }        demo();    </script></head><body></body></html>

把上面的num一级一级注释掉,看打印结果,在2级作用域,打印789,把2级num注释掉,打印是1级的,打印值456,把1级的注释掉,打印的是123,把123的num注释掉,打印报错

JavaScript-作用域链2
  1. 需要明确:
  • ES6定义变量通过let
  • ES6除了全局作用域、局部作用域以外, 还新增了块级作用域
  • ES6虽然新增了块级作用域, 但是通过let定义变量并无差异(都是局部变量)
  1. ES6作用域链
  • 全局作用域我们又称之为0级作用域
  • 定义函数或者代码块都会开启的作用域就是1级/2级/3级/...作用域
  • JavaScript会将这些作用域链接在一起形成一个链条, 这个链条就是作用域链
0  --->  1 ---->  2  ---->  3 ----> 4
  • 除0级作用域以外, 当前作用域级别等于上一级+1
  1. 变量在作用域链查找规则
  • 先在当前找, 找到就使用当前作用域找到的
  • 如果当前作用域中没有找到, 就去上一级作用域中查找
  • 以此类推直到0级为止, 如果0级作用域还没找到, 就报错
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title></title>    <script>        // 全局作用域 / 0级作用域         let num = 123;        {            // 1级作用域            let num = 456;            function test() {                // 2级作用域                let num = 789;                console.log(num);            }            test();        }    </script></head><body></body></html>

打印结果跟上面的是一样的。

JavaScript-预解析
  1. 什么是预解析?
  • 浏览器在执行JS代码的时候会分成两部分操作:预解析以及逐行执行代码
  • 也就是说浏览器不会直接执行代码, 而是加工处理之后再执行,
  • 这个加工处理的过程, 我们就称之为预解析
  1. 预解析规则
  • 将变量声明和函数声明提升到当前作用域最前面
  • 将剩余代码按照书写顺序依次放到后面
  1. 注意点
  • 通过let定义的变量不会被提升(不会被预解析)
  1. ES6之前的第一种定义函数的格式:
ES6之前的console.log(say);say();function say() {    console.log("hello it666");}//预解析格式function say() {    console.log("hello it666");}console.log(say);say();

4.1 ES6之前的第二种定义函数的格式:

  • 如果将函数赋值给一个var定义的变量, 那么函数不会被预解析, 只有变量会被预解析
say();      报错了,说say不是一个方法 (如果将函数赋值给一个var定义的变量, 那么函数不会被预解析, 只有变量会被预解析)var say = function() {    console.log("hello itzb");}//预解析格式var say;    //此时  say是undefined 是一个变量,不是函数console.log(say);  //打印结果为undefinedsay();   //所以这调用函数,报错var say = function() {    console.log("hello itzb");}

4.2 ES6定义函数的格式

say();  报错 say is not definedlet say = () => {    console.log("hello itzb");}

不会被预解析,因为把一个函数赋值给一个变量,不会被预解析,变量通过let定义的,也是不会被预解析,报错的内容是say is not defined,函数没定义

预解析练习
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>练习1</title>    <script>        // 1.下列程序的执行结果是什么?        var num = 123;        fun();        function fun() {            console.log(num);            var num = 666;        }    </script></head><body></body></html>

上面代码预解析的顺序

  1. 下面是0级左右域的预解析顺序
1. 先把变量定义放在最前面var num;2.把函数声明放在最前面function fun(){    console.log(num)    var num = 666;}3.把剩余的代码按照书写的顺序依次的放到后面num = 123;fun();
  1. 下面是函数里面1级作用域的预解析顺序
1.  先把变量定义放在最前面var num;2.把剩余的代码按照书写的顺序依次的放到后面console.log(num);num = 666;
  1. 总和一下就是
var num;function fun(){    var num;    console.log(num)     num = 666;}num = 123;fun();所以打印的结果为undefined,因为1级作用域里面的num还没赋值
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>练习1</title>    <script>        // 1.下列程序的执行结果是什么?        var a = 666;        test();        function test(){            var b = 777;            console.log(a);            console.log(b);            console.log(c);            var a = 888;            let c = 999;        }</head><body></body></html>

下面是预解析的顺序代码

//1 将变量声明和函数声明提升到当前作用域最前面var a;function test(){  //1.将变量声明和函数声明提升到当前作用域最前面,let不预解析,所以不会放在最前面  var b;  var a;  b = 777;  console.log(a);   //undefined  console.log(b);    //777  console.log(c);   报错  a = 888;  let c = 999;    var b = 777;    //console.log(a);    //console.log(b);    //console.log(c);    //var a = 888;    //let c = 999;}//2. 将其他代码依次写在后面a = 666;test();
ES6之前预解析

1.下列程序的执行结果是什么?

  • 在ES6之前没有块级作用域, 并且没有将这两个函数定义到其它的函数中,
  • 所以这两个函数应该属于全局作用域
    注意点:
  • 1.在高级浏览器中, 不会对{}中定义的函数进行提升
  • 2.只有在低级浏览器中, 才会按照正常的方式解析
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>练习3</title>    <script>        if(true){            function demo() {                console.log("hello demo1111111111");            }        }else{            function demo() {                console.log("hello demo2222222222");            }        }        demo();      /*      预解析逻辑    1. 先把函数声明放在最前面    function demo() {        console.log("hello demo1111111111");    }    //后面定义的函数,会把前面的函数覆盖掉    function demo() {        console.log("hello demo2222222222");    }    2. 把其他代码按照书写顺序,写在后面    if(true)else{}    demo();    //在高级浏览器中, 不会对{}中定义的函数进行提升,高版本输出的是1111,低版本输出的是2222  */    </script></head><body></body></html>
预解析 函数名和变量名一样
  • 如果变量名称和函数名称同名, 那么函数的优先级高于变量
  • 一定要记住, 在企业开发中千万不要让变量名称和函数名称重名
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>练习4</title>    <script>        // 1.下列程序的执行结果是什么?        console.log(value); // 会输出函数的定义        var value = 123;        function value() {            console.log("fn value");        }        console.log(value); // 会输出123     /*      1.函数放在最前面       function value() {            console.log("fn value");        }        var value;       console.log(value); // 会输出函数的定义       value = 123;       console.log(value); // 会输出123      */    </script></head><body></body></html>

阜新二级造价工程师培训
重庆二级造价工程师培训
猜你喜欢

热门话题