每日学习 JavaScript - JavaScript 中的指针函数和普通函数有什么区别?
JavaScript 的指针函数从表面上看可能与常规函数相同,但它们有一些非常重要的区别:
- 语法差异
-
this
值(执行上下文) - 用作方法
- 用作构造函数
-
arguments
捆绑
语法
指针函数和常规函数之间第一个也是最明显的区别是它们的语法。它们不仅看起来不同,而且箭头函数还提供隐式返回简写,并允许省略单个参数周围的括号。
const square = a => a * a;
// Equivalent regular function
function square(a) {
return a * a;
}
执行上下文
在常规函数中,执行上下文(即 的值this
)是动态相对的。这意味着 的值this
取决于函数的调用方式(简单调用、方法调用、间接调用或构造函数调用)。另一方面,箭头函数没有定义自己的执行上下文。这导致箭头函数的this
词法解析(即定义箭头函数的范围)。
function logThis() {
console.log(this);
}
document.addEventListener('click', logThis);
// `this` refers to the document
const logThisArrow = () => {
console.log(this);
};
document.addEventListener('click', logThisArrow);
// `this` refers to the global object
Function.prototype.call()
,Function.prototype.bind()
并且Function.prototype.apply()
也不能与箭头函数一起正常工作。它们的目的是允许方法在不同的范围内执行,但this
不能改变箭头函数的值,因为它是词法解析的。
function logThis() {
console.log(this);
}
logThis.call(42); // Logs: 42
const logThisArrow = () => {
console.log(this);
};
logThisArrow.call(42); // Logs the global object
调用方法
由于指针函数没有定义自己的执行上下文,因此它们不太适合用作直接方法调用。然而,由于Class fields proposal,如果您的环境支持,指针函数可以用作类中的方法。
const obj = {
x: 42,
logThisX: function() {
console.log(this.x, this);
},
logThisXArrow: () => {
console.log(this.x, this);
}
};
obj.logThisX(); // Logs: 42, Object {...}
obj.logThisXArrow(); // Logs: undefined, the global object
构造函数
可以使用new
关键字将常规函数用作构造函数。this
内部指针函数的词法解析的另一个后果是它们不能用作构造函数。使用new
在一个箭头作用的结果TypeError
。
function Foo(bar) {
this.bar = bar;
}
const a = new Foo(42); // Foo {bar: 42}
const Bar = foo => {
this.foo = foo;
};
const b = new Bar(42); // TypeError: Bar is not a constructor
参数
另一个区别是arguments
对象的绑定。与常规函数不同,指针函数没有自己的arguments
对象。绕过此限制的现代替代方案是使用其余参数。
function sum() {
return arguments[0] + arguments[1];
};
sum(4, 6); // 10
const arguments = [1, 2, 3];
const sumArrow = () => {
return arguments[0] + arguments[1];
};
sumArrow(4, 6); // 3 (resolves to 1 + 2)
const sumRest = (...arguments) => {
return arguments[0] + arguments[1];
}
sumRest(4, 6); // 10
其他差异
最后,还有一些其他差异并不那么重要,但值得一提。这些包括缺少prototype
指针函数中的属性,以及yield
关键字可能不会在箭头函数的主体中使用的事实。后者的结果是指针函数不能用作生成器。
上一篇: Go单元测试