11/08/2018, 20:05

[ES6] Một hành xử lạ mà không lạ của arrow function

Nếu chưa biết về arrow function trong ES6, mời các bạn xem qua bài viết này Với ý định viết một hàm hook vào chỗ trước khi save của mongoose, tôi đã sử dụng arrow function như thế này: UserSchema.pre('save', (next) => { let now = new Date(); this.updateAt = now; if ...

Nếu chưa biết về arrow function trong ES6, mời các bạn xem qua bài viết này

Với ý định viết một hàm hook vào chỗ trước khi save của mongoose, tôi đã sử dụng arrow function như thế này:

UserSchema.pre('save', (next) => {
  let now = new Date();
  this.updateAt = now;
  if (!this.createdAt) {
    this.createdAt = now;
  }

  next();
});

Nhưng thật không may, khi chạy lỗi bắn ầm ầm :smile:

TypeError: Cannot set property 'updateAt' of undefined

Thật kỳ quái, arrow function sinh ra để giải quyết vấn đề ngữ cảnh gọi hàm cơ mà, undefined là undefined thế quái nào nhỉ? Hừm, hãy xem xét kỹ một tí. Đoạn code trên có thể hiểu (một cách gần đúng) như thế này

var beforeSave = function(next) {

  var now = new Date();
  this.updateAt = now;
  if (!this.createdAt) {
    this.createdAt = now;
  }

  next();

}.bind(this); // (1)

UserSchema.pre('save', beforeSave);

Như vậy là ngữ cảnh (this) đã được gán từ vị trí (1) và hoàn toàn nằm ngoài context của UserSchema của chúng ta, và được máy chạy hiểu là undefined. Mà oái oăm hơn nữa là context của arrow function không thể override được. Vậy nên cũng dễ hiểu là chúng ta đã bị lạc ngay từ vị trí (1).

Vậy, kết luận, là arrow function chỉ nên được dùng làm thủ tục con trong thân của một phương thức nào đó. Hết :smile:

0