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. 所有的函数对象都有call()方法(它的原型对象Function.prototype上有call方法);
  2. 运行的函数是say函数;
  3. 调用这个函数的对象是obj2。
  4. 多个对象可以引用同一个函数。

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

        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

你可能感兴趣的:(笔记,javascript,学习,前端)