Sử dụng jQuery $ (this) với Hàm mũi tên ES6 (từ vựng là liên kết này)


129

Sử dụng các hàm mũi tên ES6 với thisliên kết từ vựng là rất tốt.

Tuy nhiên, tôi đã gặp sự cố cách đây không lâu khi sử dụng nó với liên kết nhấp chuột jQuery điển hình:

class Game {
  foo() {
    self = this;
    this._pads.on('click', function() {
      if (self.go) { $(this).addClass('active'); }
    });
  }
}

Sử dụng một hàm mũi tên để thay thế:

class Game {
  foo() {
    this._pads.on('click', () => {
      if (this.go) { $(this).addClass('active'); }
    });
  }
}

Và sau đó $(this)được chuyển đổi sang kiểu đóng cửa ES5 (self = this).

Có cách nào để Traceur bỏ qua "$ (this)" cho ràng buộc từ vựng không?


đây có vẻ như là một ví dụ hoàn hảo về thời điểm không sử dụng hàm mũi tên vì .on()nó thực sự có thisgiá trị hữu ích cho bạn. Đối với tôi, việc thisđề cập đến mục tiêu sự kiện rõ ràng hơn nhiều so với việc phải vượt qua sự kiện và tìm mục tiêu theo cách thủ công. Tôi chưa chơi nhiều với các hàm mũi tên nhưng có vẻ như sẽ rất khó hiểu khi quay đi quay lại với các hàm ẩn danh.
robisrob

Câu trả lời:


194

Điều này không liên quan gì đến Traceur và tắt một cái gì đó, đây chỉ đơn giản là cách ES6 hoạt động. Đó là chức năng cụ thể mà bạn đang yêu cầu bằng cách sử dụng =>thay vì function () { }.

Nếu bạn muốn viết ES6, bạn cần phải viết ES6 mọi lúc, bạn không thể chuyển vào và chuyển ra khỏi nó trên một số dòng mã nhất định và bạn chắc chắn không thể ngăn chặn hoặc thay đổi cách =>hoạt động. Ngay cả khi bạn có thể, bạn sẽ chỉ gặp một số phiên bản JavaScript kỳ lạ mà chỉ bạn hiểu và sẽ không bao giờ hoạt động chính xác bên ngoài Traceur tùy chỉnh của bạn, đây chắc chắn không phải là điểm của Traceur.

Cách giải quyết vấn đề cụ thể này là không sử dụng thisđể có quyền truy cập vào phần tử được nhấp, mà thay vào đó sử dụng event.currentTarget:

Class Game {
  foo(){
    this._pads.on('click', (event) => {
      if(this.go) {
        $(event.currentTarget).addClass('active');
      }
    });
  }
}

jQuery cung cấp event.currentTargetcụ thể bởi vì, ngay cả trước ES6, không phải lúc nào jQuery cũng có thể áp đặt một thishàm gọi lại (tức là nếu nó được liên kết với một ngữ cảnh khác thông qua bind.


4
Lưu ý, mặc dù nó chỉ phân kỳ cho các .oncuộc gọi được ủy quyền , nhưng thisthực tế là như vậy event.currentTarget.
loganfsmyth 27/12/14

Câu trả lời này có ổn không? Giống như loganfsmyth đã lưu ý, this== event.currentTarget. Không?
Léon Pelletier,

3
@ LéonPelletier Không. thisevent.currentTargetđều giống nhau trừ khi thisbị ràng buộc với phạm vi bao quanh, như với hàm mũi tên ES6.
Mudgar

8
nếu bạn muốn lưu một số mã, bạn cũng có thể hủy cấu trúc nó: ({currentTarget}) => {$ (currentTarget) .addClass ('active')}
Frank

55

Sự kiện ràng buộc

$button.on('click', (e) => {
    var $this = $(e.currentTarget);
    // ... deal with $this
});

Vòng

Array.prototype.forEach.call($items, (el, index, obj) => {
    var $this = $(el);
    // ... deal with $this
});

Tìm kiếm $jQueryElements.each()? jQuery thực sự gửi một số đối số cho mỗi đối tượng nên bạn không cần điều này cả => Đó là$(...).each((index, el) => console.log(el))
jave.web

53

Một trường hợp khác

Câu trả lời hàng đầu là đúng và tôi đã bình chọn nó.

Tuy nhiên, có một trường hợp khác:

$('jquery-selector').each(() => {
    $(this).click();
})

Có thể được sửa thành:

$('jquery-selector').each((index, element) => {
    $(element).click();
})

Đây là một sai lầm lịch sử trong jQuery khi đặt chỉ mục , thay vì phần tử làm đối số đầu tiên:

.each (hàm)

function
Type: Function( Integer index, Element element )
Một hàm để thực thi cho mỗi phần tử được so khớp.

Xem: https://api.jquery.com/each/#each- Chức năng


1
Tương tự cho fucntions như$('jquery-selector').map
Nicholas Siegmundt

Điều này cực kỳ hữu ích đối với tôi để sử dụng trong những thứ như $ ('jquery-selector'). Filter, v.v ... cảm ơn vì đã làm cho nó rõ ràng.
R Jones

8

(Đây là câu trả lời tôi đã viết cho một phiên bản khác của câu hỏi này, trước khi biết rằng nó là bản sao của câu hỏi này. Tôi nghĩ rằng câu trả lời tập hợp thông tin khá rõ ràng nên tôi quyết định thêm nó làm wiki cộng đồng, mặc dù phần lớn nó chỉ khác nhau diễn đạt các câu trả lời khác.)

Bạn không thể. Đó là một nửa điểm của các chức năng mũi tên, chúng đóng lại thisthay vì có hàm riêng được đặt theo cách chúng được gọi. Đối với trường hợp sử dụng trong câu hỏi, nếu bạn muốn thisđặt bởi jQuery khi gọi trình xử lý, trình xử lý sẽ cần phải là một functionhàm.

Nhưng nếu bạn có lý do để sử dụng một mũi tên (có lẽ bạn muốn sử dụng thisnó có ý nghĩa gì bên ngoài mũi tên), bạn có thể sử dụng e.currentTargetthay vì thisnếu muốn:

class Game {
  foo(){
    this._pads.on('click', e => {                   // Note the `e` argument
      if(this.go) {
        $(e.currentTarget).addClass('active');      // Using it
      }
    });
  }
}

Đối tượng currentTargettrên sự kiện giống như những gì jQuery đặt thisthành khi gọi trình xử lý của bạn.


5

Như Meager đã nói trong câu trả lời của mình về cùng câu hỏi này Nếu bạn muốn viết ES6, bạn cần phải viết ES6 mọi lúc ,

vì vậy nếu bạn đang sử dụng hàm arrow của ES6 : (event)=>{}, thì bạn phải sử dụng $(event.currentTarget)thay vì $(this).

bạn cũng có thể sử dụng cách sử dụng currentTarget đẹp hơn và rõ ràng hơn với tư cách là ({currentTarget})=>{},

Class Game {
  foo(){
    this._pads.on('click', ({currentTarget}) => {
      if(this.go) {
        $(currentTarget).addClass('active');
      }
    });
  }
}

ban đầu ý tưởng này đã được bình luận bởi rizzi thẳng thắn trong câu trả lời của @ Meager, và tôi cảm thấy nó hữu ích và tôi nghĩ rằng không phải tất cả mọi người sẽ đọc nhận xét đó vì vậy tôi đã viết nó như một câu trả lời khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.