google+javascriptbanktwitter@js_bankfacebook@jsbankrss@jsbank






Ruby vs JavaScript: Vài khái niệm về Hàm, Thủ tục và Khối Bài viết này cung cấp vài so sánh cơ bản giữa hai ngôn ngữ lập trình là Ruby và JavaScript. Bài viết chứa đựng các so sánh về hàm JavaScript và hàm trong Ruby, khối mã lệnh cũng như ưu và khuyết điểm của hai ngôn ngữ lập trình này trong các phạm vi so sánh.

Bài viết này là một tài liệu tham khảo khá tốt nếu bạn muốn tìm hiểu về Ruby. Vui lòng vào trang chi tiết để xem thêm.


Nhãn: Ruby vs JavaScript, Hàm, Thủ tục, so sánh cơ bản

Miễn phí web hosting 1 năm đầu tại iPage



Nếu bạn vẫn còn đang tìm kiếm một nhà cung cấp hosting đáng tin cậy, tại sao không dành chút thời gian để thử với iPage, chỉ với không quá 40.000 VNĐ/tháng, nhưng bạn sẽ được khuyến mãi kèm với quà tặng trị giá trên 10.000.0000 VNĐ nếu thanh toán cho 24 tháng ~ 900.000 VNĐ?

Có trên 1 triệu khách hàng hiện tại của iPage đã & đang hài lòng với dịch vụ, tuyệt đối chắc chắn bạn cũng sẽ hài lòng giống họ! Quan trọng hơn, khi đăng ký sử dụng web hosting tại iPage thông qua sự giới thiệu của chúng tôi, bạn sẽ được hoàn trả lại toàn bộ số tiền bạn đã sử dụng để mua web hosting tại iPage. Wow, thật tuyệt vời! Bạn không phải tốn bất kì chi phí nào mà vẫn có thể sử dụng miễn phí web hosting chất lượng cao tại iPage trong 12 tháng đầu tiên. Chỉ cần nói chúng tôi biết tài khoản của bạn sau khi đăng ký.

Nếu muốn tìm hiểu thêm về ưu / nhược điểm của iPage, bạn hãy đọc đánh giá của ChọnHostViệt.com nhé!
Thử iPage miễn phí cho năm đầu tiên NGAY

In my post Why JavaScript is AWESOME I compared Ruby to JavaScript like this:

A language like Ruby is a toolbox with some really neat little tools that do their job really nicely. JavaScript is a leather sheath with a really really sharp knife inside.

What I was partly getting at was how the two languages handle the passing around of code. Both have their own way of working with anonymous functions. They�ve taken very different approaches, so if you�re moving from one language to the other it can be confusing. I�d like to try to explain the differences. Let�s look at JavaScript first.

JavaScript functions

JavaScript has two ways of defining functions � function expressions (FE) and function declarations (FD). It can be a confusing distinction because they look the same. The difference is that a function declaration always has the word function as the first thing on the line.

//Function declaration:
function doSomething() {
    alert("Look ma, I did something!");
}

//Function expression:
var somethingElse = function () {
    alert("This is a different function");
};

The FE can optionally contain a name after the function keyword so it can call itself. I�m not going to go into depth on FD vs FE, but if you�re interested in learning more read Ben Alman�s piece on Immediately-Invoked Function Expressions, which has a good description and some useful links.

You can think of an FE as a function literal, just like {a: 'cat', b: 'dog'} is an object literal. So they don�t just have to be assigned to variables � they can be passed as function arguments, returned from functions, and stored in data structures (objects and arrays). In the end though, there�s only one function type � doSomething and somethingElse are the same type of object.

Ruby

Ruby is at the opposite end of the scale to JavaScript. Instead of having just the one function type, it has multiple types: blocks, Procs, and lambdas. (There are also methods and method objects but that�s a different story.)

Blocks

A block in Ruby is a chunk of code. It can take arguments via its funky pipe syntax, and its return value is whatever the last line evaluates to. Blocks aren�t first-class citizens in Ruby like functions are in JavaScript � they can only exist in one place � as the last argument to a method call. They�re very much a special syntactic construct baked right into the language. All methods can received blocks whether they include a parameter for one or not � it will be received anyway, and you can interact with it without it having a name. It can be called with the yield keyword, and you can check to see if a block was supplied with block_given?. Robert Sosinski gives a good example of using blocks from the point of view of the caller and that of the receiver in his post Understanding Ruby Blocks, Procs and Lambdas:

