前端JavaScript篇之箭头函数与普通函数的区别、如果new一个箭头函数的会怎么样、箭头函数的this指向哪⾥?

目录

  • 箭头函数与普通函数的区别
  • 如果new一个箭头函数的会怎么样
  • 箭头函数的this指向哪⾥?


箭头函数与普通函数的区别

箭头函数和普通函数是 JavaScript 中的两种不同的函数形式,它们在语法和行为上存在一些区别。

箭头函数的主要特点是:

  1. 箭头函数使用箭头(=>)来定义函数;
  2. 箭头函数没有自己的this值,它会继承外部作用域的this值;
  3. 箭头函数没有arguments对象,但可以使用剩余参数(rest parameters)来获取函数的参数;
  4. 箭头函数不能用作构造函数,不能使用new关键字;
  5. 箭头函数没有prototype属性。

普通函数则更为传统,具有以下特点:

  1. 普通函数使用function关键字来定义函数;
  2. 普通函数有自己的this值,它的指向根据函数的调用方式和上下文来确定;
  3. 普通函数可以通过arguments对象来获取函数的参数;
  4. 普通函数可以用作构造函数,使用new关键字进行实例化;
  5. 普通函数有prototype属性,可以添加方法和属性到函数的原型上。

箭头函数与普通函数在语法和行为上有几个重要的区别。

  1. 语法简洁性:箭头函数使用=>语法,可以更简洁地定义函数。它省略了function关键字、花括号以及return关键字(在某些情况下)。
// 箭头函数
const arrowFunc = () => console.log('Hello, Arrow Function!')

// 普通函数
function regularFunc() {
  console.log('Hello, Regular Function!')
}

arrowFunc() // 输出:Hello, Arrow Function!
regularFunc() // 输出:Hello, Regular Function!

  1. this指向:箭头函数没有自己的this值,而是继承了外部作用域的this值。普通函数的this指向调用它的对象或者全局对象(在严格模式下是undefined)。
// 对象内部定义箭头函数和普通函数
const obj = {
  name: 'John',
  arrowFunc: () => console.log(this.name),
  regularFunc: function () {
    console.log(this.name)
  }
}

obj.arrowFunc() // 输出:undefined(箭头函数继承外部作用域的this,此处为全局对象)
obj.regularFunc() // 输出:John(普通函数的this指向调用它的对象,此处为obj)

  1. arguments参数:箭头函数没有自己的arguments对象,而是继承了外部作用域的arguments对象。普通函数可以使用arguments对象来获取所有传递的参数。
// 箭头函数和普通函数使用arguments
const arrowFunc = () => console.log(arguments[0])
function regularFunc() {
  console.log(arguments[0])
}

arrowFunc(1) // 输出:1(箭头函数继承外部作用域的arguments,此处为全局对象的arguments)
regularFunc(2) // 输出:2(普通函数使用自己的arguments)

  1. 构造函数能力:箭头函数没有prototype属性,因此不能被用作构造函数来创建实例对象。普通函数可以通过new关键字创建实例对象。
// 箭头函数和普通函数作为构造函数
const ArrowConstructor = () => {}
function RegularConstructor() {}

const arrowInstance = new ArrowConstructor() // 抛出TypeError异常(箭头函数不能用作构造函数)
const regularInstance = new RegularConstructor() // 创建一个RegularConstructor的实例对象

箭头函数与普通函数在语法和行为上有一些区别,包括简洁性、this指向、arguments参数和构造函数能力等方面。需要根据具体的使用场景选择合适的函数类型。

需要注意的是,箭头函数的this值确实无法通过call()apply()bind()方法来改变,它始终使用在定义时所处的作用域的this值。

这与普通函数有所不同,普通函数的this值在运行时是可以通过这些方法来显式地改变的。call()apply()bind()方法允许我们在调用函数时指定函数内部的this值。

但是,箭头函数不具备自己的this绑定,它会继承外部作用域的this值,无法被改变。这也是箭头函数在处理对象方法时的一个重要区别,因为对象方法中的普通函数会将this绑定到调用该方法的对象上,而箭头函数则会继承外部作用域的this值。

以下是一个示例来说明箭头函数无法通过call()方法改变this值的情况:

const obj = {
  name: 'John',
  sayHello: function () {
    console.log('Hello, ' + this.name)
  },
  sayHi: () => {
    console.log('Hi, ' + this.name)
  }
}

const otherObj = {
  name: 'Jane'
}

obj.sayHello.call(otherObj) // 输出:Hello, Jane
obj.sayHi.call(otherObj) // 输出:Hi, undefined

我们尝试使用call()方法将obj.sayHelloobj.sayHi中的this值改变为otherObj。在普通函数sayHello中,this值成功地被改变为otherObj,输出了Hello, Jane。但是,在箭头函数sayHi中,this值无法被改变,仍然是继承自外部作用域的this值,因此输出了Hi, undefined

如果new一个箭头函数的会怎么样

