Javascript có giới hạn đệ quy không?

Đệ quy là một kỹ thuật giải quyết vấn đề trong lập trình. Trong bài viết này, bạn sẽ học cách sử dụng các hàm đệ quy trong JavaScript

Hàm đệ quy là gì?

Hàm đệ quy là một hàm gọi chính nó ở đâu đó trong phần thân của hàm. Dưới đây là một ví dụ cơ bản về hàm đệ quy

function recursiveFunc() {
  // some code here.. 
  recursiveFunc()
}

Như bạn có thể thấy, hàm

function recursiveFunc() {
  if(base condition) {
    // stops recursion if condition is met
  }
  // else recursion continues
  recurse();
}
7 gọi chính nó trong phần thân của hàm. Nó sẽ tự gọi lại cho đến khi đạt được đầu ra mong muốn

Vì vậy, làm thế nào để bạn nói với chức năng khi ngừng gọi chính nó?

Ba phần của hàm đệ quy

Mỗi khi bạn viết một hàm đệ quy, phải có ba phần tử. họ đang

  • Định nghĩa chức năng
  • điều kiện cơ sở
  • Cuộc gọi đệ quy

Khi thiếu ba yếu tố này, hàm đệ quy của bạn sẽ không hoạt động như bạn mong đợi. Chúng ta hãy xem xét kỹ hơn từng cái một

Cách xác định hàm đệ quy

Bạn xác định một hàm đệ quy giống như cách bạn xác định các hàm JavaScript thông thường

function recursiveFunc() {
  // some code here...
} 

Điều khác biệt giữa các hàm đệ quy với các hàm JavaScript thông thường là điều kiện cơ sở và lệnh gọi đệ quy

một điều kiện cơ bản là gì?

Khi sử dụng hàm đệ quy, điều kiện cơ bản là điều kiện cho phép hàm biết khi nào nên ngừng gọi chính nó. Khi điều kiện cơ sở được đáp ứng, đệ quy kết thúc

function recursiveFunc() {
  if(base condition) {
    // stops recursion if condition is met
  }
  // else recursion continues
  recurse();
}

Tại sao bạn cần một điều kiện cơ sở?

Không có điều kiện cơ sở, bạn sẽ gặp phải đệ quy vô hạn. Một tình huống mà chức năng của bạn tiếp tục gọi chính nó mà không dừng lại, như thế này

function doSomething(action) {
  console.log(`I am ${action}.`)
  doSomething(action)
}

doSomething("running")

Ngoài ra, không có điều kiện cơ sở, chức năng của bạn vượt quá ngăn xếp cuộc gọi tối đa. Bạn sẽ gặp phải lỗi hiển thị bên dưới

Đã vượt quá ngăn xếp cuộc gọi tối đa khi không có điều kiện cơ sở

Ngăn xếp cuộc gọi theo dõi các chức năng hiện đang chạy và các chức năng bên trong chúng

Ngăn xếp cuộc gọi có giới hạn. Và vì một hàm đệ quy không có điều kiện cơ sở sẽ chạy vô hạn, nên nó vượt quá giới hạn của ngăn xếp cuộc gọi

Điều kiện cơ sở cung cấp một cách để thoát ra khi hàm nhận được đầu ra mong muốn

Ví dụ về hàm đệ quy

Hãy xem một ví dụ đơn giản về hàm đệ quy

function doSomething(n) {
  if(n === 0) {
    console.log("TASK COMPLETED!")
    return
  }
  console.log("I'm doing something.")
  doSomething(n - 1)
}
doSomething(3)

Đây là kết quả khi bạn chuyển số

function recursiveFunc() {
  if(base condition) {
    // stops recursion if condition is met
  }
  // else recursion continues
  recurse();
}
8 cho hàm
function recursiveFunc() {
  // some code here...
} 
0

Điều kiện cơ sở cho hàm

function recursiveFunc() {
  // some code here...
} 
0 là
function recursiveFunc() {
  // some code here...
} 
2. Bất cứ khi nào hàm được gọi, trước tiên nó sẽ kiểm tra xem điều kiện cơ sở có được đáp ứng hay không

Nếu có, nó sẽ in

function recursiveFunc() {
  // some code here...
} 
3. Nếu không, nó tiếp tục với phần còn lại của mã trong hàm. Trong trường hợp này, nó sẽ in ra
function recursiveFunc() {
  // some code here...
} 
4 và sau đó gọi lại hàm

Cuộc gọi đệ quy

Cuộc gọi đệ quy là thứ xử lý chức năng tự gọi lại. Trong hàm

function recursiveFunc() {
  // some code here...
} 
0, lời gọi đệ quy là dòng bên dưới

function recursiveFunc() {
  // some code here...
} 
1

Lưu ý điều gì sẽ xảy ra khi hàm gọi chính nó. Một tham số mới  

function recursiveFunc() {
  // some code here...
} 
6 được truyền cho hàm. Trên mỗi lần lặp lại của một cuộc gọi đệ quy, tham số sẽ khác với cuộc gọi trước đó

Hàm sẽ tiếp tục gọi chính nó cho đến khi tham số mới thỏa mãn điều kiện cơ sở

Đệ quy vs Vòng lặp

Đệ quy và vòng lặp hoạt động theo cách tương tự. Mọi hàm đệ quy bạn viết đều có một giải pháp thay thế bằng một vòng lặp

Ví dụ: bạn có thể tạo một hàm để tìm giai thừa của một số đã cho bằng cách sử dụng cả đệ quy và vòng lặp

Cách tìm giai thừa bằng vòng lặp

function recursiveFunc() {
  // some code here...
} 
3

Để tìm giai thừa bằng vòng lặp, trước tiên bạn khởi tạo một biến