class Array
  def iterate!
    self.each_with_index do |n, i|
      self[i] = yield(n)
    end
  end
end

array = [1, 2, 3, 4]

array.iterate! do |n|
  n ** 2
end

Procs

If you need a block of code to act as a first-class citizen, you need to turn it into a Proc. That can be achieved with Proc.new. This takes a block and returns a Proc. Pretty cool eh? Procs are useful where you�d want to use a block but you�re not passing it as the last argument to a method. Rails provides a good example:

class Order < ActiveRecord::Base
  before_save :normalize_card_number,
    :if => Proc.new { |order| order.paid_with_card? }
end

The :if => syntax shows that we�re passing a hash to before_save. We can�t put a block as a hash value, so we need to make a Proc instead. Other callbacks can just take a raw block:

class User < ActiveRecord::Base
  validates_presence_of :login, :email

  before_create do 
    |user| user.name = user.login.capitalize if user.name.blank?
  end
end

For more discussion on Procs and blocks have a look at Eli Bendersky�s post: Understanding Ruby blocks, Procs and methods.

Lambdas

A lambda in Ruby is probably the closest thing to a function expression in JavaScript. A lambda is created similarly to Proc.new:

lambda { |x| x ** 3 }

Both lambda and Proc.new take a block and return an object. However, there are important differences in how they deal with their arguments and how they deal with return and break. To talk about that though I�ll need to go back to basics to discuss the reasons for using these self-contained chunks of code.

The reasons for using anonymous functions

There are a lot of good reasons to support anonymous functions in a programming language. In Ruby and JavaScript, the uses generally fall under two rough categories: iteration and deferred execution.

Iteration with anonymous functions

Iteration has a lot of uses � you can sort a collection, map one collection to another, reduce a collection down into a single value, etc. It basically comes down to going through a collection and doing something with each item, somehow. I�m going to show a very basic example of iteration � going through a list of numbers and printing each one.

In Ruby, there are two common ways to work through an array or other enumerable object, doing something to each item. The first is to use the for/in loop, which works like this:

arr = [1, 2, 3, 4]
for item in arr
  puts item
end

The second is to use the each iterator and a block:

arr = [1, 2, 3, 4]
arr.each do |item|
  puts item
end

Using iterators and blocks is much more common, so you�ll usually see it done like this.

JavaScript has a for/in loop as well, but it doesn�t really work very well on arrays. The standard way to iterate over an array is with the humble for loop:

var arr = [1, 2, 3, 4];
for (var i = 0, len = arr.length; i < len; i++) {
    console.log(arr[i]);
}

Many libraries offer support for something like Ruby�s each iterator � here is the jQuery version:

var arr = [1, 2, 3, 4];
$.each(arr, function(index, value) { 
    console.log(value); 
});

There�s an important difference here between the way Ruby and JavaScript handle the each iterator. Blocks in Ruby are specially designed for this kind of application. That means that they�ve been designed to work more like a looping language construct than an anonymous function. What does this mean practically? I�ll illustrate with an example:

arr = [1, 2, 3, 4]
for item in arr
  break if item > 2 #for non Rubyists, this is just like a compact if statement
  puts item
end

arr.each do |item|
  break if item > 2
  puts item
end

These two code snippets do the same thing � if item is greater than 2 iteration stops. On one level, this makes perfect sense � the each iterator takes a block of code, and if you want to stop iterating you break, as you would in any other language�s native foreach loop. On another level though, this doesn�t make any sense � break is used for loops, not anonymous functions. If you want to leave a function, you use return, not break.

Interestingly, if you use return inside a Ruby block, you don�t just return from the block, but the containing method. Here�s an example:

def find_first_positive_number(arr)
  arr.each do |x|
    if x >= 0
      return x
    end
  end
end

numbers = [-4, -2, 3, 7]
first = find_first_positive_number(numbers)

When arr.each gets to 3, find_first_positive_number will return 3. This demonstrates that in blocks in Ruby, the break and return keywords act as if the block was just a looping construct.

jQuery.each, on the other hand, is working with normal functions (there�s nothing else to work with in JavaScript). If you return inside the function passed to each, you�ll just return from that function, and each will move onto the next value. It�s therefore the equivalent of continue in a loop. To break out of the each entirely, you must return false.

