'Các Hàm Mũi tên' và 'Các Hàm' có thể tương đương / hoán đổi cho nhau không?

575
Felix Kling 2015-12-19 07:58.

Các hàm mũi tên trong ES2015 cung cấp một cú pháp ngắn gọn hơn.

  • Bây giờ tôi có thể thay thế tất cả các khai báo / biểu thức hàm của mình bằng các hàm mũi tên không?
  • Tôi phải chú ý điều gì?

Ví dụ:

Hàm tạo

function User(name) {
  this.name = name;
}

// vs

const User = name => {
  this.name = name;
};

Phương pháp nguyên mẫu

User.prototype.getName = function() {
  return this.name;
};

// vs

User.prototype.getName = () => this.name;

Phương thức đối tượng (theo nghĩa đen)

const obj = {
  getName: function() {
    // ...
  }
};

// vs

const obj = {
  getName: () => {
    // ...
  }
};

Gọi lại

setTimeout(function() {
  // ...
}, 500);

// vs

setTimeout(() => {
  // ...
}, 500);

Các hàm đa dạng

function sum() {
  let args = [].slice.call(arguments);
  // ...
}

// vs
const sum = (...args) => {
  // ...
};

3 answers

817
Felix Kling 2015-12-19 07:58.

tl; dr: Không! Hàm mũi tên và khai báo / biểu thức hàm không tương đương và không thể thay thế một cách mù quáng.
Nếu chức năng bạn muốn thay thế không không sử dụng this, argumentsvà không được gọi với new, sau đó có.


Như vậy thường xuyên: nó phụ thuộc . Các hàm mũi tên có hành vi khác với khai báo / biểu thức hàm, vì vậy trước tiên hãy xem xét sự khác biệt:

1. Lexical thisarguments

Các hàm mũi tên không có ràng buộc thishoặc riêng của chúng arguments. Thay vào đó, những định danh đó được giải quyết trong phạm vi từ vựng giống như bất kỳ biến nào khác. Điều đó có nghĩa là bên trong một hàm mũi tên thisargumentstham chiếu đến các giá trị của thisargumentstrong môi trường, hàm mũi tên được xác định trong (nghĩa là "bên ngoài" hàm mũi tên):

// Example using a function expression
function createObject() {
  console.log('Inside `createObject`:', this.foo);
  return {
    foo: 42,
    bar: function() {
      console.log('Inside `bar`:', this.foo);
    },
  };
}

createObject.call({foo: 21}).bar(); // override `this` inside createObject

// Example using a arrow function
function createObject() {
  console.log('Inside `createObject`:', this.foo);
  return {
    foo: 42,
    bar: () => console.log('Inside `bar`:', this.foo),
  };
}

createObject.call({foo: 21}).bar(); // override `this` inside createObject

Trong trường hợp biểu thức hàm, thistham chiếu đến đối tượng được tạo bên trong createObject. Trong trường hợp mũi tên chức năng, thisđề cập đến thiscủa createObjectchính nó.

Điều này làm cho các hàm mũi tên hữu ích nếu bạn cần truy cập vào thismôi trường hiện tại:

// currently common pattern
var that = this;
getData(function(data) {
  that.data = data;
});

// better alternative with arrow functions
getData(data => {
  this.data = data;
});

Lưu ý rằng điều này cũng có nghĩa là không thể đặt một hàm mũi tên thisbằng .bindhoặc .call.

Nếu bạn không quen thuộc lắm this, hãy cân nhắc đọc

2. Không thể gọi các hàm mũi tên với new

ES2015 phân biệt giữa các hàm có thể gọi và các hàm có thể xây dựng . Nếu một hàm có thể xây dựng, nó có thể được gọi với new, tức là new User(). Nếu một hàm có thể gọi được, nó có thể được gọi mà không cần new(tức là gọi hàm bình thường).

Các hàm được tạo thông qua khai báo / biểu thức hàm đều có thể xây dựng và có thể gọi.
Các hàm (và phương thức) mũi tên chỉ có thể gọi được. classhàm tạo chỉ có thể xây dựng.

