2012-03-05 3 views
43

tôi chủ yếu là một nhà phát triển Rails, và như vậy trong whipping lên một kịch bản ít ví dụ Hubot của công ty tôi, tôi đã hy vọng để thực hiện những điều sau:Coffeescript || = analogue?

robot.brain.data.contacts ||= {} 

Hoặc, chỉ làm cho băm mới này nếu nó doesn' đã tồn tại. Ý tưởng là tôi muốn có một mảng liên lạc được thêm động thông qua tập lệnh nên tôi không phải sửa đổi nguồn của Hubot và rõ ràng là tôi không muốn ghi đè bất kỳ liên hệ nào tôi thêm vào đó.

Câu hỏi: có cấu trúc nhỏ nhanh như Rails || = mà tôi có thể sử dụng trong Coffeescript để đạt được mục tiêu trên không?

Chúc mừng.

Trả lời

61

Bạn có thể sử dụng ?= chuyển nhượng có điều kiện:

speed ?= 75 

Các ? là "Hiện sinh điều hành" trong CoffeeScript, vì vậy nó sẽ kiểm tra sự tồn tại (không truthiness):

if (typeof speed === "undefined" || speed === null) speed = 75; 

Kết quả JS có một chút khác biệt trong trường hợp của bạn, tuy nhiên, bởi vì bạn đang thử nghiệm một đối tượng quảng cáo rty, không chỉ là một biến, vì vậy robot.brain.data.contacts ?= {} kết quả trong những điều sau đây:

var _base, _ref; 
if ((_ref = (_base = robot.brain.data).contacts) != null) { 
    _ref; 
} else { 
    _base.contacts = {}; 
}; 

Thông tin thêm: http://jashkenas.github.com/coffee-script/

7

?= sẽ chỉ định một biến nếu đó là null hoặc undefined.

Sử dụng nó như speed ?= 25

4

Nó được gọi là các nhà điều hành hiện sinh trong Coffeescript và là ?=, http://coffeescript.org/. Trích dẫn dưới đây:

Các Existential hành

Đó là một chút khó khăn để kiểm tra sự tồn tại của một biến trong JavaScript. nếu (biến) đến gần, nhưng không thành công, chuỗi rỗng và sai. Nhà điều hành tồn tại của CoffeeScript? trả về true trừ khi một biến là null hoặc không xác định, mà làm cho nó tương tự như nil của Ruby?

Nó cũng có thể được sử dụng để chuyển nhượng có điều kiện an toàn hơn || = cung cấp, trong trường hợp bạn có thể xử lý số hoặc chuỗi.

12

Cá nhân tôi sử dụng or= thay vì ?= chủ yếu là bởi vì đó là cái mà tôi gọi ||= (hoặc-tương đương) khi tôi sử dụng nó trong Ruby.

robot.brain.data.contacts or= {} 

Sự khác biệt là or= ngắn mạch khi robot.brain.data.contacts không phải là null, trong khi ?= kiểm tra cho null và chỉ đặt robot.brain.data.contacts để {} nếu không null.

See the compiled difference.

Như đã đề cập trong bài khác, không phải kiểm tra phương pháp cho sự tồn tại của robot, robot.brain hoặc robot.brain.data, nhưng cũng như thế Ruby tương đương.

Edit:

Ngoài ra, trong CoffeeScript or=||= biên dịch với cùng JS.

+1

'hoặc =' và '? =' không biên dịch cho cùng một JS. '? =' thực hiện kiểm tra null. Xem [this] (http://coffeescript.org/#try:a%20%3D%20b%20%3D%200%0A%0Aa%20or%3D%201%3B%0Ab%20%3F%3D% 201% 3B) cho sự khác biệt khi sử dụng các tên biến khác nhau. –

1

Các phương ngữ Coco của CoffeeScript, http://github.com/satyr/coco, hỗ trợ các mảng và đối tượng khai thác autovivification @@@:

[email protected]@[email protected] = 1 

biên dịch để - cấp, lông-looking -

var _ref, _ref2; 
((_ref = (_ref2 = robot.brain || (robot.brain = {})).data || (_ref2.data = {})).contacts || (_ref.contacts = {})).foo = 1; 

mà đảm bảo rằng mỗi bước đường, robot.brain, brain.data, data.contacts thực sự tồn tại.

Tất nhiên bạn có thể chỉ muốn các nhà điều hành thực tế có điều kiện chuyển nhượng (trong đó, theo các câu trả lời ở trên, cũng tồn tại trong CoffeeScript):

robot.brain.data.contacts ?= {} 

rằng biên dịch để

var _ref; 
(_ref = robot.brain.data).contacts == null && (_ref.contacts = {});