箭头函数

  • 箭头函数是一种特殊的函数语法,它可以更简洁地编写函数。
  • 箭头函数没有自己的this值,它继承了外部作用域的this值。
  • 箭头函数没有prototype属性,因此不能被用作构造函数。

在JavaScript中,使用new关键字创建一个箭头函数会导致错误。箭头函数是一种特殊的函数语法,它没有自己的this值和prototype属性。因此,无法使用new关键字来实例化一个箭头函数。

实际上,箭头函数不能被使用new关键字来实例化。当我们尝试使用new关键字创建一个箭头函数的实例时,会抛出一个错误。

案例参考效果:
假设我们有一个箭头函数 const greet = () => console.log('Hello');,如果我们尝试使用new关键字实例化这个箭头函数,就会抛出错误。

案例代码思路和描述:

// 定义一个箭头函数
const greet = () => console.log('Hello')

// 使用new关键字实例化箭头函数
const instance = new greet() // 抛出错误

// 错误信息:greet is not a constructor

前端JavaScript篇之箭头函数与普通函数的区别、如果new一个箭头函数的会怎么样、箭头函数的this指向哪⾥?_第1张图片

上述代码中,我们首先定义了一个箭头函数 greet,它打印出 “Hello”。然后,我们尝试使用new关键字创建一个greet的实例,并将其赋值给变量instance。但由于箭头函数没有构造函数的能力,所以创建实例的操作会抛出一个错误。错误信息提示我们 “greet is not a constructor”,即箭头函数不是一个构造函数。

因此,箭头函数不能被使用new关键字来实例化,这会导致错误。

箭头函数的this指向哪⾥?

当使用箭头函数时,它的this指向是由函数定义时所处的作用域决定的。具体来说,箭头函数继承了外部作用域的this值,而不是在运行时动态确定。

为了更好地理解箭头函数的this指向,让我们来看一个具体的案例。

案例代码如下所示:

const obj = {
  name: 'John',
  regularFunction: function () {
    console.log('Regular function:', this.name)
  },
  arrowFunction: () => {
    console.log('Arrow function:', this.name)
  }
}

const otherObj = {
  name: 'Jane'
}

obj.regularFunction() // 输出:Regular function: John
obj.arrowFunction() // 输出:Arrow function: undefined

const regularFunc = obj.regularFunction
regularFunc() // 输出:Regular function: undefined

const arrowFunc = obj.arrowFunction
arrowFunc() // 输出:Arrow function: undefined

在上述代码中,我们定义了一个对象obj,其中包含了一个普通函数regularFunction和一个箭头函数arrowFunction。我们还创建了一个名为otherObj的对象,它有一个name属性。

首先,我们调用obj.regularFunction(),这是通过对象的方法来调用普通函数。在普通函数regularFunction内部,this指向调用该方法的对象,即obj,因此输出了Regular function: John

接下来,我们调用obj.arrowFunction(),这是通过对象的方法来调用箭头函数。由于箭头函数继承了外部作用域的this值,它的this指向的是箭头函数定义时所处的作用域,即全局作用域。在全局作用域下,没有定义name属性,因此输出了Arrow function: undefined

然后,我们将obj.regularFunction赋值给变量regularFunc,并调用regularFunc()。在这种情况下,我们将普通函数从对象中提取出来并作为独立的函数调用。由于没有指定调用的对象,this的值将是全局对象(在非严格模式下是window对象),因此输出了Regular function: undefined

最后,我们将obj.arrowFunction赋值给变量arrowFunc,并调用arrowFunc()。与前面的情况类似,箭头函数的this值在定义时已经确定为全局作用域的this,因此输出了Arrow function: undefined

总结来说,箭头函数的this指向是静态的,由函数定义时所处的作用域决定。它继承了外部作用域的this值,无法通过call()apply()bind()方法来改变。

持续学习总结记录中,回顾一下上面的内容:
箭头函数的主要特点是:
箭头函数使用箭头(=>)来定义函数;
箭头函数没有自己的this值,它会继承外部作用域的this值;
箭头函数没有arguments对象,但可以使用剩余参数(rest parameters)来获取函数的参数;
箭头函数不能用作构造函数,不能使用new关键字;
箭头函数没有prototype属性。
普通函数则更为传统,具有以下特点:
普通函数使用function关键字来定义函数;
普通函数有自己的this值,它的指向根据函数的调用方式和上下文来确定;
普通函数可以通过arguments对象来获取函数的参数;
普通函数可以用作构造函数,使用new关键字进行实例化;
普通函数有prototype属性,可以添加方法和属性到函数的原型上。

箭头函数不能被使用new关键字来实例化,这会导致错误。

箭头函数的this指向是静态的,由函数定义时所处的作用域决定。它继承了外部作用域的this值,无法通过call()、apply()或bind()方法来改变。

你可能感兴趣的:(JavaScript,知识点,javascript,前端,开发语言)