Nếu bạn đang cố gắng gọi một hàm không thể gọi hoặc để tạo một hàm không thể xây dựng, bạn sẽ gặp lỗi thời gian chạy.


Biết được điều này, chúng ta có thể phát biểu như sau.

Có thể thay thế:

  • Các hàm không sử dụng thishoặc arguments.
  • Các hàm được sử dụng với .bind(this)

Không thể thay thế:

  • Hàm tạo
  • Hàm / phương thức được thêm vào nguyên mẫu (vì chúng thường sử dụng this)
  • Các hàm đa dạng (nếu chúng sử dụng arguments(xem bên dưới))

Hãy xem xét kỹ hơn điều này bằng cách sử dụng các ví dụ của bạn:

Hàm tạo

Điều này sẽ không hoạt động vì không thể gọi các hàm mũi tên với new. Tiếp tục sử dụng khai báo / biểu thức hoặc sử dụng hàm class.

Phương pháp nguyên mẫu

Nhiều khả năng là không, vì các phương thức nguyên mẫu thường sử dụng thisđể truy cập cá thể. Nếu họ không sử dụng this, thì bạn có thể thay thế nó. Tuy nhiên, nếu bạn chủ yếu quan tâm đến cú pháp ngắn gọn, hãy sử dụng classcú pháp phương thức ngắn gọn của nó:

class User {
  constructor(name) {
    this.name = name;
  }
  
  getName() {
    return this.name;
  }
}

Phương thức đối tượng

Tương tự như vậy đối với các phương thức trong một đối tượng theo nghĩa đen. Nếu phương thức muốn tham chiếu đến chính đối tượng thông qua this, hãy tiếp tục sử dụng biểu thức hàm hoặc sử dụng cú pháp phương thức mới:

const obj = {
  getName() {
    // ...
  },
};

Gọi lại

Nó phụ thuộc. Bạn chắc chắn nên thay thế nó nếu bạn đang đặt răng cưa bên ngoài thishoặc đang sử dụng .bind(this):

// old
setTimeout(function() {
  // ...
}.bind(this), 500);

// new
setTimeout(() => {
  // ...
}, 500);

Nhưng: Nếu mã gọi lệnh gọi lại đặt rõ ràng thisthành một giá trị cụ thể, như thường xảy ra với các trình xử lý sự kiện, đặc biệt là với jQuery và lệnh gọi lại sử dụng this(hoặc arguments), bạn không thể sử dụng hàm mũi tên!

Các hàm đa dạng

Vì các hàm mũi tên không có hàm riêng argumentsnên bạn không thể đơn giản thay thế chúng bằng hàm mũi tên. Tuy nhiên, ES2015 giới thiệu một giải pháp thay thế để sử dụng arguments: tham số còn lại .

// old
function sum() {
  let args = [].slice.call(arguments);
  // ...
}

// new
const sum = (...args) => {
  // ...
};

Câu hỏi liên quan:

Các tài nguyên khác:

17
Ashutosh 2020-01-10 10:22.

Chức năng mũi tên => tính năng ES6 tốt nhất cho đến nay. Chúng là một bổ sung cực kỳ mạnh mẽ cho ES6 mà tôi sử dụng liên tục.

Chờ đã, bạn không thể sử dụng hàm mũi tên ở mọi nơi trong mã của mình, nó sẽ không hoạt động trong mọi trường hợp như thiskhông sử dụng được hàm mũi tên. Không nghi ngờ gì nữa, chức năng mũi tên là một bổ sung tuyệt vời nó mang lại sự đơn giản cho mã.

Nhưng bạn không thể sử dụng hàm mũi tên khi cần có ngữ cảnh động: xác định phương thức, tạo đối tượng bằng hàm tạo, lấy mục tiêu từ hàm này khi xử lý sự kiện.

