2011-12-02 35 views
33

Đối với làm những việc nhưArguments.callee không được dùng nữa - những gì nên được sử dụng thay thế?

setTimeout(function() { 
    ... 
    setTimeout(arguments.callee, 100); 
}, 100); 

tôi cần một cái gì đó giống như arguments.callee. Tôi thấy rằng information at javascript.infoarguments.callee bị phản đối:

Khách sạn này bị phản đối bởi ECMA-262 ủng hộ tên chức năng biểu thức và cho hiệu suất tốt hơn.

Nhưng sau đó nên sử dụng cái gì? Một cái gì đó như thế này?

setTimeout(function myhandler() { 
    ... 
    setTimeout(myhandler, 100); 
}, 100); 
// has a big advantage that myhandler cannot be seen here!!! 
// so it doesn't spoil namespace 

BTW, là arguments.callee tương thích giữa các trình duyệt?

+2

Đối với wh tại giá trị của nó: [Các biểu thức hàm được đặt tên được làm rõ] (http://kangax.github.com/nfe/). – sdleihssirhc

+0

Có, bạn nên đặt tên cho hàm của bạn và sử dụng tên của nó trong setTimeout. – kubetz

+1

có thể trùng lặp của [Tại sao thuộc tính arguments.callee.caller không được chấp nhận trong JavaScript?] (Http://stackoverflow.com/questions/103598/why-was-the-arguments-callee-caller-property-deprecated-in- javascript) – cHao

Trả lời

10

Có, đó là lý do, về mặt lý thuyết, nên sử dụng. Bạn đúng. Tuy nhiên, nó không hoạt động trong một số phiên bản của Internet Explorer, như mọi khi. Vì vậy hãy cẩn thận. Bạn có thể cần phải quay lại trên arguments.callee hoặc, thay vào đó, đơn giản:

function callback() { 
    // ... 
    setTimeout(callback, 100); 
} 

setTimeout(callback, 100); 

Làm việc trên IE.

+1

Chờ đợi - bạn muốn nói rằng 'setTimeout (function myhandler() {setTimeout (myhandler ...' sẽ không hoạt động trong một số phiên bản của IE? Đây có phải là một điều không chuẩn? Tôi nghĩ đó là một điều khá chuẩn để làm – TMS

+3

@TomasT .: Nó * là * tiêu chuẩn - nhưng kể từ khi nào IE đã hoàn toàn tiêu chuẩn? :) (Vâng, có thể là IE10.) Tôi nhớ đã bị vấp phải bởi nó một thời gian. Một thử nghiệm nhanh cho thấy nó không phải là vấn đề trong IE7 ít nhất, có lẽ là IE6, tôi không có nó để kiểm tra – Ryan

+0

Theo Microsoft, nó hoạt động trong IE6: https://docs.microsoft.com/en-us/scripting/javascript/reference/callee -property-arguments-javascript –

5

Nhưng sau đó nên sử dụng cái gì? Một cái gì đó như thế này?

Có, bạn đã trả lời câu hỏi của riêng bạn. Để biết thêm thông tin, xem tại đây:

Why was the arguments.callee.caller property deprecated in JavaScript?

Nó có một cuộc thảo luận khá tốt về việc tại sao sự thay đổi này đã được thực hiện.

+0

cảm ơn Jonathan. – TMS

0

Câu trả lời của minitech khá tốt, nhưng thiếu một kịch bản nữa. Hàm khai báo của bạn gọi là gọi lại, có nghĩa là hai thứ, đầu tiên hàm là đối tượng trong bộ nhớ, và hàm thứ hai, tên hàm chỉ để tham chiếu đến đối tượng. Nếu bạn, vì bất kỳ lý do nào phá vỡ tham chiếu giữa hai mã này, mã được đề xuất cũng sẽ không hoạt động.

Proof:

function callback() { 
    // ... 
    setTimeout(callback, 100); 
} 

setTimeout(callback, 100); 

var callback2 = callback; //another reference to the same object 
callback = null; //break the first reference 
callback2(); //callback in setTimeout now is null. 

Từ developer Mozilla page trong mô tả là:

Cảnh báo: 5th edition của ECMAScript (ES5) cấm sử dụng arguments.callee() trong chế độ nghiêm ngặt. Tránh sử dụng arguments.callee() bằng cách hoặc cho biểu thức hàm một tên hoặc sử dụng hàm khai báo trong đó một hàm phải tự gọi.

rõ ràng đây là ví dụ đầu tiên của workaround "bởi một trong hai chức năng đưa ra biểu thức một tên", nhưng cho phép xem làm thế nào chúng ta có thể đối phó với "hoặc sử dụng một tuyên bố chức năng mà một hàm phải gọi chính nó" và điều đó sẽ mang lại:

function callback(){ 
    //... 
    setTimeout(innercall(), 100); 
    function innercall(){ 
     //innercall is safe to use in callback context 
     innercall.caller(); //this will call callback(); 
    } 
} 

Sau đó chúng ta được an toàn để làm bất cứ điều gì chúng tôi muốn có tài liệu tham khảo callback:

var callback2 = callback; 
callback = null; 
callback2(); //will work perfectly. 
+0

'người gọi' không phải là thực hành tốt và mã mẫu ở đây dường như không thực sự hết thời gian chờ. Chỉ cần không ghi đè hàm được khai báo của bạn. – Ryan

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