1

this

1.其实js中的this没那么难理解,当找不到this时记住一句话:
谁调我,我就指谁!new 谁指谁

function text1(){
    console.log(this);     //指window因为是window调我了
}
var text2={
    one:function(){
        console.log(this); //指text因为text调我,我就指它!
    }
}

function text3(){
    this.x=this;
}
var t=new text3();
   t.x;                     //指text3 new 谁指谁

apply、call

2.apply和call两个方法的作用都是改变this的指向
来个栗子:

function food(){}
food.prototype={
    color:"red",
    name:'apple',
    sayName:function(){
        console.log('my name is '+this.name); 
    }
}
var text1=new food();

text1.sayName();//my name is apple

var banana={
    name:'banana'
}
var pear={
    name:'pear'
}
text1.sayName.apply(banana); //my name is banana
text1.sayName.call(pear); //my name is pear

apply与call的作用完全一样就是接收参数的方式不同列如:

var fn=function(arg1,arg2){}
apply(fn,[arg1,arg2]);
call(fn,arg1,arg2);

那么当参数,数量固定的时候用call不固定时用apply
这里特别说下函数内的arguments对象他是一个伪数组不能直接使用push等方法
下面写几个栗子展示下他两的实际用法:

//第一个栗子追加数组
var array1=[1,2,3,4,5];
var array2=[6,7,8,9,10];
Array.prototype.push.apply(array1,array2);
array1; //[1,2,3,4,5,6,7,8,9,10]
//第二个栗子求number的最大值
var numbers=[1,10,33,100,-55,423];
Math.max.apply(Math,numbers);
Math.max.call(Math,1,10,33,100,-55,423);
//来个经常用到的代理console.log方法
function log(msg){
    console.log(msg);
}
//上面是常用的写法,但这样 我传的值是 log(1) 没毛病 如果是log(1,2,3)呢?那就有毛病了
//他不管后面传多少参数都会被舍弃掉只会打印1
//改进版本
function log(){
    console.log.apply(console,arguments);
}
//这样不管传多少个参数都能打印出来了

bind

bind() 方法与 apply 和 call 很相似,也是可以改变函数体内 this 的指向。

概念是:bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。

var say=function(){
    console.log(this.x)
}
var one={
    x:1
}
var two={
    x:2
}
var three={
    y:3
}
var fn=say.bind(one);
fn()//1
var fn2=say.bind(two).bind(one).bind(three);//如果连续bind呢?结果会是什么?
fn2();//结果还是第一个bind

原因是,在Javascript中,多次 bind() 是无效的。更深层次的原因, bind() 的实现,相当于使用函数在内部包了一个 call / apply ,第二次 bind() 相当于再包住第一次 bind() ,故第二次以后的 bind 是无法生效的。
那么call、apply、bind三者之间的区别和应用场景是什么呢?

var obj={
    x:81
}
var text={
    fn:function(){
       return this.x;
    }
}
console.log(text.fn.call(obj));//81
console.log(text.fn.apply(obj));//81
console.log(text.fn.bind(obj)());//81

结果都是81,但注意的是bind()后面多了对调用的括号。
那么总结一下:

  1. apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;

  2. apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;

  3. apply 、 call 、bind 三者都可以利用后续参数传参;

  4. bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。


lx_blog
97 声望12 粉丝

geek