Hàm mũi tên KHÔNG nên được sử dụng vì:

  1. Họ không có this

    Nó sử dụng "phạm vi từ vựng" để tìm ra giá trị của " this" nên là bao nhiêu. Trong phạm vi từ vựng đơn giản, nó sử dụng “ this” từ bên trong phần thân của hàm.

  2. Họ không có arguments

    Hàm mũi tên không có argumentsđối tượng. Nhưng chức năng tương tự có thể đạt được bằng cách sử dụng các tham số nghỉ.

    let sum = (...args) => args.reduce((x, y) => x + y, 0) sum(3, 3, 1) // output - 7 `

  3. Chúng không thể được sử dụng với new

    Các hàm mũi tên không thể là hàm tạo vì chúng không có thuộc tính nguyên mẫu.

Khi nào sử dụng chức năng mũi tên và khi nào không:

  1. Không sử dụng để thêm chức năng như một thuộc tính trong đối tượng theo nghĩa đen vì chúng tôi không thể truy cập điều này.
  2. Biểu thức hàm là tốt nhất cho các phương thức đối tượng. Mũi tên chức năng là tốt nhất cho callbacks hoặc các phương pháp như map, reducehoặc forEach.
  3. Sử dụng khai báo hàm cho các hàm bạn sẽ gọi theo tên (vì chúng được nâng lên).
  4. Sử dụng các hàm mũi tên cho các lệnh gọi lại (vì chúng có xu hướng ngắn hơn).
2
toddmo 2020-05-16 15:56.

Để sử dụng các hàm mũi tên với function.prototype.call, tôi đã tạo một hàm trợ giúp trên nguyên mẫu đối tượng:

  // Using
  // @func = function() {use this here} or This => {use This here}
  using(func) {
    return func.call(this, this);
  }

sử dụng

  var obj = {f:3, a:2}
  .using(This => This.f + This.a) // 5

Biên tập

Bạn không CẦN người trợ giúp. Bạn có thể làm:

var obj = {f:3, a:2}
(This => This.f + This.a).call(undefined, obj); // 5

Related questions

MORE COOL STUFF

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett đã bất chấp những lời khuyên hẹn hò điển hình khi cô gặp chồng mình.

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Michael Sheen là một diễn viên phi lợi nhuận nhưng chính xác thì điều đó có nghĩa là gì?

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Ngôi sao của Hallmark Colin Egglesfield chia sẻ về những cuộc gặp gỡ với người hâm mộ ly kỳ tại RomaDrama Live! cộng với chương trình INSPIRE của anh ấy tại đại hội.

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Bạn sẽ phải phủi sạch đầu đĩa Blu-ray hoặc DVD để xem tại sao Northern Exposure trở thành một trong những chương trình nổi tiếng nhất của thập niên 90.

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

8 công dụng tuyệt vời của Baking Soda và Giấm

8 công dụng tuyệt vời của Baking Soda và Giấm

Bạn biết đấy, hai sản phẩm này là nguồn điện để làm sạch, riêng chúng. Nhưng cùng với nhau, chúng có một loạt công dụng hoàn toàn khác.

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Thủy điện rất cần thiết cho lưới điện của Hoa Kỳ, nhưng nó chỉ tạo ra năng lượng khi có nước di chuyển. Bao nhiêu nhà máy thủy điện có thể gặp nguy hiểm khi các hồ và sông cạn kiệt?

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Tóc tỉa từ các tiệm và các khoản quyên góp cá nhân có thể được tái sử dụng như những tấm thảm thấm dầu và giúp bảo vệ môi trường.

Đây là Tổng thống Trump đe dọa 'trợ cấp' xe điện của GM vì đóng cửa nhà máy

Đây là Tổng thống Trump đe dọa 'trợ cấp' xe điện của GM vì đóng cửa nhà máy

Trump và Giám đốc điều hành GM Mary Barra vào năm 2017. Kể từ khi tin tức nổ ra ngày hôm qua rằng General Motors đang cắt giảm việc làm ở Bắc Mỹ để chuẩn bị cho tương lai điện / xe tự hành / khủng khiếp có thể xảy ra của chúng tôi, gần như tất cả mọi người đã tự hỏi: Tổng thống Trump, người đã vận động tranh cử trên một nền tảng sẽ như thế nào của việc mang lại và duy trì việc làm ô tô của Mỹ, phải nói gì về điều này? Bây giờ chúng ta biết.

