2012-04-02 68 views
17

Nếu tôi chạy các chức năng dưới đây trước khi xác định nó, tôi sẽ nhận được lỗi này ...Có phải định nghĩa hàm Javascript trước khi gọi không?

Uncaught ReferenceError: openModal is not defined 

chạy sau đó xác định

$(document).ready(function() { 

    delay(openModal, 2000); 

    delay = function (f, t) { 
     setTimeout(function() { 
      f(); 
     }, t); 
    }; 

    openModal = function() { 
     $('#modal-box').css({ 
      left: $(window).width()/2 - $('#modal-box').width()/2, 
      top: $(window).height()/2 - $('#modal-box').height()/2 
     }); 
     $('#modal-box').show(); 
     $('#modal-mask').show(); 
    }; 

}); 

Bây giờ nếu tôi xác định các chức năng đầu tiên và sau đó gọi nó là nó hoạt động ... Tôi có một nền tảng trong PHP vì vậy tôi quen với việc có thể truy cập các chức năng trên toàn cầu, tôi có làm điều gì đó sai hay làm tất cả các chức năng phải được xác định trước khi chúng có thể được sử dụng?

$(document).ready(function() { 

    delay = function (f, t) { 
     setTimeout(function() { 
      f(); 
     }, t); 
    }; 

    openModal = function() { 
     $('#modal-box').css({ 
      left: $(window).width()/2 - $('#modal-box').width()/2, 
      top: $(window).height()/2 - $('#modal-box').height()/2 
     }); 
     $('#modal-box').show(); 
     $('#modal-mask').show(); 
    }; 

    delay(openModal, 2000); 

}); 
+0

Có phải đó là tất cả mọi thứ, ví dụ: bạn đã tuyên bố nhận diện 'openModal' (như trái ngược với định nghĩa nó) trên phạm vi đó? ví dụ. 'var openModal;' – Rup

+2

Liên quan: http://stackoverflow.com/questions/261599/why-can-i-use-a-function-before-its-defined-in-javascript – TJHeuvel

+0

@Rup đây là lần đầu tiên openModal được sử dụng – JasonDavis

Trả lời

32

Khi bạn gán một hàm cho một biến , bạn phải gán nó trước khi bạn có thể sử dụng biến để truy cập hàm.

Nếu bạn khai báo hàm với cú pháp thông thường thay vì gán nó vào một biến, nó được định nghĩa khi mã được phân tách, vì vậy công trình này:

$(document).ready(function() { 

    delay(openModal, 2000); 

    function openModal() { 
     $('#modal-box').css({ 
      left: $(window).width()/2 - $('#modal-box').width()/2, 
      top: $(window).height()/2 - $('#modal-box').height()/2 
     }); 
     $('#modal-box').show(); 
     $('#modal-mask').show(); 
    }; 

}); 

