JavaScript学习笔记(十三)——劫持

劫持

劫持分为三类,重点学习js中的this关键字的引用劫持。

  1. 黑客劫持网络数据包,然后暴力解码(逆向工程)个人隐私窃取了;

  2. 系统内置功能的重写;

  3. this关键字的引用劫持:在调用函数的时候让函数内部的this是指定的对象。

  • call() 方法

var obj={
    name:'marry',
    say:function(){
    console.log(this.name,str);
    }
};
var obj2={name:'jack'};
​
obj.say.call(obj2);
//相当于是obj2再调用say方法
obj.say.call(obj2,100);
//第二个参数是调用方法的参数
  • apply() 方法

var obj={
    name:'marry',
    say:function(){
    console.log(this.name,str1,str2);
    }
};
var obj2={name:'jack'};
​
obj.say.apply(obj2,[10,20]);  //打印 Jack 10 20
//调用obj2里面的say方法,以数组的方式传入实参

案例:数组里面并没有max()方法,但是Math里面有max()方法,这里很好理解,因为数组里面可以存很多类型的值,比如字符串,并不是只有数值型无法比较。这个时候我们就可以直接劫持掉Math的max()方法,来对全是数值型的数组进行最大值的寻找。

var re = Math.max(12, 23, 2, 3);
console.log(re);//23
​
var arr = [12, 3, 133, 46, 31, 2];
var maxnum = Math.max.apply('', arr);//劫持Math里的max()方法,这里'',随便写因为这道题与this无关
console.log(maxnum);//打印最大值133
​
  • 定义是函数可以在设计的时候就指定this ---> 用bind()方法

        var obj2 = {
            name: "karen"
        };
        var obj = {
            name: "jack",
            say: function () {
                console.log(this.name);
            }.bind(obj2)
        }
​
        obj.say();//打印karen 
​
        var obj3 = {
            name: "marry"
        };
        obj.say.call(obj3);//打印karen ,虽然用了call()方法劫持,但是在say()方法设计了bind绑定了obj2,也就是说bind()方法的优先级最高,这也就是为什么内置功能无法改变的原因。

自己设计函数功能的时候大量应用bind方法绑定对象,以防其他人改掉你的this指向。

 

 

拓展:

根据(obj.say.call(obj2);)官方的源代码推出一些规律:

  1.  

  2. 所有的函数对象都有call()方法(它的原型对象Function.prototype上有call方法);

  3. 运行的函数是say函数;

  4. 调用这个函数的对象是obj2。

  5. 多个对象可以引用同一个函数。

现在这前面这些总结上分析下面这道题:

        function fn() {
            console.log(1)
        }
​
        function fn2() {
            console.log(2)
        }
​
​
        fn.call.call(fn2);
        //fn.call是一个函数,他有call方法,fn.call引用了一个函数,这个函数运行,这个函数是fn2调用的(所有的函数引用的call函数都是同一个内置call函数),所以运行fn2里面的打印2
        fn.call.call.call(fn2); //同理,无论多少个call都是调用fn2 打印2
 
posted @ 2022-06-18 11:10  小狐狸ya  阅读(234)  评论(0编辑  收藏  举报