Bản vá lỗi tiếp theo của Fallout 76 sẽ mang lại một số bản sửa lỗi cần thiết

Bản vá lỗi tiếp theo của Fallout 76 sẽ mang lại một số bản sửa lỗi cần thiết

Bethesda cho biết ngày hôm nay trên Reddit, Fallout 76 sẽ có một bản vá lớn khác vào ngày 4 tháng 12, sẽ bắt đầu cố gắng khắc phục một số vấn đề lớn hơn của trò chơi. Ngoài ra, công ty cho biết họ có kế hoạch giao tiếp nhiều hơn trong tương lai về những gì nhóm Fallout 76 đang làm việc và khi nào các bản cập nhật mới cho trò chơi sẽ ra mắt.

Mạng lưới bệnh viện Công giáo sẽ không cho phép nhân viên phá thai tại phòng khám ngoài giờ làm việc

Mạng lưới bệnh viện Công giáo sẽ không cho phép nhân viên phá thai tại phòng khám ngoài giờ làm việc

Bạn có biết rằng một trong sáu bệnh nhân ở bệnh viện ở Hoa Kỳ được điều trị tại một cơ sở Công giáo? Và bạn có biết rằng quyền sở hữu của Công giáo hạn chế sâu sắc việc thiết lập các thủ tục y tế có thể được thực hiện trong các bệnh viện này, rõ ràng nhất là khi nói đến chăm sóc sức khỏe sinh sản? Bây giờ NPR báo cáo rằng sự gia tăng của các bệnh viện thuộc Công giáo đang gây khó khăn hơn cho các bác sĩ — những người bị cấm bởi các quy định do Hoa Kỳ viết.

Khói từ đám cháy rừng ở California đã đến tận thành phố New York

Khói từ đám cháy rừng ở California đã đến tận thành phố New York

Đường chân trời San Francisco bị che khuất bởi khói và khói mù do cháy rừng phía sau Đảo Alcatraz, Thứ Tư, ngày 14 tháng 11 năm 2018, ở San Francisco.

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Rothschild's luggage got lost, but luckily she has an incredible closet to shop: Sister Paris Hilton's!

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa. Từ Hollywood đến New York và mọi nơi ở giữa, hãy xem các ngôi sao yêu thích của bạn đang làm gì!

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

Các nhà điều tra đang xem xét liệu nhóm và nghi phạm có biết nhau trước vụ tấn công hay không

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Vụ kiện, nêu tên một số học khu, lập luận rằng dự luật "Không nói đồng tính" được ban hành gần đây của Florida "có hiệu quả im lặng và xóa bỏ học sinh và gia đình LGBTQ +"

Đường băng hạ cánh

Đường băng hạ cánh

Cuối hè đầu thu là mùa hoài niệm. Những chiếc đèn đường chiếu ánh sáng của chúng qua những con đường đẫm mưa, và những chiếc lá dưới chân - màu đỏ cam tắt trong bóng chạng vạng - là lời nhắc nhở về những ngày đã qua.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Vào năm 2021, tôi khuyến khích bạn suy nghĩ lại mọi thứ bạn biết về khách hàng mà bạn phục vụ và những câu chuyện bạn kể cho họ. Lùi lại.

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Vào ngày sinh nhật thứ 9 của Felix The Cat, tôi nhớ về một trong những mất mát lớn nhất trong cuộc đời trưởng thành của tôi - Sophie của tôi vào năm 2013. Tôi đã viết bài luận này và chia sẻ nó trên nền tảng này một thời gian ngắn vào năm 2013.

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Tôi ghét từ "tàu đắm". Mọi người cảm thấy thoải mái trong la bàn đạo đức của riêng mình, và khi làm như vậy, họ thấy mình vượt qua sự phán xét.

Language