8.JS学习篇-箭头函数和普通函数

1. 箭头函数

1.语法特点

1.基本语法

  • 箭头函数由参数列表、箭头(=>)和函数体组成。
    const add = (a, b) => a + b;,这个箭头函数接收两个参数a和b,并返回它们的和。

2.简洁的单参数和无参数形式

  • 如果箭头函数只有一个参数,可以省略参数列表的括号。例如:
    const square = x => x * x;
  • 如果箭头函数没有参数,需要使用空括号。
    const getCurrentTime = () => new Date().toLocaleTimeString();

3.简洁的函数体

如果函数体只有一条表达式,可以省略大括号和return关键字,表达式的值会自动作为函数的返回值。

const double = num => num * 2;

        如果函数体包含多条语句,需要使用大括号,并明确使用return语句返回值。

const calculate = (a, b) => { const sum = a + b; const product = a * b; return { sum, product }; };
2.this绑定

1.继承外层上下文的this

  • 箭头函数不具有自己的this,它会继承外层代码块的this值。这在处理回调函数和事件处理程序时非常有用,可以避免this指向错误的问题。
       const obj = {
         name: 'John',
         sayHello: function() {
           setTimeout(() => {
             console.log(`Hello, ${this.name}!`);
           }, 1000);
         }
       };
    
       obj.sayHello(); // 输出:Hello, John!

2.与普通函数的对比

  • 普通函数的this指向取决于函数的调用方式,可以通过callapplybind方法来改变this的值。而箭头函数的this是在定义时确定的,不能通过这些方法改变。
    function Person() {
         this.age = 30;
         this.sayAge = function() {
           console.log(this.age);
         };
         this.sayAgeArrow = () => {
           console.log(this.age);
         };
       }
    
       const person = new Person();
       const sayAgeFunc = person.sayAge;
       sayAgeFunc(); // undefined(在非严格模式下为全局对象的属性值)
       const sayAgeArrowFunc = person.sayAgeArrow;
       sayAgeArrowFunc(); // 30(继承了外层上下文的`this`)
3.实际应用场景

1.数组方法中的回调函数

  • 在数组的mapfilterreduce等方法中,使用箭头函数可以使代码更加简洁易读。
       const numbers = [1, 2, 3, 4, 5];
       const doubledNumbers = numbers.map(num => num * 2);
       const evenNumbers = numbers.filter(num => num % 2 === 0);
       const sum = numbers.reduce((acc, num) => acc + num, 0);

2.事件处理程序

  • 在处理 DOM 事件时,箭头函数可以确保this指向正确的对象,避免了使用普通函数时需要手动绑定this的麻烦。
    <button id="myButton">Click me</button>
    
    
    document.getElementById('myButton').addEventListener('click', () => {
         console.log(this); 
    // 在浏览器环境中,`this`通常指向`window`对象或全局对象,
    // 如果在严格模式下,`this`为`undefined`。
    // 但是,如果在模块中使用箭头函数作为事件处理程序,`this`的指向取决于模块的上下文。
       });

3.立即执行函数表达式(IIFE)

  • 箭头函数可以用于创建立即执行的函数表达式,特别是在需要传递参数或避免污染全局命名空间时。
    (() => {
         console.log('This is an immediately invoked arrow function.');
       })();

4. 注意事项

        1.不能作为构造函数

  • 箭头函数不能用作构造函数,不能使用new关键字调用箭头函数。如果尝试这样做,会抛出错误。
    const MyClass = () => {}; const instance = new MyClass(); // 抛出错误。

        2.没有arguments对象

  • 箭头函数没有自己的arguments对象。如果需要访问函数的参数,可以使用剩余参数或解构赋值来获取参数。
    const sum = (...nums) => nums.reduce((acc, num) => acc + num, 0);
       console.log(sum(1, 2, 3)); // 6

2.普通函数

普通函数是一种常见的编程结构,具有以下特点和应用场景:

1.语法和定义

        1.基本语法

  • 使用 function 关键字进行定义。
    function add(a, b) { return a + b; }
  • 函数可以有零个或多个参数,参数之间用逗号分隔。
  • 函数体包含一系列语句,用于执行特定的任务,并可以通过 return 语句返回一个值。

        2.函数声明和函数表达式

  • 函数声明是在代码中独立出现的函数定义,会在代码执行前被解析和提升到作用域的顶部。
    function multiply(a, b) { return a * b; }
  • 函数表达式是将函数赋值给一个变量,可以在任何位置定义。
    const subtract = function(a, b) { return a - b; }

2.this指向

        1.一般情况下的 this

  • 在普通函数中,this 的指向取决于函数的调用方式。
  • 在全局作用域中调用函数时,this 指向全局对象(在浏览器中是 window 对象)。
  • 当函数作为对象的方法调用时,this 指向调用该方法的对象。
       const obj = {
         name: 'John',
         sayHello: function() {
           console.log(`Hello, ${this.name}!`);
         }
       };
    
       obj.sayHello(); // 输出:Hello, John!

        2.使用 callapply 和 bind 方法改变 this

  • 可以使用 callapply 和 bind 方法来显式地指定函数执行时的 this 值。
       function greet() {
         console.log(`Hello, ${this.name}!`);
       }
    
       const person = { name: 'Alice' };
       greet.call(person); // 输出:Hello, Alice!
       greet.apply(person); // 输出:Hello, Alice!
       const boundGreet = greet.bind(person);
       boundGreet(); // 输出:Hello, Alice!
