Rất nhiều câu trả lời khác đang tập trung vào một mẫu hoạt động, nhưng các giải thích của họ không thực sự rất kỹ lưỡng về lý do mã hiện tại của bạn không hoạt động.
Mã của bạn, để tham khảo:
function funcName() {
alert("test");
}
var func = funcName();
var run = setInterval("func",10000)
Hãy chia nhỏ ra thành khối. Chức năng của bạn funcName
là tốt. Lưu ý rằng khi bạn gọi funcName
(nói cách khác, bạn chạy nó), bạn sẽ được cảnh báo "test"
. Nhưng lưu ý rằng funcName()
- dấu ngoặc đơn có nghĩa là "gọi" hoặc "chạy" hàm - không thực sự trả về một giá trị. Khi một hàm không có giá trị trả về, hàm này mặc định là giá trị được gọi là undefined
.
Khi bạn gọi một hàm, bạn nối thêm danh sách đối số của nó vào cuối trong dấu ngoặc đơn. Khi bạn không có bất kỳ đối số nào để vượt qua hàm, bạn chỉ cần thêm dấu ngoặc đơn trống, chẳng hạn như funcName()
. Nhưng khi bạn muốn tham khảo chính hàm đó, và không gọi nó, bạn không cần các dấu ngoặc đơn vì các dấu ngoặc đơn chỉ ra để chạy nó.
Vì vậy, khi bạn nói:
var func = funcName();
Bạn đang thực sự khai báo một biến func
mà có một giá trị của funcName()
. Nhưng chú ý đến dấu ngoặc đơn. funcName()
thực sự là giá trị trả lại của funcName
. Như tôi đã nói ở trên, vì funcName
không thực sự trả về bất kỳ giá trị nào, giá trị mặc định là undefined
. Vì vậy, nói cách khác, biến của bạn func
thực sự sẽ có giá trị undefined
.
Sau đó, bạn có dòng này:
var run = setInterval("func",10000)
Chức năng setInterval
nhận hai đối số.Đầu tiên là hàm được chạy thường xuyên, và thứ hai là số mili giây giữa mỗi lần hàm được chạy.
Tuy nhiên, đối số đầu tiên thực sự phải là hàm, không phải là chuỗi. Nếu đó là một chuỗi, thì công cụ JavaScript sẽ sử dụng eval
trên chuỗi đó thay thế. Vì vậy, nói cách khác, setInterval của bạn đang chạy mã JavaScript sau:
func
// 10 seconds later....
func
// and so on
Tuy nhiên, func
chỉ là một biến (với giá trị undefined
, nhưng đó là loại không thích hợp). Cứ mười giây một lần, công cụ JS sẽ đánh giá biến số func
và trả về undefined
. Nhưng điều này không thực sự làm bất cứ điều gì. Ý tôi là, về mặt kỹ thuật, nó được đánh giá sau mỗi 10 giây, nhưng bạn sẽ không thấy bất kỳ hiệu ứng nào từ đó.
Giải pháp là cung cấp cho setInterval
một hàm để chạy thay vì chuỗi. Vì vậy, trong trường hợp này:
var run = setInterval(funcName, 10000);
Lưu ý rằng tôi không cung cấp cho nó func
. Điều này là do func
là không một chức năng trong mã của bạn; đó là giá trị undefined
, bởi vì bạn đã gán nó funcName()
. Như tôi đã nói ở trên, funcName()
sẽ gọi hàm funcName
và trả về giá trị trả lại của hàm. Vì funcName
không trả lại bất cứ điều gì, giá trị mặc định này là undefined
. Tôi biết tôi đã nói rằng nhiều lần bây giờ, nhưng nó thực sự là một khái niệm rất quan trọng: khi bạn nhìn thấy funcName()
, bạn nên nghĩ rằng "giá trị trả về của funcName
". Khi bạn muốn tham chiếu đến một hàm chính nó, giống như một thực thể riêng biệt, bạn nên bỏ dấu ngoặc đơn để bạn không gọi nó: funcName
.
Vì vậy, một giải pháp cho mã của bạn sẽ là:
var func = funcName;
var run = setInterval(func, 10000);
Tuy nhiên, đó là một chút dư thừa: tại sao sử dụng func
thay vì funcName
?
Hoặc bạn có thể ở lại là đúng càng tốt để mã gốc bằng cách sửa đổi hai bit:
var func = funcName;
var run = setInterval("func()", 10000);
Trong trường hợp này, động cơ JS sẽ đánh giá func()
mỗi mười giây. Nói cách khác, nó sẽ cảnh báo "test"
cứ mười giây một lần. Tuy nhiên, như cụm từ nổi tiếng, eval
is evil, vì vậy bạn nên cố gắng tránh cụm từ này bất cứ khi nào có thể.
Một bước nhảy khác trên mã này là sử dụng chức năng ẩn danh. Nói cách khác, một hàm không có tên - bạn chỉ cần thả nó vào mã bởi vì bạn không quan tâm nó được gọi là gì.
setInterval(function() {
alert("test");
}, 10000);
Trong trường hợp này, vì tôi không quan tâm chức năng được gọi là gì, tôi chỉ để lại chức năng chung, chưa được đặt tên (ẩn danh) ở đó.
Bạn nên xem bảng điều khiển lỗi của trình duyệt của bạn nói gì trong những trường hợp này. – Bojangles
Bạn có biết điều gì sẽ xảy ra khi bạn chuyển 'func '' thành 'setInterval' và giá trị' func' có? Nó luôn hữu ích khi đọc [một số tài liệu] (https://developer.mozilla.org/en/window.setInterval). –
Việc truyền một chuỗi tới 'setInterval()' (thường là một ý tưởng tồi ở nơi đầu tiên) khiến cho nó thực hiện một 'eval (" func ")'.Đó là cơ bản giống như một dòng javascript như thế này: 'func;' mà không có gì. Như một chuỗi, bạn phải thực sự thực thi hàm như 'setInterval (" func() ", 10000)', nhưng tốt hơn hết là chỉ cần truyền tên hàm thực tế như 'setInterval (funcName, 10000)' và không bao giờ ép nó vào sử dụng 'eval()' ngay từ đầu. – jfriend00