function recursiveFunc() {
  // some code here...
} 
7 với giá trị là
function recursiveFunc() {
  // some code here...
} 
8

Sau đó, bạn bắt đầu vòng lặp với số đã cho

function recursiveFunc() {
  // some code here...
} 
9. Vòng lặp sẽ tiếp tục chạy cho đến khi
function recursiveFunc() {
  if(base condition) {
    // stops recursion if condition is met
  }
  // else recursion continues
  recurse();
}
0

Đối với mỗi lần lặp lại, bạn nhân giá trị hiện tại của

function recursiveFunc() {
  // some code here...
} 
7 với
function recursiveFunc() {
  if(base condition) {
    // stops recursion if condition is met
  }
  // else recursion continues
  recurse();
}
2. Và bạn giảm giá trị của
function recursiveFunc() {
  if(base condition) {
    // stops recursion if condition is met
  }
  // else recursion continues
  recurse();
}
2 đi 1 cho đến khi
function recursiveFunc() {
  if(base condition) {
    // stops recursion if condition is met
  }
  // else recursion continues
  recurse();
}
2 không lớn hơn 0

Cuối cùng, bạn trả về giá trị của giai thừa khi vòng lặp chạy xong

Cách tìm giai thừa với đệ quy

Bạn có thể tạo cùng một giải pháp với hàm đệ quy

function recursiveFunc() {
  if(base condition) {
    // stops recursion if condition is met
  }
  // else recursion continues
  recurse();
}
2

Đầu tiên, bạn cần một điều kiện cơ sở

function recursiveFunc() {
  if(base condition) {
    // stops recursion if condition is met
  }
  // else recursion continues
  recurse();
}
5

Bạn cũng cần gọi đệ quy

function recursiveFunc() {
  if(base condition) {
    // stops recursion if condition is met
  }
  // else recursion continues
  recurse();
}
6 để đảm bảo số tiếp tục giảm ở mỗi lần gọi khi bạn chuyển một tham số mới là
function recursiveFunc() {
  if(base condition) {
    // stops recursion if condition is met
  }
  // else recursion continues
  recurse();
}
7

Sau đó, bạn nhân kết quả với số trước đó là

function recursiveFunc() {
  if(base condition) {
    // stops recursion if condition is met
  }
  // else recursion continues
  recurse();
}
8 cho đến khi đáp ứng điều kiện cơ sở

Vậy cái nào tốt hơn – đệ quy hay vòng lặp?

Vậy cái nào tốt hơn? . Tuỳ bạn quyết định. Tùy thuộc vào vấn đề bạn đang giải quyết, bạn có thể chọn vấn đề này thay vì vấn đề khác

Tối ưu hóa khả năng đọc mã của bạn. Đôi khi, giống như trong ví dụ giai thừa, đệ quy dẫn đến mã ngắn hơn và dễ đọc hơn

Nhưng các hàm đệ quy không phải lúc nào cũng trực quan. Nếu đó là trường hợp, bạn nên dính vào các vòng lặp

Sự kết luận

Trong bài viết này, bạn đã biết đệ quy là gì và cách tạo hàm đệ quy trong JavaScript

Đọc và viết các hàm đệ quy lúc đầu có thể khó hiểu. Nhưng hãy nhớ rằng, điều khiến hàm đệ quy khác với hàm thông thường là điều kiện cơ sở và lệnh gọi đệ quy

Cảm ơn vì đã đọc. Và mã hóa hạnh phúc

QUẢNG CÁO

QUẢNG CÁO

QUẢNG CÁO

QUẢNG CÁO


Javascript có giới hạn đệ quy không?
Benjamin Semah

Người phát triển phần mềm. Nhà văn kỹ thuật


Nếu bạn đọc đến đây, hãy tweet cho tác giả để cho họ thấy bạn quan tâm. Tweet một lời cảm ơn

Học cách viết mã miễn phí. Chương trình giảng dạy mã nguồn mở của freeCodeCamp đã giúp hơn 40.000 người có được việc làm với tư cách là nhà phát triển. Bắt đầu

Có giới hạn cho đệ quy không?

Do đó, giới hạn đệ quy của python thường được đặt thành một giá trị nhỏ (xấp xỉ 10^4) . Điều này có nghĩa là khi bạn cung cấp đầu vào lớn cho hàm đệ quy, bạn sẽ gặp lỗi. Điều này được thực hiện để tránh tràn ngăn xếp. Trình thông dịch Python giới hạn giới hạn đệ quy để tránh các lần truy cập vô hạn.

Một hàm có thể có bao nhiêu trường hợp đệ quy?

Hàm đệ quy có thể có bao nhiêu trường hợp cơ sở tùy ý . (Và một số hàm đệ quy chắc chắn cần nhiều hơn một; e. g. một hàm fibonacci đệ quy. )

Tại sao đệ quy không phải là vô hạn?

Nếu một đệ quy không bao giờ đến trường hợp cơ sở, thì nó sẽ tiếp tục thực hiện các cuộc gọi đệ quy mãi mãi và chương trình sẽ không bao giờ kết thúc . Điều này được gọi là đệ quy vô hạn và nó thường không được coi là một ý tưởng hay. Trong hầu hết các môi trường lập trình, một chương trình có đệ quy vô hạn sẽ không thực sự chạy mãi mãi.

JavaScript có đệ quy đuôi không?

Phiên bản tiếp theo của JavaScript (ECMAScript 6) sẽ giới thiệu một tính năng lập trình cực kỳ mạnh mẽ có tên là Đệ quy đuôi , một tính năng mà tôi rất hào hứng. Trong bài viết này tôi muốn nói một chút về đệ quy vs. lặp, đệ quy đuôi và điều đó có ý nghĩa gì đối với tương lai của JavaScript.