2010-05-28 38 views
25

thể trùng lặp:
JavaScript: var functionName = function() {} vs function functionName() {}Có bất kỳ sự khác biệt nào giữa var name = function() {} & function name() {} trong Javascript không?

Giả sử chúng ta đang ở trong một hàm và không trong không gian tên toàn cầu.

function someGlobalFunction() { 
    var utilFunction1 = function() { 
    } 

    function utilFunction2() { 
    } 

    utilFunction1(); 
    utilFunction2(); 

} 

Có phải những từ đồng nghĩa này không? Và các chức năng này hoàn toàn chấm dứt tồn tại khi someGlobalFunction trả về? Tôi có nên thích cái này hay cái kia để dễ đọc hay một số lý do khác?

Trả lời

46

Chúng là chủ yếu là giống nhau.

utilFunction1 sẽ chỉ khả dụng sau khi được khai báo. utilFunction2 được treo lên đầu chức năng, vì vậy có thể sử dụng trước khi nó được xác định.

function someGlobalFunction() { 
    utilFunction1(); // Error: untilFunction1 is undefined :(
    utilFunction2(); // Works 

    var utilFunction1 = function() { 
    } 

    function utilFunction2() { 
    } 
} 

Trừ khi chúng bị kẹt trong đóng cửa, cả hai sẽ ngừng tồn tại khi someGlobalFunction trả về.

Tôi thích sử dụng phương pháp được sử dụng để khai báo utilFunction2, nhưng tùy thuộc vào bạn.

khai báo có dạng utilFunction2 (được gọi là khai báo Function) có lợi ích bị tên (ví dụ: hiển thị như utilFunction2) trong của bạn-yêu thích-debuggerTM, nơi như utilFunction1 (gọi tắt là Expressions Function) sẽ chỉ hiển thị dưới dạng hàm ẩn danh .


Để hoàn chỉnh, bạn cũng có biểu mẫu;

var utilFunction3 = function utilFunction4() { 
    // blah 
}; 

... được gọi là một chức năng biểu hiện tên, trong đó có weird properties (và bugs (trong các phiên bản cũ của trình duyệt IE)) của riêng nó.

+0

+1 - Có vẻ như bạn đã bảo vệ mọi thứ. – ChaosPandion

+3

Nó cũng có thể được lưu ý rằng đầu tiên là một FunctionExpression trong khi thứ hai là một FunctionDeclaration. –

9

Vâng, chúng hoàn toàn khác:

  • utilFunction1 không có tên, vì vậy nếu nó ném một ngoại lệ, công cụ gỡ lỗi của bạn sẽ chỉ cho bạn biết rằng một chức năng ẩn danh ném lên
  • utilFunction2 sẽ có mặt tại phạm vi của hàm ngay cả trước khi dòng đó đạt được (như chú thích fletcher)
  • sử dụng ký hiệu utilFunction2 có thể gây ra hành vi kỳ quặc trong một số trường hợp nhất định trong IE.

Ex:

if (true) { 
    function utilFunction() { 
    return true; 
    } 
} else { 
    function utilFunction() { 
    return false; 
    } 
} 

utilFunction(); // returns false in IE, true everywhere else 

IE coi trọng vấn đề phạm vi chức năng đến cực điểm, chức năng đánh giá hiệu quả, thậm chí nếu không có mã đường dẫn đến họ!

+7

Đưa một câu lệnh hàm vào bên trong một 'if' hoặc khối không có chức năng khác không hợp lệ trong ECMAScript; hành vi trình duyệt thay đổi rất nhiều. Tránh! – bobince

8

Xin chúc mừng!Bạn đã tìm thấy tình huống mà chức năng Hoisting được tham gia.

var foo = function() { }; 

là khá khác biệt so với

function foo() { }; 

Đối với tất cả những lý do đã nói ở nơi khác, cộng thêm một.

Ví dụ thứ hai sẽ được "treo" - nó sẽ có sẵn ở bất kỳ nơi nào trong quá trình đóng cửa hiện tại (thường là chức năng hiện tại). Ngay cả trước khi nó được tuyên bố trong vòng kết thúc nói.

Something như thế này sẽ làm việc:

function foo() { 
    bar(); 
    function bar() { alert('baz'); } 
} 

Trong khi một cái gì đó như thế này sẽ chắc chắn nhất không:

function foo() { 
    bar(); 
    var bar = function bar() { alert('baz'); }; 
} 

Bạn nhận được một lỗi trong ví dụ thứ hai này, vì thanh chưa được xác định chưa. Nếu bạn trao đổi hai dòng trong hàm foo, ví dụ đó sẽ hoạt động.

Douglas Crockford ủng hộ sử dụng phương pháp thứ hai này, vì nó không chứa một hành vi ẩn như cẩu - mã của bạn không chính xác những gì nó nói nó sẽ làm, không có thủ thuật liên quan.

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