(Lưu ý sự khác biệt trong phạm vi, mặc dù Khi bạn. tạo biến số openModal bằng cách chỉ sử dụng nó, nó sẽ được tạo ra trong phạm vi toàn cục và sẽ có sẵn cho tất cả các mã Khi bạn khai báo một hàm bên trong một hàm khác, nó sẽ chỉ có sẵn bên trong hàm đó. biến cục bộ thành hàm quá, sử dụng var openModal = function() {.)

6

Di chuyển định nghĩa chức năng ra bên ngoài khối tài liệu.ready và mọi thứ sẽ hoạt động như bạn mong đợi. Trong javascript (như trong hầu hết các ngôn ngữ), bạn phải định nghĩa một hàm hoặc biến trước khi thực hiện một tham chiếu đến nó.

Trong ví dụ đầu tiên của bạn, bạn tham chiếu openModal trong cuộc gọi đến delay(), nhưng javascript không có cách nào biết được openModal là gì.

openModal = function() { 
    $('#modal-box').css({ 
     left: $(window).width()/2 - $('#modal-box').width()/2, 
     top: $(window).height()/2 - $('#modal-box').height()/2 
    }); 
    $('#modal-box').show(); 
    $('#modal-mask').show(); 
}; 

$(document).ready(function() { 
    delay(openModal, 2000); 
}); 

chỉnh sửa:

TJHeuvel chỉ ra rằng function hiện một số thủ đoạn gian trá để xác định chức năng trước khi bất cứ điều gì khác được thực hiện trong cùng một khối: Why can I use a function before it's defined in Javascript?

+4

Điểm xác định hàm bên ngoài là gì? * "bạn phải định nghĩa một hàm [...] trước khi thực hiện một tham chiếu đến nó" *: Không nhất thiết. Vì các khai báo hàm * được hoisted, bạn có thể định nghĩa chúng ở bất kỳ đâu và mã khác trong phạm vi hiện tại có thể gọi nó. Chỉ các hàm * biểu thức * có thể được gọi sau khi chúng được gán. –

+0

Lưu ý rằng những gì TJHeuvel chỉ ra không áp dụng khi bạn gán một hàm cho một biến. Ngay cả khi chính đối tượng hàm được tạo khi mã được phân tích cú pháp, nó được gán cho biến đó khi chạy. – Guffa

-1

Trong shor t có bạn phải xác định nó trước khi sử dụng một chức năng, nhưng bạn có thể sử dụng chức năng setTimeout cho sự chậm trễ của mình mà phải mất một chuỗi như mã để exectute:

$(document).ready(function() { 

    setTimeOut('openModal()', 2000); 

    openModal = function() { 
     $('#modal-box').css({ 
      left: $(window).width()/2 - $('#modal-box').width()/2, 
      top: $(window).height()/2 - $('#modal-box').height()/2 
     }); 
     $('#modal-box').show(); 
     $('#modal-mask').show(); 
    }; 

}); 

này sẽ làm việc như chức năng không được gọi cho đến khi sau khi nó được xác định.

+2

Đề xuất đầu tiên của bạn không hoạt động, vì tại thời điểm bạn gọi là 'delay (openModal, 2000) ',' openModal' vẫn giữ tham chiếu đến hàm trống. Chức năng thực sự chỉ được gán sau đó, nhưng nó không ảnh hưởng đến giá trị bạn đã vượt qua. Đề xuất thứ hai của bạn chỉ hoạt động "do nhầm lẫn". Vì 'openModal' không được khai báo với' var', nó là toàn cầu. Nhưng ngay sau khi bạn khai báo nó đúng với 'var', nó sẽ không hoạt động nữa, vì' setTimeout' đánh giá các chuỗi trong phạm vi toàn cục (và 'openModal' sẽ là cục bộ cho trình xử lý sự kiện sẵn sàng). –

+0

ok cảm ơn. đã chỉnh sửa – Richard

1

Tôi sẽ nói, CÓ. Một hàm luôn phải được xác định trước khi gọi. Nhưng một số chức năng có thể được gọi (gọi là) trước khi nơi họ đã được xác định (cẩu)

Hai loại khác nhau của các chức năng mà tôi muốn viết về là:

Chức năng biểu & Chức năng giảm tốc

1 - Chức năng biểu thức: Một biểu thức hàm có thể được lưu trữ trong một biến để chúng không cần tên hàm. Chúng cũng sẽ được đặt tên như một hàm ẩn danh (một hàm không có tên).Để gọi (gọi) chúng luôn luôn cần sử dụng một tên biến.Những loại chức năng sẽ không hoạt động nếu các cuộc gọi trước khi nó đã được xác định có nghĩa là Hoisting không xảy ra ở đây. Chúng ta luôn phải định nghĩa hàm biểu thức trước và sau đó gọi nó.

let lastName = function (family) { 
console.log("My last name is " + family); 
};   
let x = lastName("Lopez"); 

Đây là cách bạn có thể viết trong ES6:

lastName = (family) => console.log("My last name is " + family); 
x = lastName("Lopez"); 

2- giảm tốc Chức năng: Chức năng được khai báo với cú pháp sau đây không thực hiện ngay lập tức. Chúng được "lưu lại để sử dụng sau này", và sẽ được thực thi sau này, khi chúng được gọi ra (được gọi). Các kiểu hàm này hoạt động nếu bạn gọi chúng là TRƯỚC KHI hoặc SAU nơi chúng đã được định nghĩa. Nếu bạn gọi một hàm giảm tốc trước khi nó được xác định - Hoisting - hoạt động đúng.

function Name(name) { 
    console.log("My cat's name is " + name); 
} 
Name("Chloe"); 

Treo dụ:

Name("Chloe"); 
function Name(name) { 
    console.log("My cat's name is " + name); 
} 
Các vấn đề liên quan