2013-09-05 22 views
12

Tôi đã tìm thấy mã javascript điên khùng này.Cách thực hiện (ví dụ: theo thứ tự nào) mã này chạy và nó hoạt động như thế nào?

Ai đó có thể xây dựng các bước chính xác mà mã này đang thực hiện và tại sao?

(function a(a){ 
    return a; 
}) 
(function b(b){ 
    return b; 
}) 
(function c(c){ 
    return c; 
}) 
(true); 
+5

Chỉ ba chức năng của nó và trả về đúng sự thật .. Thats it –

+0

Tôi không. Bạn tôi đã cho tôi như một câu đố. – Joon

+2

Phần khó khăn của "câu đố" này không phải là các hàm được gọi tự động, nhưng tại sao chúng được gọi từ trái sang phải. Nếu bạn thêm câu lệnh 'console.log' trước mỗi lần trả về, bạn sẽ thấy rằng' a' được xuất ra trước 'b', được xuất ra trước' c'. Nhưng làm thế nào có thể chức năng 'a' biết đầu vào arg trước khi chức năng' b' trả về nó? – Steve

Trả lời

11
  • chí này tự gọi a được đưa ra functionb như là đối số (kể từ a được định nghĩa là một biến bên trong phạm vi địa phương a 's rằng sẽ mất sự hiện diện trên chức nănga được khai báo trong cha mẹ phạm vi.).
  • Sau đó, nó sẽ tự gọi b được đưa ra c làm đối số.
  • Cuối cùng, chức năng c là tự viện dẫn trả về true như được đưa ra làm đối số.

Bạn có thể nhìn vào nó như là một chuỗi làm điều này:

a(var a) // function b given as arg. When a returns b() will be invoked 
    b(var b) // function c given as arg. When b returns c() will be invoked 
     c(true) 

a khi bên trong hàm (phạm vi địa phương) là một biến vì function foo(bar){} cũng giống như function(){var bar = arguments[0]}.

Chức năng a có thể được viết như thế này và làm điều tương tự:

function a(foo){ 
    return foo; 
} 

Bạn có thể xác minh bằng cách làm này:

console.log('start'); 

(function a(a){ 
    console.log('a', typeof a); 
    return a; 
}) 
(function b(b){ 
    console.log('b', typeof b); 
    return b; 
}) 
(function c(c){ 
    console.log('c', typeof c); 
    return c; 
}) 
(true); 

console.log('end'); 

ONLINE FIDDLE HERE

đầu ra

Console (cập nhật để hiển thị trong FF cũng như sử dụng Chrome để xem định nghĩa hàm o utput ):

> start 
> a function 
> b function 
> c boolean 
> end 
+1

Tôi đồng ý rằng đây là thứ tự đầu ra đúng, nhưng làm thế nào mà phần thân của hàm 'a' biết đầu vào arg khi nó rõ ràng dựa vào hàm' b' đến sản xuất nó? – Steve

+0

@Steve chức năng được phân tích cú pháp trước khi thực hiện bất kỳ (cùng một lý do bạn có thể gọi một hàm trước hoặc sau khi định nghĩa của nó) vì vậy 'b' đã được định nghĩa khi' a' đang được gọi. Vì JS là luồng đơn 'a' phải kết thúc trước khi' b' có thể được gọi là mục nhập tiếp theo tại hàng đợi sự kiện. Nó không sử dụng kết quả từ 'b' chỉ định nghĩa' b' * chính nó * (nghĩ 'var b = someFunction'). – K3N

+0

Nếu bạn đang nói về cẩu, thì điều này chỉ áp dụng cho các khai báo hàm, chứ không phải các biểu thức hàm ... và đặt các dấu ngoặc quanh một hàm làm cho nó trở thành một biểu thức hàm, tức là 'function a() {..}' nhưng không phải 'var a = function() {...}' cũng không '(hàm a() {...})'. – Steve

1

Các chức năng được thực thi theo thứ tự từ trên xuống. Bạn có thể gọi hàm với hàm khác làm đối số của nó. Điều này là tốt. Nó tiếp tục làm điều này cho đến khi "true" được chuyển thành một đối số, trong trường hợp đó chuỗi gọi trả về "true".

(function a(a){  // Function a is called with function b as an argument. 
    console.log('a'); // The console.log statement is executed, 
    return a;   // Then function a returns b 
})      

(function b(b){  // Function b is called with function c as an argument. 
    console.log('b') // The console.log statement is executed 
    return b;   // And then function b returns c 
}) 

(function c(c){  // Function c is called with "true" as an argument 
    console.log('c') // The console.log statement is executed 
    return c;   // And then function c returns true. 
}) 

(true); 
+0

Tôi không nghĩ rằng điều này là chính xác. Nếu tôi đặt console.log bên trong của mỗi hàm, thứ tự ngược lại với những gì bạn đang nói. Nhưng tại sao? – Joon

+0

@Juno. Bạn hoàn toàn đúng. Tôi đã sửa đổi các ý kiến ​​để giải thích tại sao điều này xảy ra. Các hàm được gọi/được thực thi theo thứ tự từ trên xuống. – ktm5124

2

Điều này trả về true.

Đầu tiên function a (tên xấu?) Được xác định để nhận đối số và trả về. Hàm này đã được gọi ngay lập tức, với đối số là giá trị trả về là (function b(b){ return b; })(function c(c){ return c; })(true). Được đánh giá trước khi số a được gọi.

(function b(b){ return b; })(function c(c){ return c; })(true) là một cấu trúc tương tự, với hàm b được xác định trả về đối số nhận được, và một lần nữa được gọi ngay lập tức với đối số tương tự và giống với hàm thứ ba c.

4

Để hiểu những gì đang xảy ra, đơn giản hóa nó:

(function a(d){ 
    return 5*d; 
}) 
(2) 

Đoạn mã trên, chạy trong giao diện điều khiển, sẽ ra 10. Điều đang xảy ra là các dấu ngoặc đang yêu cầu mã chạy ngay lập tức (nó được gọi là một hàm tự gọi), lấy bất cứ điều gì sau đây như một tham số. Vì vậy, tôi đang tạo function a và ngay lập tức chạy nó với thông số 2.

Mã bạn có về cơ bản là giống nhau, nhưng với nhiều cấp độ hơn và không có phép nhân. Tất cả các hàm của bạn chỉ trả về các tham số của chúng, và một hàm được truyền vào là boolean true, vì vậy mã sẽ xuất ra true ở cuối.

+0

Lời giải thích tuyệt vời cũng giúp hiểu được các câu trả lời khác :) – bobs12

1
(function a(a){ 
      alert(a); 
     return a; 
    }) 
    (function b(b){ 
     alert(b); 
     return b; 
    }) 
    (function c(c){ 
     alert(c); 
     return c; 
    }) 
    (true); 

Chỉ trả lại phần tiếp theo của tham số bằng ký hiệu().

1

Tôi sẽ bị đâm vào nó.

(function a(a){ 
    return a; 
}) 
(function b(b){ 
return b; 
}) 
(function c(c){ 
return c; 
}) 
(true); 

Đây là tất cả các chức năng tự gọi.

Nhưng mới nhất:

(function c(c){ 
     return c; 
    }) 
    (true); 

Gets giá trị thực sự được thông qua năm Vì vậy, khi nó trả về "c" - bạn sẽ có được sự thật..

Đối với những người khác, nó chỉ di chuyển lên dưới dạng các hàm ẩn danh được truyền vào giá trị trả về của hàm. Vì vậy, một hình ảnh.

(function a(a){ <-- the return of b, gets passed in here 
     return a; 
    })(function b(b){return b;}) <-- the return of c, gets passed in here 

    (function c(c){return c;})(true); <--- true gets passed into c. 
Các vấn đề liên quan