So, in Ruby, break, continue and return work in the same way whether you�re using the for/in looping construct or using an iterator with a block. With a jQuery iterator, return is the equivalent of continue, return false is the equivalent of break, and there�s no equivalent of return without putting extra logic outside the loop. It�s easy to see why Ruby blocks were made to work this way.

Deferred execution

This is where a function is passed to another function for later use (this is often called a callback). For example, in :

$.getJSON('ajax/test.json', function(data) {
    console.log(data);
});

The anonymous function isn�t executed until the JSON data comes back from the server. Similarly, with Rails:

class User < ActiveRecord::Base
  validates_presence_of :login, :email

  before_create do |user|
    user.name = user.login.capitalize
  end
end

The block won�t be executed immediately � it�ll be saved away, ready to be executed as soon as a new User is created. In this case, break no longer makes sense � there�s no loop to break out of. return generally also doesn�t make sense in this case, as it may try to return to a function that has already returned. For more details on this see my question on Stack Overflow. This is where lambdas come to the rescue. A lambda in Ruby works much more like a Ruby method or a JavaScript function: return just leaves the lambda; it doesn�t try to exit the containing method.

So why use a block as a callback? Probably the best reason is that Ruby makes blocks so easy, so it�s simpler just to pass a block to the before_create method than to create a lambda and pass that (the before_create internals will be simpler as well).

Pros and cons

As I said at the beginning, Ruby and JavaScript have taken two extremely different approaches to functions. There�s a whole different discussion about methods across the two languages as well (JavaScript uses the same function type for methods, whereas Ruby has yet another type) but I�m not going to go there. Ruby has something different for every situation, and each one is optimised for its primary use-case. This can lead to confusion but can also make code easier to read. On the other hand, in JavaScript, a function is a function is a function. Once you know how they work, it�s easy.

There�s no point arguing about which of these two approaches is better � there�s no answer to that. Some people will prefer one over the other, but I like them both. I love the way blocks in Ruby make certain kinds of functional-like programming just roll off the fingers, but I also love the way JavaScript doesn�t complicate things, and makes proper functional programming much more possible.

If you made it this far, good on ya. I didn�t mean to write such a mammoth post, but sometimes these things happen. Cheers!

Ứng dụng AI Video.com
Tạo video doanh nghiệp của bạn bằng AI chỉ với giọng nói hoặc văn bản

chatGPTaz.com
Nói chuyện với ChatGPT bằng ngôn ngữ mẹ đẻ của bạn

Ứng dụng AI Video
Ứng dụng video AI MIỄN PHÍ đầu tiên của bạn

Deepfake Video
Deepfake AI Video Maker

Deepfake
Deepfake AI Video Maker

AI Deep Fake
Deepfake AI Video Maker

AIvidio
AI Video Mobile Solutions

AIvideos
AI Video Platform & Solutions

AIvedio
AI Video App Maker

Faceswap AI trực tuyến
Đổi mặt Video, Ảnh & GIF ngay lập tức với Công cụ AI mạnh mẽ - Faceswap AI Trực tuyến MIỄN PHÍ

Faceswap AI trực tuyến
Đổi mặt Video, Ảnh & GIF ngay lập tức với Công cụ AI mạnh mẽ - Faceswap AI Trực tuyến MIỄN PHÍ

Temu tặng $500 cho người dùng mới
Claim Free Temu $500 Credit via Affiliate & Influencer Program

Tín dụng quảng cáo TikTok miễn phí
Làm chủ quảng cáo TikTok cho hoạt động tiếp thị doanh nghiệp của bạn

Dall-E-OpenAI.com
Tự động tạo ra hình ảnh sáng tạo với AI

chatGPT4.win
Nói chuyện với ChatGPT bằng ngôn ngữ mẹ đẻ của bạn

Sản phẩm AI đầu tiên của Elon Musk - Grok/UN.com
Nói chuyện với Grok AI Chatbot bằng ngôn ngữ của bạn

Công cụ.win
Mở trung tâm công cụ miễn phí để mọi người sử dụng với hàng trăm công cụ

GateIO.gomymobi.com
Airdrop miễn phí để nhận, chia sẻ lên đến 150.000 đô la cho mỗi dự án

iPhoneKer.com
Tiết kiệm tới 630$ khi mua iPhone 16 mới

Mua Robot Tesla Optimus
Đặt mua Tesla Bot: Robot Optimus Gen 2 ngay hôm nay với giá dưới 20.000 đô la

JavaScript theo ngày


Google Safe Browsing McAfee SiteAdvisor Norton SafeWeb Dr.Web