前端面试-箭头函数

常问面试内容-箭头函数

. 什么是箭头函数?

箭头函数是ES6中引入的一种新的函数语法,它用更简洁的方式书写函数。

基本语法对比

javascript 复制代码
// 传统函数写法
function add(a, b) {
    return a + b;
}

// 箭头函数写法
const add = (a, b) => {
    return a + b;
};

// 更简洁的箭头函数(当只有一条返回语句时)
const add = (a, b) => a + b;

是不是感觉代码简洁了很多?但这只是箭头函数的冰山一角!

2. 箭头函数的基本用法

不同形式的箭头函数

javascript 复制代码
// 1. 没有参数
const sayHello = () => {
    console.log('Hello!');
};

// 2. 一个参数(可以省略括号)
const double = n => n * 2;

// 3. 多个参数
const multiply = (a, b) => a * b;

// 4. 函数体有多条语句
const checkNumber = (num) => {
    if (num > 0) {
        return '正数';
    } else {
        return '非正数';
    }
};

立即执行的箭头函数

javascript 复制代码
// 传统立即执行函数
(function() {
    console.log('立即执行');
})();

// 箭头函数立即执行
(() => {
    console.log('箭头函数立即执行');
})();

3. 箭头函数的核心特性:this绑定

这是箭头函数最重要的特性,也是很多人困惑的地方。

传统函数的this问题

javascript 复制代码
var name = '全局name';

var obj = {
    name: '对象name',
    traditionalFunction: function() {
        console.log(this.name); // this指向obj
    },
    showNameLater: function() {
        setTimeout(function() {
            console.log(this.name); // this指向window!
        }, 1000);
    }
};

obj.traditionalFunction(); // 输出:'对象name'
obj.showNameLater();       // 输出:'全局name'(不是我们想要的!)

showNameLater中,setTimeout里的回调函数有自己的this,指向了全局对象。

箭头函数解决this问题

javascript 复制代码
var name = '全局name';

var obj = {
    name: '对象name',
    showNameLater: function() {
        setTimeout(() => {
            console.log(this.name); // this继承自showNameLater!
        }, 1000);
    }
};

obj.showNameLater(); // 输出:'对象name'(正确!)

箭头函数没有自己的this,它继承外层作用域的this值。

4. 箭头函数的this绑定规则

规则一:继承外层作用域的this

javascript 复制代码
function outer() {
    return () => {
        console.log(this.name);
    };
}

var obj1 = { name: 'obj1' };
var obj2 = { name: 'obj2' };

// 箭头函数在定义时确定this
const arrowFunc = outer.call(obj1);
arrowFunc(); // 输出:'obj1'

// 即使尝试用call改变,也不会生效
arrowFunc.call(obj2); // 仍然输出:'obj1'

规则二:在对象方法中的特殊情况

javascript 复制代码
var name = '全局';

var person = {
    name: '张三',
    
    // 传统方法:this指向调用者
    traditionalMethod: function() {
        console.log(this.name); // 指向person
    },
    
    // 箭头函数:this指向定义时的外层作用域
    arrowMethod: () => {
        console.log(this.name); // 指向全局!
    }
};

person.traditionalMethod(); // 输出:'张三'
person.arrowMethod();       // 输出:'全局'

这是因为对象字面量{}不创建作用域,箭头函数在全局作用域中定义。

5. 箭头函数的其他特性

没有arguments对象

javascript 复制代码
// 传统函数有arguments
function traditional() {
    console.log(arguments);
}

// 箭头函数没有arguments
const arrow = () => {
    console.log(arguments); // 错误!
};

// 可以用剩余参数代替
const arrowWithArgs = (...args) => {
    console.log(args);
};

不能作为构造函数

javascript 复制代码
// 传统函数可以作为构造函数
function Person(name) {
    this.name = name;
}
const person = new Person('张三'); // 正确

// 箭头函数不能作为构造函数
const Animal = (name) => {
    this.name = name;
};
const animal = new Animal('猫'); // 报错!

没有prototype属性

javascript 复制代码
function traditionalFunc() {}
console.log(traditionalFunc.prototype); // 有prototype

const arrowFunc = () => {};
console.log(arrowFunc.prototype);       // undefined

6. 箭头函数的适用场景

适合使用的场景

javascript 复制代码
// 1. 回调函数
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);

// 2. 定时器
setTimeout(() => {
    console.log('1秒后执行');
}, 1000);

// 3. 事件处理(需要小心,可能不适合所有情况)
button.addEventListener('click', () => {
    console.log('按钮被点击');
});

// 4. 在需要固定this的场景
class Counter {
    constructor() {
        this.count = 0;
    }
    
    start() {
        setInterval(() => {
            this.count++; // this正确指向Counter实例
            console.log(this.count);
        }, 1000);
    }
}

不适合使用的场景

javascript 复制代码
// 1. 对象方法(需要动态this)
const obj = {
    values: [1, 2, 3],
    getValue: function(index) {
        return this.values[index]; // 需要this指向obj
    }
};

// 2. 构造函数
// 箭头函数不能用作构造函数

// 3. 需要arguments对象的函数
function traditional() {
    console.log(arguments); // 需要访问arguments
}

8. 总结

特性 传统函数 箭头函数
this绑定 动态绑定 词法作用域绑定
arguments
构造函数 可以 不可以
prototype
语法 相对冗长 简洁

使用建议:

  1. 使用箭头函数:回调函数、需要固定this的场景、简单的单行函数

  2. 使用传统函数:对象方法、构造函数、需要arguments的函数

记住:箭头函数的this在定义时确定,不会改变,这是理解箭头函数的关键

相关推荐
Youyzq3 小时前
前端box-shadow出现兼容性问题如何处理
前端
携欢3 小时前
PortSwigger靶场之将 XSS 存储到onclick带有尖括号和双引号 HTML 编码以及单引号和反斜杠转义的事件中通关秘籍
前端·html·xss
三小河3 小时前
工作中的Ai工具汇总
前端
沐怡旸3 小时前
【算法】725.分割链表--通俗讲解
算法·面试
mapbar_front3 小时前
react项目开发—关于代码架构/规范探讨
前端·react.js
二木一夕3 小时前
Vue 3 的组合式 API和传统选项式 API区别(vue2转vue3,两者差异)
前端
LuckySusu3 小时前
【vue篇】Vue 项目中的静态资源管理:assets vs static 终极指南
前端·vue.js
LuckySusu3 小时前
【vue篇】Vue.delete vs delete:数组删除的“陷阱”与正确姿势
前端·vue.js
LuckySusu3 小时前
【vue篇】Vue 模板编译原理:从 Template 到 DOM 的翻译官
前端·vue.js