欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

每日学习 JavaScript - JavaScript 中的指针函数和普通函数有什么区别?

最编程 2024-07-05 18:33:10
...

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关键字可能不会在箭头函数的主体中使用的事实。后者的结果是指针函数不能用作生成器。