2010-08-04 23 views
21

Trong đoạn mã này, tôi đã tạo ra một hàm gọi là someFunction. Sau đó, tôi đã sửa đổi Function.prototype.apply và các phương thức gọi. Vì vậy, thay vì mã chức năng của tôi đang làm việc tôi đang chạy mã chặn của tôi (trong đó cho thấy một cảnh báo). Nhưng không phải "gọi" hay "áp dụng" đều chặn cuộc gọi phương thức trực tiếp. Liệu nó có thể đánh chặn điều này?Tôi có thể chặn một hàm được gọi trực tiếp không?

Function.prototype.call = function(){alert("call");}; 
Function.prototype.apply = function(){alert("apply");}; 
function someFunction(){} 
window.onload = function(){ 
    someFunction.call(this); //call alert is shown 
    someFunction.apply(this); //apply alert is shown 
    someFunction(); //how can I intercept this? 
} 

Trả lời

27

Bạn chỉ có thể ghi đè lên một chức năng được biết đến bằng cách thiết lập chức năng vào chỗ của nó (ví dụ, bạn không thể chặn tất cả các cuộc gọi chức năng):

(function() { 
    // An anonymous function wrapper helps you keep oldSomeFunction private 
    var oldSomeFunction = someFunction; 

    someFunction = function() { 
     alert("intercepted!"); 
     oldSomeFunction(); 
    } 
})(); 

Lưu ý rằng, nếu someFunction đã được aliased/được tham chiếu bởi một tập lệnh khác trước khi nó được thay đổi bởi mã này, những tham chiếu đó sẽ trỏ đến hàm ban đầu không bị hàm thay thế ghi đè.

+0

Có lẽ tôi có thể thay đổi Function.constructor chức năng như vậy mỗi chức năng quay trở lại sẽ có wrapper của bạn xung quanh nó. – yilmazhuseyin

+2

@yilmazhuseyin: không, bạn không thể. Việc thay đổi hàm tạo * Function * sẽ chỉ cho phép bạn ghi đè các hàm được tạo bằng 'hàm mới (str)'. –

+0

có bạn đã đúng. function newConstructor() {alert ("a");}; Function.prototype.constructor = newConstructor; không hoạt động. – yilmazhuseyin

2

Bạn có thể lặp qua phạm vi toàn cục và thay thế bất kỳ đối tượng nào của loại hàm bạn tìm thấy không phải là "của bạn".

3

Có một cơ hội bạn có thể ngăn chặn chức năng trực tiếp gọi điện. Điều này đòi hỏi:

  • Hoặc là chức năng được tạo ra bởi Function.prototype.bind và bạn phải ghi đè lên Function.prototype.bind trước khi tạo các chức năng, hoặc
  • Chức năng được tạo ra từ chức năng() (hoặc mới Hàm()) và bạn cũng phải ghi đè hàm chức năng trước khi tạo hàm mục tiêu.

Nếu không của hai bên trên có thể được đáp ứng, cách duy nhất để ngăn chặn một cuộc gọi trực tiếp là để bọc các chức năng mục tiêu, đó là giải pháp được cung cấp bởi AndyE https://stackoverflow.com/a/3406523/1316480

Đối với một chức năng được tạo ra bởi chức năng theo nghĩa đen và được ẩn trong phạm vi riêng tư, không có cách nào để chặn cuộc gọi trực tiếp đến nó.

Tôi có một bài viết trên blog kết luận tất cả những: http://nealxyc.wordpress.com/2013/11/25/intercepting-javascript-function/

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