我們知道,Javascript中函數(shù)有靜態(tài)函數(shù)、成員函數(shù)和實(shí)例化對(duì)象的成員函數(shù)之分,這些函數(shù)的實(shí)現(xiàn)存在正常函數(shù)和匿名函數(shù)的區(qū)分。所以在我們Hook成員時(shí),我們要對(duì)這些情況兼而顧之。
例如對(duì)與下列函數(shù)Hook調(diào)用,預(yù)想產(chǎn)生如下的輸出:
//全局函數(shù)無參數(shù)
function Method1(){
alert('Method1');
}
Method1.hook(function()
{
alert('befor Method1');
return true;
},
function()
{
alert('after Method1');
}
);
Method1();
/* 輸出
befor Method1
Method1
after Method1
*/
alert('-----------------');
//全局函數(shù)有參數(shù)
function Method2(name){
alert('Method2 with ' + name);
}
Method2.hook(function(name)
{
alert('befor Method2 with ' + name);
return true;
},
function()
{
alert('after Method2 ');
}
);
Method2('evlon');
/* 輸出
befor Method2 with evlon
Method2 with evlon
after Method2
*/
alert('-----------------');
//Hook字符串的toString 函數(shù)
String.prototype.toString.hook(String.prototype, function()
{
alert('befor string.toString');
return true;
});
var s = "return s";
alert(s.toString());
/* 輸出
befor string.toString
return s
*/
alert('-----------------');
//Hook 系統(tǒng)已有全局函數(shù)parseInt
parseInt.hook(function()
{
alert('befor parseInt');
return true;
});
alert(parseInt('5'));
/* 輸出
befor parseInt
5
*/
alert('-----------------');
//Hook 所有數(shù)組對(duì)象的join 方法
Array.prototype.join.hook(Array.prototype, function(span)
{
alert('befor Array.prototype.join separator ' + span);
return true;
});
alert([3,5,6].join(','));
/* 輸出
befor Array.prototype.join separator ,
3,5,6
*/
alert('-----------------');
var list = [3, 5, 6];
//Hook list 這個(gè)實(shí)例數(shù)組對(duì)象的join 方法
list.join.hook(list, function(span)
{
alert('befor list.join separator ' + span);
return true;
});
alert(list.join(','));
/* 輸出
befor list.join separator ,
befor Array.prototype.join separator ,
3,5,6
*/
alert('-----------------');
var list2 = [3, 5, 6, 7];
// 此處調(diào)用不會(huì)產(chǎn)生befor list.join separator ,
alert(list2.join(','));
/* 輸出
befor Array.prototype.join separator ,
3,5,6,7
*/
alert('-----------------');
//自定義類
function People() {
//成員函數(shù)帶參數(shù)
this.getName = function(name) {
alert('in getName with ' + name);
return 'return evlon';
}
}
var p = new People();
var p2 = new People();
//這里我們只Hook實(shí)例p2 的函數(shù)調(diào)用
p2.getName.hook(p2, 'getName2',
function(name) {
alert('befor getName2 with ' + name);
return true;
},
function() {
alert('after getName2');
}
);
p2.getName.hook(p2,
function(name) {
alert('befor getName with ' + name);
return true;
},
function() {
alert('after getName');
}
);
//因?yàn)橹籋ook了P2, 對(duì)這個(gè)調(diào)用無影響
alert(p.getName('argName'));
/* 輸出
in getName with argName
return evlon
*/
alert('-----------------');
alert(p2.getName('argName'));
/* 輸出
befor getName with argName
in getName with argName
after getName
return evlon
*/
alert('-----------------');
alert(p2.getName2('argName2'));
/* 輸出
befor getName2 with argName2
in getName with argName2
after getName2
return evlon
*/