2008-10-15 29 views
16

Như có thể thấy trong Mozilla changlog cho JavaScript 1.7, chúng đã thêm phép gán destructuring. Đáng buồn là tôi không phải là rất thích cú pháp (tại sao viết a, b hai lần?):Phân công chuyển cấu trúc trong JavaScript

var a, b; 
[a, b] = f(); 

Something như thế này sẽ tốt hơn rất nhiều:

var [a, b] = f(); 

Đó vẫn sẽ là tương thích ngược . Sự phá hủy giống như Python sẽ không tương thích ngược.

Dù sao giải pháp tốt nhất cho JavaScript 1.5 mà tôi đã có thể đưa ra là:

function assign(array, map) { 
    var o = Object(); 
    var i = 0; 
    $.each(map, function(e, _) { 
     o[e] = array[i++]; 
    }); 
    return o; 
} 

Những công trình như:

var array = [1,2]; 
var _ = assign[array, { var1: null, var2: null }); 
_.var1; // prints 1 
_.var2; // prints 2 

Nhưng điều này thực sự sucks vì _ không có ý nghĩa. Nó chỉ là một vỏ rỗng để lưu trữ tên. Nhưng thật đáng buồn là nó cần thiết vì JavaScript không có con trỏ. Về phía cộng, bạn có thể gán giá trị mặc định trong trường hợp các giá trị không khớp. Cũng lưu ý rằng giải pháp này không cố gắng cắt mảng. Vì vậy, bạn không thể làm điều gì đó như {first: 0, rest: 0}. Nhưng điều đó có thể dễ dàng được thực hiện, nếu một người muốn hành vi đó.

Giải pháp tốt hơn là gì?

Trả lời

23

Trước hết, var [a, b] = f() tác phẩm tốt trong JavaScript 1.7 - thử nó!

Thứ hai, bạn có thể mịn ra các cú pháp sử dụng hơi sử dụng with():

var array = [1,2]; 
with (assign(array, { var1: null, var2: null })) 
{ 
    var1; // == 1 
    var2; // == 2 
} 

Tất nhiên, điều này sẽ không cho phép bạn thay đổi giá trị của biến hiện có, vì vậy IMHO đó là một toàn bộ rất nhiều ít hữu ích hơn so với tính năng JavaScript 1.7. Trong mã tôi đang viết bây giờ, tôi chỉ cần trả lại các đối tượng trực tiếp và tham khảo các thành viên của họ - Tôi sẽ đợi cho đến 1.7 tính năng trở nên phổ biến rộng rãi hơn.

+0

Cảm ơn! Điều đó khắc phục một trong những nhược điểm :) –

+2

Kể từ hôm nay 'var [a, b] = [1,2];' dẫn đến lỗi cú pháp trong Chrome. – Marcin

+9

@Marcin: JavaScript 1.7 là [ngôn ngữ chỉ dành cho Mozilla] (http://stackoverflow.com/questions/1330498/what-is-cross-browser-support-for-javascript-1-7s-new-features-specifically -ar) – Shog9

4

Bạn không cần biến "_" giả. Bạn có thể trực tiếp tạo ra các biến "toàn cầu" bằng cách sử dụng phạm vi đối tượng cửa sổ:

window["foo"] = "bar"; 
alert(foo); // Gives "bar" 

Dưới đây là một vài điểm hơn:

  • tôi sẽ không đặt tên cho chức năng này "gán" bởi vì đó là quá chung chung một thuật ngữ.
  • Để gần giống với cú pháp JS 1.7, tôi muốn đặt hàm này làm đích đến làm đối số đầu tiên và nguồn là đối số thứ hai .
  • Sử dụng đối tượng theo nghĩa đen để vượt qua các biến đích là tuyệt vời nhưng có thể bị nhầm lẫn với việc phá hủy JS 1.7 nơi đích thực sự là đối tượng chứ không phải mảng. Tôi chỉ thích sử dụng một danh sách được phân cách bằng dấu phẩy gồm các tên biến như một chuỗi.

Đây là những gì tôi đã đưa ra:

function destructure(dest, src) { 
    dest = dest.split(","); 

    for (var i = 0; i < src.length; i++) { 
     window[dest[i]] = src[i]; 
    } 
} 

var arr = [42, 66]; 

destructure("var1,var2", arr); 

alert(var1); // Gives 42 
alert(var2); // Gives 66 
+2

Điều duy nhất tôi đồng ý là việc hủy cấu trúc có thể là tên tốt hơn. * nguồn, đích là phong cách unix. * phổ biến phạm vi toàn cầu không đẹp. Nó không dẫn đến khả năng kết hợp. * Viết các biến đầu ra dưới dạng một chuỗi bị mệt mỏi và khó khăn hơn để trình soạn thảo của bạn kiểm tra. Giống như viết SQL. –

+0

@AndersRuneJensen Vì điều này bắt chước một nhiệm vụ, đích đến gần như chắc chắn nằm ở bên trái - theo cách đó nó trông giống như '[var1, var2] = arr'. Và 'destructure' là một tên khủng khiếp, không có ý định tiết lộ. Tôi nghĩ rằng 'gán' là tốt hơn - sau khi tất cả, điều này là * nghĩa vụ * là một chức năng tiện ích chung. Nếu không, thì có thể 'massAssign'? –

0

Trong tiêu chuẩn Javascript chúng tôi làm quen với tất cả các loại xấu xa, và bắt chước destructuring giao nhiệm vụ bằng một biến trung gian không phải là quá xấu:

function divMod1(a, b) { 
    return [ Math.floor(a/b), a % b ]; 
} 

var _ = divMod1(11, 3); 
var div = _[0]; 
var mod = _[1]; 
alert("(1) div=" + div + ", mod=" + mod); 

Tuy nhiên tôi nghĩ rằng mô hình sau đây là hơn idomatic:

function divMod2(a, b, callback) { 
    callback(Math.floor(a/b), a % b); 
} 

divMod2(11, 3, function(div, mod) { 
    alert("(2) div=" + div + ", mod=" + mod); 
}); 

Lưu ý rằng thay vì trả về hai kết quả dưới dạng mảng, chúng tôi chuyển chúng thành các đối số cho hàm gọi lại.

(Xem mã chạy tại http://jsfiddle.net/vVQE3/)

1

Dưới đây là những gì tôi đã làm trong PHPstorm 10:

File -> Cài đặt -> Ngôn ngữ & Khung -> ...

... đặt phiên bản ngôn ngữ JavaScript thành ví dụ JavaScript 1.8.5 ...

-> nhấp vào Áp dụng.

Các vấn đề liên quan