3.参数和返回值

        1.参数

  • 普通函数可以接收任意数量的参数,可以使用参数默认值、剩余参数和扩展运算符等 ES6 特性。
       function add(a = 0, b = 0,...rest) {
         return a + b + rest.reduce((sum, num) => sum + num, 0);
       }
    
       console.log(add(1, 2)); // 3
       console.log(add(1, 2, 3, 4)); // 10

        2.返回值

  • 函数可以返回任何类型的值,包括基本数据类型、对象、函数等。
  • 如果没有明确的 return 语句,函数将返回 undefined
       function createObject() {
         return { name: 'Bob', age: 30 };
       }
    
       const person = createObject();
       console.log(person); // { name: 'Bob', age: 30 }
4.实际应用场景

        1.封装和模块化

  • 普通函数可以用于封装一段可重复使用的代码逻辑,将其封装在一个函数中,提高代码的可维护性和可读性。
  • 例如,可以将一些复杂的业务逻辑封装在一个函数中,然后在不同的地方调用这个函数。
  • 函数还可以用于实现模块化,将相关的功能封装在一个模块中,通过暴露一些公共的函数来与其他模块进行交互。

        2.事件处理

  • 在前端开发中,普通函数经常用于处理 DOM 事件。可以将事件处理函数定义为普通函数,并将其绑定到特定的 DOM 元素上。
    <button id="myButton">Click me</button>
    document.getElementById('myButton').addEventListener('click', function() {
         console.log('Button clicked!');
       });

        3.异步操作

  • 普通函数可以用于处理异步操作,例如使用 setTimeoutfetch 等函数进行异步请求或延迟执行。
       function fetchData() {
         return fetch('https://api.example.com/data')
          .then(response => response.json())
          .then(data => {
             console.log(data);
             return data;
           });
       }
    
       fetchData();
5. 优点和注意事项

        1.优点

  • 灵活性高:可以根据不同的需求定义不同的函数,实现各种复杂的功能。
  • 可重用性:可以在不同的地方调用同一个函数,提高代码的可维护性和可扩展性。
  • 可读性好:通过合理的函数命名和代码结构,可以使代码更加易于理解和维护。

        2.注意事项

  • this 的指向问题:需要注意函数调用方式对 this 的影响,避免出现 this 指向错误的问题。
  • 命名冲突:在大型项目中,需要注意函数命名的唯一性,避免出现命名冲突的问题。
  • 性能问题:过多的函数调用可能会影响性能,特别是在频繁调用的情况下。可以考虑使用优化技术,如缓存函数结果、避免不必要的函数调用等。

3.箭头函数和普通函数的区别

在前端开发中,箭头函数和普通函数有以下一些区别

1.语法形式

1.普通函数:用function关键字定义

function add(a, b) { return a + b; }

2.箭头函数:用=>定义

const add = (a, b) => a + b;
2.this指向

1.普通函数

在普通函数中,this的指向取决于函数的调用方式。它可以指向全局对象、当前对象或者在特定的调用上下文中被绑定到其他对象。

   function Person() {
     this.age = 30;
     this.sayAge = function() {
       console.log(this.age);
     };
   }

   const person = new Person();
   person.sayAge(); // 30
   const sayAgeFunc = person.sayAge;
   sayAgeFunc(); // undefined(在非严格模式下为全局对象的属性值)

2.箭头函数

箭头函数不具有自己的this,它会继承外层上下文的this值。

   function Person() {
     this.age = 30;
     this.sayAge = () => {
       console.log(this.age);
     };
   }

   const person = new Person();
   person.sayAge(); // 30
   const sayAgeFunc = person.sayAge;
   sayAgeFunc(); // 30(继承了外层上下文的`this`)
3.参数和返回值

1.参数

  • 普通函数可以使用参数默认值、剩余参数和扩展运算符等 ES6 特性。
    function add(a = 0, b = 0,...rest) { return a + b + rest.reduce((sum, num) => sum + num, 0); }
  • 箭头函数也支持这些特性,语法更加简洁。
    const add = (a = 0, b = 0,...rest) => a + b + rest.reduce((sum, num) => sum + num, 0);

2.返回值

  • 如果函数体只有一条表达式,可以省略return关键字和大括号,直接返回表达式的值。
    const multiply = (a, b) => a * b;
  • 如果函数体包含多条语句,需要使用大括号并明确使用return语句返回值。
    const complexFunction = (a, b) => { const result = a + b; return result * 2; };
4.构造函数

1.普通函数

  • 可以作为构造函数使用,通过new关键字创建新的对象实例,并在构造函数内部使用this来初始化对象的属性。
    function Person(name, age) { this.name = name; this.age = age; }

2.箭头函数

        不能作为构造函数使用,不能使用new关键字调用箭头函数,否则会抛出错误。

5.原型和方法

1.普通函数

  • 可以在函数的原型上定义方法,这些方法可以被函数创建的对象实例共享。
    function Person() {}; 
    Person.prototype.sayHello = function() { console.log('Hello!'); };

2.箭头函数

  • 通常不用于定义原型方法,因为箭头函数没有自己的this,无法正确地指向对象实例。
6.实际应用场景

1.简洁性和可读性

  • 当函数逻辑简单且需要简洁的语法时,箭头函数是一个很好的选择。例如,在数组的mapfilterreduce等方法中使用箭头函数可以使代码更加简洁易读。
    const numbers = [1, 2, 3, 4, 5]; 
    const doubledNumbers = numbers.map(num => num * 2);

2.this的上下文

  • 如果需要确保函数内部的this指向特定的对象,或者需要在不同的调用上下文中动态地确定this的值,普通函数可能更合适。例如,在事件处理程序中,普通函数可以正确地绑定this到触发事件的元素。
    document.getElementById('button').addEventListener('click', function() { console.log(this.id); });

3.构造函数和原型方法

  1. 当需要创建对象实例并定义可共享的方法时,应该使用普通函数作为构造函数,并在原型上定义方法。

4.

  • 9
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值