Nếu bởi "sẽ không được thực thi", bạn có nghĩa là "sẽ không làm gì khi được gọi nhiều lần", bạn có thể tạo một bao đóng:
var something = (function() {
var executed = false;
return function() {
if (!executed) {
executed = true;
// do something
}
};
})();
something(); // "do something" happens
something(); // nothing happens
Trả lời nhận xét của @Vladloffe (hiện đã bị xóa): Với một biến toàn cục, mã khác có thể đặt lại giá trị của cờ "đã thực thi" (bất kỳ tên nào bạn chọn cho nó). Với việc đóng, các mã khác không có cách nào để làm điều đó, dù vô tình hay cố ý.
Như các câu trả lời khác ở đây chỉ ra, một số thư viện (chẳng hạn như Dấu gạch dưới và Ramda ) có một hàm tiện ích nhỏ (thường được đặt tên là once()
[*] ) chấp nhận một hàm làm đối số và trả về một hàm khác gọi hàm được cung cấp chính xác một lần, bất kể cách thức nhiều lần hàm trả về được gọi. Hàm trả về cũng lưu trữ giá trị được trả về đầu tiên bởi hàm được cung cấp và trả về giá trị đó trong các lần gọi tiếp theo.
Tuy nhiên, nếu bạn không sử dụng thư viện của bên thứ ba như vậy, nhưng vẫn muốn có một chức năng tiện ích như vậy (thay vì giải pháp nonce mà tôi đã đưa ra ở trên), nó đủ dễ dàng để thực hiện. Phiên bản đẹp nhất mà tôi đã thấy là phiên bản này được đăng bởi David Walsh :
function once(fn, context) {
var result;
return function() {
if (fn) {
result = fn.apply(context || this, arguments);
fn = null;
}
return result;
};
}
Tôi sẽ có xu hướng thay đổi fn = null;
thành fn = context = null;
. Không có lý do gì cho việc đóng cửa để duy trì một tham chiếu đến context
một lần fn
đã được gọi.
[*] Tuy nhiên, hãy lưu ý rằng các thư viện khác, chẳng hạn như phần mở rộng Drupal này cho jQuery , có thể có một hàm có tên once()
thực hiện một cái gì đó khá khác biệt.