js逆向之webpack模块化的编写风格_call和apply

webpack结构

注意:js 中的函数其实是对象,函数名是对 Function 对象的引用webpack结构类似如下样子:

示例1:

function (x){
    function xx(yy){ //此xx方法是模块加载器
        x[yy].call(xx0,xx1,xx2,xx3); //必有一个加载模块的方法(不一定是call, 也可能是apply)
    } //这里的xx0是一个对象, xx1,xx2,xx3参数分别对应着下方模块中的x1,x2,x3参数
    
    //xx(0) //可以调用第一个模块(即选择下面方法数组中的方法并执行)
    
}([ //这里传的是数组
    function(x1,x2,x3) {},
    function(x1,x2,x3) {},
    function(x1,x2,x3) {}
]); //传一系列的方法数组  (即这些都是模块)

示例2:

function (x){
    function xx(yy){ //此xx方法是模块加载器
        x[yy].call(xx0,xx1,xx2,xx3); //必有一个加载模块的方法(不一定是call, 也可能是apply)
    } //这里的xx0是一个对象, xx1,xx2,xx3参数分别对应着下方模块中的x1,x2,x3参数
    
    //xx("fun1") //可以调用第一个模块(即选择下面方法对象中的方法并执行)
    
}({ //这里传的是对象
    fun1:function(x1,x2,x3) {},
    fun2:function(x1,x2,x3) {},
    fun3:function(x1,x2,x3) {}
}); //传一系列的方法对象  (即这些都是模块)

call和apply方法

apply()和call差不多,只不过apply第二个参数必须传入的是一个数组,而call 第二个参数可以是任意类型,且它们的第一个参数都必须为一个对象。

  • xxx.call(对象, “参数1”, “参数2”);
  • xxx.apply(对象, [‘参数1’, ‘参数2’]);

用法

function add (x, y) 
{ 
    console.log (x + y);
} 
function sub (x, y) 
{ 
    console.log (x - y); 
} 
add.call (sub , 1, 1);    //2 

解释:用 add 来替换 sub,add.call(sub,1,1) == add(1,1) ,所以运行结果为:2

 function Animal(name){    
     this.name = name;    
     this.showName = function(){    
         alert(this.name);    
     }    
 }      
 function Cat(name){  
     Animal.call(this, name);  
 }      
 var cat = new Cat("Black Cat");   
 cat.showName();

解释:Animal.call(this) 的意思就是使用 Animal对象代替this对象,那么 Cat中不就有Animal的所有属性和方法了吗,Cat对象就能够直接调用Animal的方法以及属性了。

在js逆向中的应用

某js中外层的函数加密模块:

function(t, e, i) {
        var s;
        s = function(t, e, s) {
            function n() {
                "undefined" != typeof r && (this.jsencrypt = new r.JSEncrypt,
                this.jsencrypt.setPublicKey("省略"))
            }
            var r = i(4); //观察这个i方法是什么
            n.prototype.encode = function(t, e) {
                var i = e ? e + "|" + t : t;
                return encodeURIComponent(this.jsencrypt.encrypt(i))
            }
            ,
            s.exports = n
        }
        .call(e, i, e, t),
        !(void 0 !== s && (t.exports = s))
    }

观察上方的i方法到底是什么?

某js中加载器部分代码:

function e(s) { //方法
       if (i[s])
           return i[s].exports;
       var n = i[s] = { //对象
           exports: {}, //对象
           id: s,
           loaded: !1
       };
   
   	//这里的e是指递归调用自身, 作用: 将加载函数又传给了模块,让模块也拥有了加载其他函数的功能
   	//同时上方的i方法所属的外层函数加密模块,也是由这里的call加载调用的
       return t[s].call(n.exports, n, n.exports, e), //在此处打断点,如果断不住,就说明是动态加载的
       n.loaded = !0,
       n.exports
   }

上方的ifunction(t, e, i)函数中的第三个参数,因为call方法中第一个参数必须为一个对象,所以上方的i又对应着call(n.exports, n, n.exports, e)中的第4个参数,即e

  • 结论:上方的i方法就是这里的e方法(也就是加载器本身)
  • 注意:若为i(20),则就是调用方法对象(即模块)中的20所对应的函数
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值