javascript avanzado (3)

función

Tres formas de crear una función

1. Función ordinaria declarada por función (función nombrada)

2. Expresión de función (función anónima)

3.nueva función ()

var fn = new Function ('parámetro 1', 'parámetro 2', ..., 'cuerpo de la función);

  • Los parámetros en Function () están todos en formato de cadena

  • El tercer método tiene una eficiencia de ejecución relativamente baja y es incómodo de escribir, por lo que rara vez se usa

  • Todas las funciones son objetos de instancia de Fnction

  • Las funciones también son objetos

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>函数的定义和调用方式</title>
</head>
<body>
<script>
    // 自定义方式
 function fn() {
    }
    // 函数表达式
 var fn = function() {
    }
    // 利用new Function('参数1','参数2','函数体')
 var f = new Function('a','b','return a+b')
    console.log(f(1,2));
    console.dir(f);
    //用来判断f是否是一个对象
 console.log(f instanceof Object)
</script>
</body>
</html>


Inserte la descripción de la imagen aquí

Cómo llamar a diferentes funciones


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button>按钮</button>
</body>
<script>
    // 函数的调用方式
    // 1.普通函数的调用
    function fn() {
        console.log('hello word')
    }
    fn()
    // 2.对象类的函数调用
    var obj = {
        say: function () {
            return 'hello word'
        }
    }
    console.log(obj.say())
    // 3.构造函数的调用
    function Star(name, age) {
        this.name = name;
        this.age = age;
    }
    var star1 = new Star('尧子陌', '18');
    console.log(star1.name)
    //4.事件函数的调用
    var bth = document.querySelector('button');
    bth.addEventListener('click', function () {
        console.log('事件函数')
    })
    // 5.定时器函数
    setInterval(function () {
        console.log('定时器函数')
    }, 5000)
</script>
</html>

Inserte la descripción de la imagen aquí

Función autoejecutable

Como su nombre lo indica: una función llamada por usted mismo


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>自执行函数</title>
</head>
<body>
<script>
    (function () {
        alert('hello word')
    })()
</script>
</body>
</html>

Inserte la descripción de la imagen aquí

esto apunta al problema

Este punto dentro de la función se determina cuando llamamos

Nota: Esto se refiere a la ventana en la función autoejecutable.

Inserte la descripción de la imagen aquí

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>函数的this指向</title>
    </head>
    <body>
        <button>按钮</button>
    </body>
    <script>
        // 函数的调用方式

        // 1.普通函数的调用
        function fn() {
            console.log(this) //windows

        }

        fn()
        // 2.对象类的函数调用
        var obj = {
            say: function() {
                console.log(this) //指向o这个对象
            }
        }
        obj.say()

        // 3.构造函数的调用
        function Star(name, age) {
            console.log(this) //构造函数中的this指向的是它的实例化 star
            this.name = name;
            this.age = age;

        }

        var star1 = new Star('尧子陌', '18');
        //4.事件函数的调用
        var bth = document.querySelector('button');
        bth.addEventListener('click', function() {
            console.log(this) //事件函数中的this 指向的是它的调用者bth按钮
        })

        // 5.定时器函数
        setInterval(function() {
            console.log(this) //定时器中的this 指向的是windows
        }, 5000)
    </script>
</html>



Inserte la descripción de la imagen aquí

llamar () aplicar () vincular ()

método call ()

El método call () llama a un objeto. Simplemente se entiende como la forma de llamar a una función, pero puede cambiar este punto de la función.

fun.call (thisArg, arg1, arg2,…)

  • thisArg: este valor especificado cuando la función divertida se está ejecutando
  • arg1, arg2: otros parámetros pasados
  • El valor de retorno es el valor de retorno de la función, porque es la función que llama
  • Por lo tanto, cuando queremos cambiar este punto y llamar a esta función al mismo tiempo, podemos usar llamada, como herencia


<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <title>call()</title>
    </head>

    <body>

    </body>
    <script>
        // 改变函数内部的this指向之call()方法
        var o = {
            name: "andy"
        };

        function fn(a, b) {
            console.log(this); //o
            console.log(a + b); //3
        }

        fn.call(o, 1, 2) //call方法不仅可以改变函数内部的this指向,还可以传递参数


        //call()方法主要是为了实现继承


        function Father(name, age, sex) {
            console.log(this)
            this.name = name;
            this.age = age;
            this.sex = sex;

        }

        function Son(name, age, sex) {
            Father.call(this, name, age, sex)
        }

        var son = new Son('刘德华', '18', '男');
        console.log(son)
    </script>

</html>

 


Inserte la descripción de la imagen aquí

aplicar () método

El método apply () llama a una función. Simplemente se entiende como la forma de llamar a una función, pero puede cambiar este punto de la función.

fun.apply (thisArg, [argsArray])

  • bthisArg: este valor se especifica cuando se ejecuta la función divertida
  • argsArray: el valor pasado debe estar contenido en la matriz
  • El valor de retorno es el valor de retorno de la función, porque es la función que llama
  • Por lo tanto, aplicar está principalmente relacionado con la matriz, como usar Math.max () para encontrar el valor máximo de la matriz

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>改变函数内部的this指向之apply()</title>
</head>

<body>

</body>
<script>
    var o = {
        name: 'andy'

    }

    function fn(arr) {
        console.log(this); //此时的this指向的是0;
        console.log(arr)

    }

    fn.apply(o, ['pink']); //注意:第二个参数必须为数组

    // 可以用数组方法实现求数组的最大值
    var arr2 = [1, 66, 22, 55, 108];
    var max = Math.max.apply(Math, arr2);
    var min = Math.min.apply(Math, arr2);
    console.log(max, min)
</script>

</html>

Inserte la descripción de la imagen aquí

unir()

El método bind () no llama a la función. Pero puede cambiar este punto dentro de la función.

fun.bind (thisArg, arg1, arg2,…)

  • thisArg: este valor especificado cuando la función divertida se está ejecutando
  • arg1, arg2: otros parámetros pasados
  • Devuelve una copia de la función original modificada por el valor especificado y los parámetros de inicialización
  • Entonces, cuando solo queremos cambiar este punto y no queremos llamar a esta función, podemos usar bind ()
  
  <!DOCTYPE html>
  <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>改变函数的内部的this指向之bind()方法</title>

    <body>
        <button>按钮</button>
        <button>按钮</button>
        <button>按钮</button>
    </body>
    <script>
        // bind()方法是绑定 捆绑的意思
        var o = {
            name: "andy"
        }

        function fn(a, b) {
            console.log(this)
            console.log(a + b)
        }

        // 注意:bind()方法会改变函数内部的this,但不会调用原来的函数
        var f = fn.bind(o, 1, 2);
        f()

        //案例:当我们点击按钮之后,就禁用这个按钮,三秒之后再次开启这个按钮
        var bths = document.querySelectorAll('button');
        for (var i = 0; i < bths.length; i++) {
            bths[i].onclick = function() {
                this.disabled = true;
                setTimeout(function() {
                    this.disabled = false
                    // 这里的this指的是bth这个按钮
                }.bind(this), 2000)
            }
        }
    </script>
</html>

Inserte la descripción de la imagen aquí

La diferencia entre call () apply () bind ()

Punto de diferencia:

1.call and apply llamará a la función y cambiará este punto dentro de la función.

2. Los parámetros pasados ​​por la llamada y la aplicación son diferentes, la llamada pasa los parámetros aru1, aru2 ... la forma de aplicación debe estar en forma de matriz [arg]

3. Bind no llamará a la función, puede cambiar el punto interno de la función.
Escenarios de aplicación principales:

La llamada a menudo hace herencia.

1.aplicar a menudo está relacionado con matrices. Por ejemplo, el uso de objetos matemáticos para lograr los valores máximos y mínimos de la matriz

2.bind no llama a la función, pero también quiere cambiar este punto. Por ejemplo, cambia este punto dentro del temporizador.

Modo estricto

La aparición del modo estricto es limitar la gramática no estándar en el modo estricto no estándar y allanar el camino para ES6

El modo estricto realiza algunos cambios en la semántica normal de JavaScript:

1. Elimine algunos aspectos poco razonables e imprecisos de la sintaxis de Javascript y reduzca algunos comportamientos extraños.

2. Elimine algunos aspectos inseguros de la operación del código y garantice la seguridad de la operación del código.

3. Mejore la eficiencia del compilador y aumente la velocidad de ejecución.

4. Desactive algunas gramáticas que puedan definirse en futuras versiones de ECMAScript, allanando el camino para nuevas versiones de Javascript en el futuro.

Por ejemplo, algunas palabras reservadas como: clase, enumeración, exportación, extensión, importación, super no se pueden utilizar como nombres de variable.

Activa el modo estricto

Poner 'usar estricto' en el script del script o dentro de la función es equivalente a activar el modo estricto


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script type="text/javascript">
      // 为脚本开启严格模式
        'use strict'
  </script>
  
  <script type="text/javascript">
        function fn(){
            // 为函数开启严格模式
            'use strict'
        }
  </script>
</body>
</html>


Cambios en modo estricto

  • En modo estricto, las variables deben declararse antes de que puedan usarse
  • Esto en funciones ordinarias en modo estricto apunta a indefinido
  • En modo estricto, el constructor no agrega una nueva llamada, esto se refiere a indefinido
  • Esto en el temporizador en modo estricto apunta a la ventana

<!DOCTYPE html>
<html lang="en">
   <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <meta http-equiv="X-UA-Compatible" content="ie=edge">
       <title>严格模式的变化</title>
   </head>
   <body>
       <script type="text/javascript">
           'use strict'
           // 1.变量必须先声明再使用
           var num = 10;
           console.log(10);
           // delete  num; 严格模式下禁用删除变量

           // 2.严格模式下的this指向undefined
           function fn() {
               console.log(this) //严格模式下this指的是undefined
           }
           fn()
           // 3.严格模式下构造函数不加new调用,this指的是undefined
           function Star() {
               console.log(this)
           }
           Star()

           //4.严格模式下定时器的this指向window
           setTimeout(function() {
               console.log(this)
           }, 2000)
       </script>
   </body>
</html>




Inserte la descripción de la imagen aquí

Función de orden superior

Las funciones de orden superior son funciones que operan en otras funciones, acepta funciones como parámetros o funciones de salida como valores de retorno.

fn () y fn2 son funciones caras




<!DOCTYPE html>
<html>
   <head>
       <meta charset="utf-8">
       <title>高阶函数</title>
   </head>
   <body>

   </body>
   <script>
       // 将函数作为参数
       function fn(callback) {
           callback && callback()
       }
       fn(function() {
           alert('hello word')
       })


       //将函数作为返回值输出
       function fn2() {
           return function() {}
       }
       console.log(fn2())
   </script>
</html>



Inserte la descripción de la imagen aquí

Llamar de vuelta

La función también es un tipo de datos, que se puede pasar como parámetro a otra función como parámetro, la más típica es la función de devolución de llamada


 
<!DOCTYPE html>
<html>
   <head>
       <meta charset="utf-8">
       <title>高阶函数</title>
       <style>
           * {
               margin: 0;
               padding: 0;
           }
           .box {
               position: absolute;
               top:0;
               left: 0;
               width: 200px;
               height: 200px;
               background-color: blueviolet
           }
       </style>
   </head>
   <script src="jquery.min.js"></script>
   <body>
       <div class="box"></div>
       
   </body>
   <script>
       $('.box').animate({
           left:200,
           top:200
       },function(){
           $(this).css('background','red')
       })
   </script>
</html>



Inserte la descripción de la imagen aquí

Cierre

Se refiere a una función que tiene acceso a variables en el ámbito de otra función.

Rol: ampliar el alcance de la variable


<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>闭包</title>
    </head>
    <body>
        <div></div>
    </body>
    <script>
        // 所谓的闭包 简单理解:就是有权访问另一个函数的局部变量
        function fn() {
            let num = 10;

            function fun() {
                console.log(num) //10
            }

            fun()
        }

        fn()
    </script>
</html>


Inserte la descripción de la imagen aquí

Cierre de depuración en cromo

1. Abra el navegador y presione F12 para iniciar la herramienta de depuración de Chrome.

2. Establezca un punto de interrupción.

3. Busque la opción Alcance (el significado de Alcance).

4. Cuando volvamos a actualizar la página, ingresaremos a la depuración del punto de interrupción y habrá dos parámetros en el alcance (alcance global global, alcance local local).

5. Los parámetros de cierre representan funciones de cierre

El papel de las funciones de cierre


<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>闭包的作用</title>
    </head>
    <body>

    </body>
    <script>
        // 有权访问另一个函数的局部变量的函数 便叫做局部变量
        function fn() {
            var num = 10;
            return function() {
                console.log(num) //10
            }

        }

        var f = fn(); //fn()
        f(); //调用return后面的函数
    </script>
</html>


Inserte la descripción de la imagen aquí

La salida del cierre li es el número de índice creado actualmente

Idea central: solo use la función para ejecutar inmediatamente

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>闭包之点击i输出索引号</title>
    </head>
    <body>
        <ul class="nav">
            <li>one</li>
            <li>two</li>
            <li>three</li>
            <li>four</li>
        </ul>
    </body>
    <script>
        // 第一种方法:点击i输出当前i的索引号
        var lis = document.querySelector('.nav').querySelectorAll('li');

        for (var i = 0; i < lis.length; i++) {
            lis[i].index = i; //为每次循环的li设置索引号

            lis[i].addEventListener('click', function() {
                console.log(this.index)
            })
        }

        // 第二种方法:利用闭包输出当前的索引号

        for (var i = 0; i < lis.length; i++) {
            // 利用for循环创建四个立刻执行函数,因为立刻执行函数里面的原函数可以使用它的变量

            (function(i) {
                lis[i].addEventListener('click', function() {
                    console.log(i)
                })
            }(i))

        }
    </script>
</html>




Inserte la descripción de la imagen aquí

Temporizador de cierre

Requisito: mostrar automáticamente el contenido en li después de tres segundos

Idea central: utilice la función de cierre generada por cada bucle del bucle for



<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>闭包之定时器</title>
    </head>
    <body>
        <ul class="nav">
            <li>one</li>
            <li>two</li>
            <li>three</li>
            <li>four</li>
        </ul>
    </body>
    <script>
        var lis = document.querySelector('.nav').querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {

            (function(i) {
                setTimeout(function() {
                    console.log(lis[i].innerHTML)
                }, 5000)
            }(i))
        }
    </script>


</html>





Inserte la descripción de la imagen aquí

Precio del taxi de cierre

El precio inicial de un taxi es 13 (dentro de los 3 kilómetros), y luego se agregarán 5 yuanes adicionales por cada kilómetro adicional. El usuario puede ingresar el número de kilómetros para calcular el precio del taxi.

Si hay congestión, el precio total se cobrará una tarifa de congestión adicional de 10 yuanes.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>闭包之打车价格</title>
    </head>
    <body>
    </body>
    <script>
        let car = (function() {
            let star = 13; //打车起步价
            let total = 0; //总价 局部变量
            return {
                price: function(n) {
                    if (n <= 3) {
                        total = star
                    } else {
                        total = star + (n - 3) * 5
                    }
                    return total //注意:不要忘记将值返回
                },
                // 拥堵之后的费用
                yd: function(flag) {
                    return flag ? total + 10 : total;
                }

            }

        })();
        console.log(car.price(5));
        console.log(car.yd(true)) //参数为true 则说明堵塞加10元


        console.log(car.price(6));
        console.log(car.yd(false))
    </script>
</html>
                                                    




Inserte la descripción de la imagen aquí

Prueba de cierre

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
<script>
    // 思考题 1:

    var name = "The Window";
    var object = {
        name: "My Object",
        getNameFunc: function () {
            return function () {
                return this.name;
            };
        }
    };

    console.log(object.getNameFunc()())
    var f = object.getNameFunc();

    var f = function () {
        return this.name;
    }
    f();


    // 思考题 2:

    var name = "The Window";
    var object = {
        name: "My Object",
        getNameFunc: function () {
            var that = this;
            return function () {
                return that.name;
            };
        }
    };
    console.log(object.getNameFunc()())
</script>
</body>

</html>




Inserte la descripción de la imagen aquí

función recursiva

Si una función puede llamarse a sí misma internamente, esta función es una función recursiva

Comprensión simple: llámese a sí mismo dentro de la función

El efecto de la función recursiva es el mismo que el efecto del bucle, es propenso al 'desbordamiento de la pila', por lo que es necesario agregar la condición de salida return

Ejercicios de funciones recursivas



<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

</body>
<script>
    var num = 1;

    function fn() {
        console.log('hello word')
        if (num == 6) {
            return //递归函数必须要有退出条件
        }
        num++
        fn()
    }

    fn()
</script>
</html>


Inserte la descripción de la imagen aquí

Función recursiva para encontrar el factorial de 1 ~ n

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>利用递归求1-n的阶乘</title>
</head>
<body>

</body>
<script>
    function fn(n) {
        if(n==1){
            return 1
        }
        return  n *fn(n-1)

    }

    console.log(fn(3));
    // 假入用户输入的是3
   /* return 3*fn(2)
    return 3*fn(2*fn(1))
    return 3*(2*1)
    return 3*2
    return 6 */
</script>
</html>


Inserte la descripción de la imagen aquí

Encontrar la secuencia de Fibonacci de la función recursiva (secuencia de conejo)

Encuentra la secuencia de Fibonacci (secuencia de conejo) 1, 1, 2, 3, 5, 8, 13, 21 ...


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
<script>
    // 利用递归函数求斐波那契数列(兔子序列)  1、1、2、3、5、8、13、21...
    // 用户输入一个数字 n 就可以求出 这个数字对应的兔子序列值
    // 我们只需要知道用户输入的n 的前面两项(n-1 n-2)就可以计算出n 对应的序列值
    function fb(n) {
        if (n === 1 || n === 2) {
            return 1;
        }
        return fb(n - 1) + fb(n - 2);
    }
    console.log(fb(3));
    console.log(fb(6));

  
</script>
</body>

</html>



Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/weixin_45419127/article/details/112646585
Recomendado
Clasificación