• 【技术积累】JavaScript中的函数【一】


    什么是函数?如何声明函数?

    JavaScript中的函数是一段可重复使用的代码块,它可以接受输入并返回输出。 在JavaScript中,函数是一种特殊的对象,因此可以将其存储在变量中,将其作为参数传递给其他函数,并从其他函数中返回。

    在JavaScript中,声明函数有两种方式:函数声明和函数表达式。

    1. 函数声明

    函数声明是指用关键字function定义函数的方法,在函数名后跟一对圆括号和一对花括号,并在花括号中编写函数体。

    示例:声明一个函数,它将两个数字相加并返回其总和。

    function addNumbers(num1, num2) {
      return num1 + num2;
    }

    2. 函数表达式

    函数表达式是指将函数赋值给变量的方法。它通常包含一个匿名函数,因此可以使用变量名调用该函数。

    示例:用函数表达式声明一个函数,它打印出两个数字的总和。

    let addNumbers = function(num1, num2) {
      console.log(num1 + num2);
    };

    函数还可以在调用时接受参数。这些参数通常是函数需要的输入,可以在函数中使用。

    例如,下面的函数将两个参数相加并返回结果:

    function addNumbers(num1, num2) {
      return num1 + num2;
    }
    
    let result = addNumbers(3, 5);
    console.log(result); // 输出结果为 8

    在这个例子中,我们调用了addNumbers函数,并将3和5传递给它作为参数。计算完成后,该函数返回结果8。 最后,我们将结果输出到控制台。

    总之,JavaScript中的函数是一种强大的工具,可以帮助我们将代码重用和管理代码流程。无论是函数声明还是函数表达式,我们都可以使用它们来创建代码块,以便在程序中多次使用。

    函数如何返回值

    JavaScript函数可以返回值。一个函数可以返回一个值,这个值可以是任意类型的数据,包括数字、字符串、对象等等。

    要返回一个值,可以使用关键字“return”后面跟着要返回的值。示例如下:

    function add(a, b) {
      return a + b;
    }
    
    var sum = add(2, 3);
    console.log(sum); // 输出 5

    在这个例子中,函数“add”返回了参数“a”和“b”的和。当使用这个函数时,返回值会被存储在变量“sum”中,并且在控制台中输出。

    在函数内部,如果没有明确的使用“return”语句,则默认返回“undefined”。例如:

    function sayHello() {
      console.log("Hello");
    }
    
    var result = sayHello();
    console.log(result); // 输出 undefined

    在这个例子中,函数“sayHello”没有返回任何值,因此默认返回了“undefined”。

    在实际编程中,函数的返回值通常用于向调用者传递处理结果或者状态。例如,在某些情况下,可能需要根据函数返回的值采取不同的操作,像这样:

    function checkAge(age) {
      if (age >= 18) {
        return "成年人";
      } else {
        return "未成年人";
      }
    }
    
    var result = checkAge(20);
    
    if (result === "成年人") {
      console.log("你可以去看电影");
    } else {
      console.log("你还不能去看电影");
    }

    在这个例子中,函数“checkAge”接收一个参数“age”,根据年龄判断是否成年,并返回“成年人”或“未成年人”。当调用函数时,返回值被存储在“result”变量中。在后面的代码中,使用“if”语句根据返回值来判断是否可以去看电影。

    什么是函数参数?函数参数传递的方式有哪些?

    函数参数是函数定义时用来接收外部传递进来的值或对象的占位符。在调用函数时,我们需要传递实际的值或对象作为函数参数,以便在函数内部使用。

    函数参数传递的方式有以下几种:

    1. 传递单个值:直接把值传递给函数。

    2. 传递多个值:使用逗号分隔多个值,按照参数列表的顺序传递给函数。

    3. 传递对象:将一个对象作为参数传递给函数,函数可以通过对象访问其属性。

    4. 传递数组:将一个数组作为参数传递给函数,函数可以使用数组下标访问数组元素。

    5. 省略参数:可以省略某些参数,未传递的参数将被设定为undefined。

    6. 回调函数:将一个函数作为另一个函数的参数传递,以便在另一个函数执行完成后调用该函数。

    7. 使用arguments对象:函数内部可以使用arguments对象访问所有传递进来的参数,无需事先定义参数的名称和数量。

    8. ES6中的展开运算符:可以使用展开运算符将数组或对象中的值展开为函数的参数。

    在函数中使用全局变量可以直接使用全局变量的名称。在JavaScript中,全局变量可以通过在函数外部定义变量来创建。例如:

    var globalVar = "Hello World!";
    
    function myFunction() {
      console.log(globalVar);
    }
    
    myFunction(); // 输出结果:Hello World!

    在函数内部创建局部变量,可以使用var、let和const关键字定义一个新的变量。这些变量的作用域仅限于函数内部,函数外部无法访问。例如:

    function myFunction() {
      var localVar = "This is a local variable.";
      console.log(localVar);
    }
    
    myFunction(); // 输出结果:This is a local variable.
    console.log(localVar); // 抛出ReferenceError异常:localVar is not defined

    在ES6中,使用let和const关键字创建的变量具有块级作用域,可以在定义变量的块中访问该变量,包括在函数内部。例如:

    function myFunction() {
      let localVar = "This is a local variable.";
      console.log(localVar);
    }
    
    myFunction(); // 输出结果:This is a local variable.
    console.log(localVar); // 抛出ReferenceError异常:localVar is not defined

    什么是函数作用域

    JavaScript的函数作用域是指变量可以在函数内声明并在函数内使用,而在函数外无法访问该变量。这是因为JavaScript中的函数都有它们自己的作用域。

    例如,在以下示例中,变量x在函数foo的作用域中声明,因此只能在该函数内部使用:

    function foo() {
      var x = 10; // 变量x 只在函数foo中可见
      console.log(x);
    }
    
    console.log(x); // 报错,变量x无法访问

    函数作用域可以帮助程序员避免变量命名冲突和全局变量的滥用。它还允许在函数内声明和使用私有变量,这些变量不会泄露到全局作用域中。

    JavaScript中的函数作用域实现是通过词法作用域(也称静态作用域)实现的。在词法作用域中,函数的作用域是在函数定义时确定的,而不是在函数调用时确定的。这意味着函数可以在它被定义的地方访问其外部作用域中的变量,而不必等到函数被调用时。

    什么是闭包?如何使用闭包?

    闭包是指在一个函数内部定义另一个函数,并使得这个内部函数可以访问到外部函数的变量和参数。闭包可以将这些变量和参数的值保存下来,以供后续使用。

    在JavaScript中,可以使用闭包来实现许多功能,比如:

    1. 封装私有变量

    通过使用闭包,可以创建一个对象,该对象包含一些私有变量和一些公共方法,但这些私有变量无法从外部访问。这样做可以保证代码的安全性和可维护性。

    例如:

    function createCounter() {
      var count = 0;
      return {
        increment: function() {
          count++;
        },
        getValue: function() {
          return count;
        }
      };
    }
    
    var counter = createCounter();
    
    counter.increment();
    console.log(counter.getValue()); // 1

    2. 延迟执行

    通过使用闭包,可以在需要时延迟执行某些代码,这对于一些需要耗费时间的操作(比如网络请求)很有用。

    例如:

    function delayedAlert(message, time) {
      setTimeout(function() {
        alert(message);
      }, time);
    }
    
    delayedAlert('Hello World!', 2000);

    3. 记忆化

    通过使用闭包,可以在函数执行时将其结果缓存下来,以便下次执行时直接返回缓存的结果,从而提高性能。

    例如:

    function memoize(func) {
      var cache = {};
      return function() {
        var key = JSON.stringify(arguments);
        if (cache[key]) {
          return cache[key];
        } else {
          var result = func.apply(this, arguments);
          cache[key] = result;
          return result;
        }
      };
    }
    
    var fib = memoize(function(n) {
      if (n <= 1) {
        return n;
      } else {
        return fib(n - 1) + fib(n - 2);
      }
    });
    
    console.log(fib(10)); // 55

    4. 模块化

    通过使用闭包,可以创建一个独立的模块,该模块包含一些私有变量和方法,同时仍然可以对外暴露一些公共方法。

    例如:

    var calculator = (function() {
      var result = 0;
    
      function add(x) {
        result += x;
      }
    
      function subtract(x) {
        result -= x;
      }
    
      function reset() {
        result = 0;
      }
    
      function getResult() {
        return result;
      }
    
      return {
        add: add,
        subtract: subtract,
        reset: reset,
        getResult: getResult
      };
    })();
    
    calculator.add(5);
    calculator.subtract(2);
    console.log(calculator.getResult()); // 3
    calculator.reset();
    console.log(calculator.getResult()); // 0

    总之,闭包是一种非常强大的功能,在JavaScript中广泛使用。它可以用于封装私有变量、延迟执行、记忆化、模块化等多种场合。

    闭包的优点和缺点是什么?

    JavaScript闭包的优点:

    1. 可以通过闭包来创建私有变量和方法,防止变量和方法被外部代码访问和修改,从而保护程序的安全性。
    2. 可以帮助我们实现高阶函数,从而提高代码的可复用性,并且可以使代码更加简洁。
    3. 闭包可以实现数据缓存,从而提高程序的性能,避免重复计算。

    JavaScript闭包的缺点:

    1. 闭包可能导致内存泄漏,因为闭包中捕获的变量不会被垃圾回收机制自动释放。
    2. 闭包的运行速度可能比常规函数慢,因为它需要同时保存外部函数的作用域和内部函数的作用域。
    3. 闭包可能会导致变量被意外修改,因为闭包中的变量是共享的,如果在外部函数中修改了闭包中的变量,那么所有使用该闭包的代码都会受到影响。

    什么是高阶函数

    在JavaScript中,高阶函数是指能够接收一个或多个函数作为参数,并且能够返回一个新函数的函数。这种函数的灵活性让它们非常强大,并可以用于编写更加简洁和灵活的代码。

    高阶函数的特点:

    1. 接收一个或多个函数作为参数。
    2. 返回一个新函数。
    3. 可以对参数函数进行处理,比如运算、组合、封装等操作。

    高阶函数的使用场景:

    1. 回调函数:在异步代码中,高阶函数常常被用作回调函数,用于处理异步操作的结果。
    2. 遍历:高阶函数可以用于对数组、对象或其他数据结构进行遍历和筛选。
    3. 函数组合:高阶函数可以将多个处理逻辑组合在一起,实现更加复杂的功能。
    4. 封装:高阶函数可以用于对一些重复的操作进行封装,提高代码重用性和可维护性。

    例如,如果我们想在一个数组中找到所有大于3的数字,可以使用高阶函数`filter`:

    const arr = [1, 2, 3, 4, 5];
    const result = arr.filter(function(item) {
      return item > 3;
    });
    console.log(result); // [4, 5]

    在上述代码中,`filter`函数就是一个高阶函数,它接收一个匿名函数作为参数,用于处理数组元素,并返回一个新的数组,其中仅包含满足条件的元素。

    什么是回调函数?如何使用回调函数?

    回调函数是一个在某个事件发生时执行的函数,它是JavaScript中一种常见的异步编程方式。回调函数通常作为参数传递给另一个函数,并在另一个函数执行完毕后被调用。

    使用回调函数时,需要注意以下几点:

    1. 回调函数必须是一个函数,可以是内置函数或自定义函数。
    2. 回调函数必须作为参数传递给另一个函数,并在另一个函数执行完毕后被调用。
    3. 回调函数的参数和返回值必须符合另一个函数的要求。

    示例:

    function add(a, b, callback) {
      var result = a + b;
      callback(result);
    }
    
    add(1, 2, function(result) {
      console.log(result);
    });

    在上面的例子中,add函数有三个参数,其中callback函数是回调函数,当add函数执行完毕后,会调用这个回调函数并传递计算结果。

    在调用add函数时,传入了两个数字和一个回调函数。回调函数在add函数执行完毕后被调用,并打印出计算结果。

    什么是箭头函数?

    JavaScript中的箭头函数是ES6(ECMAScript 2015)中添加的一种新函数类型。箭头函数是一种更简洁的函数声明方式,同时也有不同于传统函数的一些特性。

    箭头函数的语法形式为:(参数)=> {函数体}

    其中,参数和函数体之间由箭头符号(=>)连接。

    箭头函数与传统函数的一些不同点如下:

    1. 箭头函数没有自己的this对象,它的this继承自父作用域。这意味着在箭头函数中使用this时,它实际上是指向父作用域中的this,而不是箭头函数自己的this。

    2. 箭头函数没有arguments对象,但可以使用rest参数(...args)取代。

    3. 如果箭头函数只有一个参数,可以省略小括号。

    4. 如果函数体只有一条语句,可以省略大括号和return语句。

    箭头函数的应用场景:

    1. 作为回调函数。箭头函数的简洁语法和继承父作用域的this对象使它非常适合作为回调函数。

    2. 与数组方法结合使用。在数组方法中,箭头函数比传统函数更具可读性和简洁性。

    3. 与PromiseAPI结合使用。在PromiseAPI中,箭头函数可以帮助我们更方便地处理异步代码。

    总之,箭头函数是一种更简洁、更易读、更方便的函数类型,它的使用可以提高代码的可读性和开发效率。

    // 传统函数
    function greeting(name) {
      console.log("Hello, " + name);
    }
    
    // 箭头函数
    const greetingArrow = name => {
      console.log("Hello, " + name);
    }
    
    greeting("Tom"); // 输出 "Hello, Tom"
    greetingArrow("Jerry"); // 输出 "Hello, Jerry"
    const shoppingCart = [
       { id: 1, name: "Shirt", price: 25 },
       { id: 2, name: "Pants", price: 50 },
       { id: 3, name: "Shoes", price: 100 }
    ];
    
    const VAT_RATE = 0.2; // 税率
    
    const calculateTotalPrice = shoppingCart => {
      // 使用 reduce 方法计算购物车中所有商品的总价
      const totalPrice = shoppingCart.reduce((acc, product) => acc + product.price, 0);
      
      // 计算总价和税费
      const total = totalPrice + (totalPrice * VAT_RATE);
      
      // 四舍五入并保留两位小数
      return Math.round(total * 100) / 100;
    }
    
    const total = calculateTotalPrice(shoppingCart);
    console.log("Total Price: $" + total); // 输出 "Total Price: $210"

    什么是Promise?如何使用Promise?

    Promise是JavaScript中一种异步编程的解决方案,它表示一个尚未完成但预计将来会完成的操作,并提供一种处理该操作结果的方式。

    在Promise中,我们可以定义需要执行的操作,以及当操作完成后需要执行的一系列回调函数。Promise既可以表示操作失败的情况,也可以表示操作成功的情况。

    Promise具有以下特点:

    1. Promise对象的状态不受外界影响。一旦状态改变,就不会再变,任何时候都可以得到这个结果。

    2. Promise对象的状态一旦改变,就不能再改变。如果不设置回调函数,Promise内部的错误不会影响到外部。

    3. Promise 对象提供了链式操作,可以使其代码更加简洁易读。

    const promise = new Promise((resolve, reject) => {
      // 异步操作
      setTimeout(function(){
        const num = Math.random();
        if(num < 0.5){
          resolve(num)
        } else {
          reject(num)
        }
      }, 1000)
    })
    
    promise.then((res)=>{
      console.log("操作成功,结果为:", res);
    }).catch((err)=>{
      console.log("操作失败,结果为:", err);
    })

    上述代码中,我们通过Promise构造函数创建了一个Promise对象,在异步操作完成后通过resolve方法表示操作成功并返回一个结果,通过reject方法表示操作失败并返回一个错误信息。在then和catch方法中,我们分别定义了操作成功和操作失败后需要执行的回调函数。

     

    Promise有三种状态:pending、fulfilled和rejected。当异步操作执行时,它最初处于pending状态。如果异步操作成功,则状态变为fulfilled,并返回一个值,如果发生错误,则状态变为rejected,并返回一个错误对象。

    下面是使用Promise的简单示例:

    function fetchData() {
      return new Promise((resolve, reject) => {
        fetch('https://jsonplaceholder.typicode.com/users')
          .then(response => response.json())
          .then(data => resolve(data))
          .catch(error => reject(error))
      })
    }
    
    fetchData()
      .then(data => console.log(data))
      .catch(error => console.error(error))

    上面的代码中,fetchData函数返回一个Promise。如果异步操作成功,它会调用resolve回调函数,并传递数据对象。如果发生错误,它会调用reject回调函数,并传递一个错误对象。

    在这个示例中,我们使用了fetch API来获取数据。通过调用response.json(),我们将响应对象转换为JSON格式的数据。最后,我们处理数据对象或错误对象,您可以在.then()和.catch()方法中进行操作。

    在处理异步操作时,Promise非常强大且易于使用。它可以简化代码并提高可读性。不要犹豫,尝试使用Promise来处理异步操作。

    什么是async/await? 如何使用async/await?

    async/await 是一种用于简化异步操作的语法特性。它基于 Promise 对象,利用 async 和 await 关键字简化 Promise 的链式调用和错误处理,使异步代码看起来像同步代码。

    async 表示一个函数是异步的,并返回一个 Promise 对象。await 表示等待 Promise 对象的解决,并返回 Promise 对象的解决值。使用 async/await 可以避免回调地狱,提高代码的可读性和可维护性。

    使用 async/await 的基本流程如下:

    1.定义一个异步函数,使用 async 关键字标记。

    2.在函数中使用 await 关键字等待 Promise 对象处理完成,返回 Promise 对象的解决值。

    3.处理 Promise 对象的错误,使用 try...catch 捕获异步操作的错误。

    例如:

     

    async function getData() {
      try {
        let response = await fetch('https://jsonplaceholder.typicode.com/users');
        let data = await response.json();
        console.log(data);
      } catch (error) {
        console.log(error);
      }
    }
    
    getData();

    在上面的例子中,我们定义一个异步函数`getData`,使用 await 关键字等待 fetch() 方法返回的 Promise 对象处理完成,然后再使用 await 关键字等待 response 对象的 json() 方法返回的 Promise 对象处理完成,最后将返回的 JSON 数据输出。同时使用 try...catch 捕获异步操作的错误,便于进行错误处理。

    使用 async/await 可以大大简化 Promise 的链式调用和错误处理,提高代码的可读性和可维护性。但需要注意的是,await 只能在 async 函数内部使用,否则会报语法错误。

  • 相关阅读:
    力扣大厂热门面试算法题 27-29
    SpringCloud组件Ribbon的IRule的问题排查
    训练一个神经网络要多久,神经网络训练时间过长
    【无标题】
    SpringBoot集成RabbitMQ使用建议
    报名开启丨2023 SpeechHome 语音技术研讨会
    竞赛 深度学习 python opencv 火焰检测识别
    缓存的使用及常见问题的解决方案
    Redis 集群模式
    【计算机网络期末复习】选择题①1~50
  • 原文地址:https://www.cnblogs.com/yyyyfly1/p/17477105.html