cấu trúc đối tượng mà không có var


97

Tại sao việc hủy cấu trúc đối tượng lại gặp lỗi nếu không có vartừ khóa phía trước nó?

{a, b} = {a: 1, b: 2};

ném SyntaxError: expected expression, got '='

Ba ví dụ sau hoạt động mà không có vấn đề

var {a, b} = {a: 1, b: 2};
var [c, d] = [1, 2];
    [e, f] = [1, 2];

Câu hỏi bổ sung: Tại sao chúng ta không cần cấu trúc varmảng for?

Tôi gặp sự cố khi làm một cái gì đó như

function () {
  var {a, b} = objectReturningFunction();

  // Now a and b are local variables in the function, right?
  // So why can't I assign values to them?

  {a, b} = objectReturningFunction();
}

Câu trả lời:


158

Vấn đề bắt nguồn từ các {...}toán tử có nhiều nghĩa trong JavaScript.

Khi {xuất hiện ở đầu Câu lệnh , nó sẽ luôn đại diện cho một khối , không thể gán cho khối này. Nếu nó xuất hiện sau đó trong Câu lệnh dưới dạng Biểu thức , thì nó sẽ đại diện cho một Đối tượng.

Điều varnày giúp tạo ra sự khác biệt, vì nó không thể được theo sau bởi một Tuyên bố , cũng như các dấu ngoặc kép sẽ được nhóm :

( {a, b} = objectReturningFunction() );

Từ tài liệu của họ: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destosystem_assignment#Assignment_without_decosystem

Lưu ý: Các dấu ngoặc đơn (...) xung quanh câu lệnh gán là bắt buộc khi sử dụng phép gán hủy cấu trúc theo nghĩa đen đối tượng mà không cần khai báo.

{a, b} = {a: 1, b: 2} không phải là cú pháp độc lập hợp lệ, vì {a, b} ở phía bên trái được coi là một khối chứ không phải là một đối tượng theo nghĩa đen.

Tuy nhiên, ({a, b} = {a: 1, b: 2}) hợp lệ, cũng như var {a, b} = {a: 1, b: 2}

Biểu thức (...) của bạn cần phải đặt trước dấu chấm phẩy hoặc nó có thể được sử dụng để thực thi một hàm trên dòng trước đó.


Nếu nó xuất hiện sau đó trong Câu lệnh dưới dạng Biểu thức, thì nó sẽ đại diện cho một Đối tượng. Điều này có nghĩa là chúng ta không bao giờ có thể có phạm vi khối bên trong dấu ngoặc đơn nhóm
sharad_kalya

Mẹo phân nhóm dấu ngoặc đơn là một mẹo hay.
James Smith

Đây là một chút kiến ​​thức mù mờ tuyệt vời khiến tôi bối rối. Nó cho phép hủy cấu trúc trên phạm vi (tốt, đại loại - tất nhiên bạn vẫn cần khai báo các biến của mình). Nhưng nó giải quyết được hạn chế của việc sử dụng chuỗi Promise trong khi cần sử dụng nhiều biến được giải quyết từ bước này của chuỗi Promise ở bước khác mà không tạo ra quá nhiều lộn xộn. Cảm ơn.
Kevin Teljeur

21

Nếu bạn viết Javascript không có dấu chấm phẩy , thì cú pháp 'gán mà không cần khai báo' phải được đặt trước bằng dấu chấm phẩy để nó hoạt động dễ đoán

let a, b

;({a, b} = objectReturningFunction()) // <-- note the preceding ;

Tôi chỉ muốn làm nổi bật điều này khi nó phát hiện ra và hy vọng có thể giúp những người khác tiết kiệm thời gian tìm ra lý do tại sao nó không hoạt động và / hoặc tạo ra kết quả kỳ lạ với các trình định dạng mã như prettier.

Thật vậy, nó thực sự nằm ngay trong câu trả lời được chấp nhận (dòng cuối cùng của tài liệu được trích dẫn) nhưng rất dễ bỏ sót, đặc biệt là không xem ví dụ!


Vâng. Một lý do để mọi người sử dụng dấu chấm phẩy!
jfriend00

0

Đây là một cách khác:

let {} = {a, b} = objectReturningFunction()

Ưu điểm:

  • Không cần dấu ngoặc
  • Không cần dấu chấm phẩy

Nhược điểm:

  • Trông hơi kỳ lạ, mặc dù theo ý kiến ​​của tôi thì không có gì lạ hơn !(){...}() IIFE
  • Có thể khó hiểu tại sao nó ở đó

Loại cảm giác như IIFE có thể so sánh ;({ a, b })hơn let {} = { ... }. Tuy nhiên, mẹo hay. :)
shuckster

@ proto-n, +1, ý tưởng rất thông minh. Làm thế nào bạn có được điều này?
Pacerier
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.