Hướng dẫn  Làm thế nào để đổi hai giá trị mà không cần biến phụ trong JavaScript?

Business
Thông thường, hoán đổi giá trị của hai biến cần 3 câu lệnh và 1 biến phụ. Bạn có ngạc nhiên không nếu tôi bảo rằng: trong JavaScript (JS), còn có cách đơn giản hơn như thế nhiều.

1*JNpk3yLpt9f4x_aEO5pa-w.jpeg

Có hai loại hoán đổi. Loại thứ nhất, tạm gọi là loại cổ điển, đó là khi chúng ta hoán đổi hai số cho nhau. Loại thứ hai phức tạp hơn: hoán đổi hai biến có kiểu dữ liệu bất kì (string, float, object, v.v…)
----
Mục tiêu: hoán đổi giá trị của 2 biến a và b (kiểu bất kỳ).
Hiển nhiên, chúng ta thấy xuất hiện một biến mới, tạm lưu giá trị của a trong quá trình hoán đổi. Vậy không cần thằng c này có được không? Được, được chứ!
----
Đối với số nguyên
Bắt đầu với thử thách đầu tiên: số nguyên
DÙNG TOÁN TỬ TOÁN HỌC
Hoặc viết gọn là:
DÙNG TOÁN TỬ XOR
Bởi đây là các số nguyên, chúng ta có thể khéo léo dùng toán tử đảo bit là XOR trong trường hợp này:
Hoặc viết gọn là:
Đây còn được gọi là Thuật toán hoán đổi dùng XOR. Nguyên lý của nó được mô tả trong bài viết sau (ND: click để xem – Wikipedia).
VÀI MẸO HAY HO KHÁC
Hoán đổi trong một dòng
a = b + (b=a, 0)
Phương án này không cần biến phụ, không dùng mảng, chỉ thêm thắt có một xíu vậy thôi, và nó chạy rất nhanh. Thực tế đôi khi nó còn nhanh hơn cách dùng biến phụ nếu chạy trên một vài nền tảng. Nó đúng với mọi loại số, không bao giờ tràn bộ nhớ, và cân luôn mấy trường hợp đặc biệt chẳng hạn Infinity hay NaN.
(ND: Nếu hoán đổi hai biến kiểu string, chỉ cần thay đổi số 0 thành “”).
Nó chạy cụ thể như sau:
  1. (b=a, 0): gán giá trị ban đầu của a cho b, trả về số 0. (ND: Bạn đọc nào chưa hiểu rõ cái này, xem thêm tài liệu tại đây).
  2. a = b + 0: gán giá trị b (ban đầu) + 0 cho a, tức gán a = b
Cách hoán đổi khác, cũng một dòng
Hoán đổi một dòng, dùng XOR
a = a^b^(b^=(a^b))
----
Lời giải dùng được với MỌI KIỂU DỮ LIỆU
Nhiệm vụ thứ hai khó nhai hơn: đổi giá trị 2 biến bất kỳ
PHƯƠNG PHÁP CỔ ĐIỂN TRONG MỘT DÒNG LỆNH
Mẹo này sử dụng mảng để hoán đổi biến. Đọc qua dòng lệnh và thử suy nghĩ chút nhé:
a = [b, b=a][0];
Có vài điều đáng nói ở đây. Nếu bạn chưa hiểu câu lệnh này chạy thế nào, hãy đọc phần giải thích này:
  1. Khởi tạo một mảng với phần tử đầu là b, phần tử số 2 là b
  2. Gán b = a ngay khi mảng được khởi tạo
  3. Gán giá trị của phần tử đầu tiên trong mảng, tức giá trị của b ban đầu, cho a.
(ND: Đoạn trên đây OP chắc chắn đã nhầm một chút, mình đã tự dịch theo ý của mình)
PHƯƠNG PHÁP HOÁN ĐỔI KHÁC
Với ES6, ta có thể dùng hàm rút gọn:
b = (a=>a)(a,a=b);
Hoặc nếu trong ES5, câu lệnh này được viết là:
b = (function(a){ return a })(a,a=b);
(ND: Hàm dạng này gọi là self-executing function. Xem thêm tại đây)
PHƯƠNG PHÁP DÙNG CHO ES6 TRỞ LÊN
Kể từ ES6, bạn đã có thể hoán đổi hai biến một cách đẹp trai hơn. Chỉ đơn giản gán hai mảng như sau:
[a, b] = [b, a]
(ND: Đây là destructuring assignment, xem thêm tại đây)
[Tác giả: Александр Майоров
Ngày xuất bản 18/06/2016
Link bài viết gốc: https://link.medium.com/A3lZ79skl4
Dịch: Bùi Thanh Lâm]
 
Trả lời

NgoHungCuong


Junior Moderator
Thành viên BQT
Mục tiêu là viết code dễ hiểu chứ không phải viết code khôn ngoan. Mình nhớ là đã đọc được câu này ở đâu đó.
 

rattonwing

Gà con
biết hết hay hơn là hết biết gì thêm. Cảm ơn tác giả nhiều! Tiếp tục phát huy nhé!
 

dammage

Rìu Chiến
cách truyền thống dễ đọc dễ hiểu, trong khi ưu điểm của bớt 1 biến trung gian trong javascript là gì vậy bạn