js10---this的引用劫持(call,apply,bind)

190 阅读2分钟

call apply 方法

1.函数的call apply调用函数时,通过参数1 修改this

2.call 接受的实参可以是n个,其他的每一项参数再被函数的每一项实参接受

3.apply 接收的实参只接受两个,另一个实参会被解析后赋值给每一项实参

 function fn(a,b,c) {
        console.log(arguments.length);
        console.log(a,b,c);
        console.log(this);
        console.log(this.username);
        console.log("good");
        
    }
    var obj1={
        username:"lx"
    },obj2={
        username:"ygx"
    }

fn.call(obj1,100,200,300);
fn.call(obj2,"a","b","c");

fn.apply(obj1,[100,200,300]);
fn.apply(obj2,["a","b","c"])

image.png

call例题

    var obj={name:"karen",say:function(str,arg2){console.log(this.name,str,arg2)}}
    var obj2={name:"jack"}
    var obj3={name:"marry"}
    obj.say.call(obj2,100,200) //相当于是obj2在调用say方法
    obj.say.call(obj3,80,10)
    

image.png

分析:obj.say.call(obj2,100,200) 将say方法的this指定为obj2,相当于obj2在调用say方法,将实参100,200传入function(str,arg2){console.log(this.name,str,arg2),打印结果为jack,100 200

obj.say.call(obj3,80,10)同上

apply例题

1

var obj={name:"karen",say:function(arg1,arg2){console.log(this.name,arg1,arg2,arguments)}}
    var obj2={name:"jack"}
    var obj3={name:"marry"}
    obj.say.apply(obj2,[10,20])
    obj.say.apply(obj3,[100,200])
    obj.say.apply(obj3,[100,200,80,90])
    

image.png

分析: obj.say.apply(obj3,[100,200,80,90]),将say方法的this指定为obj3,将数组[100,200,80,90]解析为4个实参传入say方法,say方法按顺序接收实参。obj.say.apply(obj3,[100,200,80,90]), 相当于假装obj3也有say方法,obj3.say(100,200,80,90)

2 找出数组最大值

var arr=[10,230,40,6,2];
var maxnum=Math.max.apply(null,arr);//相当于假装null有max方法  null.max(10,230,40,6,2)==>230
console.log(maxnum)

image.png

分析:var maxnum=Math.max.apply(null,arr),将say方法的this指定为null,相当于假装null有max方法 ,将数组解析为5个实参传入max方法,找出最大值

bind

1.定义式的函数可以在设计的时候就指定this

  var obj2={name:"jack"}
  var obj={
      name:"karen",
      say:function(){
          console.log(this)
      }.bind(obj2)
  }		  
  obj.say()
  var obj3={name:"marry"}
  obj.say.call(obj3)
  obj.say.apply(obj3,[])

image.png 分析:say:function(){ console.log(this) }.bind(obj2)将say方法的this绑定为obj2,不会受到call方法和apply方法的影响

2.函数bind 返回值新函数,给新函数绑定好this 的指向

   var obj={
   pName:"讲桌"
   }
   //函数bind  返回值新函数,给新函数并绑定好this 的指向
   var newFn=fn.bind(obj);
   
   
   console.log(  newFn );
   console.log(  typeof newFn );
   console.log(  newFn==fn );//false,新构建的函数与原函数并不是同一个,重新开辟了一块空间
   
   
   fn()
   newFn();
   
   
   var newObj={
   pName:"鼠标",
   newFn:newFn
   }
   newObj.newFn()//newFn的this已经被绑定为obj
   

image.png

拓展

    function fn () {
    	console.log(1)
    }
    function fn2 () {
    	console.log(2)
    }
    fn.call.call(fn2)
    

image.png

分析: fn.call.call(fn2),fn.call是一个函数它有call方法。fn.call引用了一个函数,这个函数运行。fn.call是一个函数这个函数是fn2调用的,相当于fn2在调用call方法,fn2.call()。不管有多少次call调用只看两次就行了