脚本宝典收集整理的这篇文章主要介绍了

浅谈javascript里面的this、call、apply、bind

脚本宝典小编觉得挺不错的,现在分享给大家,也给大家做个参考,希望能帮助你少写一行代码,多一份安全和惬意。

在了解call,apply之前需要先了解下javascrit中this指向

this的指向
在ES5里面,this永远指向最后调用它的那个对象
举个栗子:

var name = "outerName";
function test(){
    var name = "innerName";
    console.log(this.name);  //outerName
    console.log("inner:" + this);  //inner:Window
}
test();
console.log("outer:"+this);//outer:Window

我们最后调用test的地方test();,前面没有调用的对象那么就是全局对象window,相当于window.test();注意这里没有使用严格模式,如果使用严格模式,全局对象就是undefined,那么就会报错Uncaught TypeError:cannot read property 'name' of underfined

在举个栗子:

var name = "outerName";
var test = {
    name:"innerName",
    fn:function(){
        console.log(this.name); //innerName
    }
};
test.fn();
window.test.fn();

这里打出的是innerName,因为fn是test调用的

还有个略坑的栗子:

var name = "outerName";
var test = {
    name:null,
    fn:function(){
        console.log(this.name); //outerName
    }
};
var f = test.fn
f();

这里打出的outerName因为f并没有被调用,fn()仍然是window调用的

再看看这个栗子:

var name = "outerName";
function fn(){
    var name = "innnerName";
    innerFn();
    function innerFn(){
        console.log(this.name); //outerName
    }
};
fn();

这里打出的是outerName,因为仍然是window调用的

总结一下:
this的指向并不是在创建的时候就可以确定的,在ES5里面,this永远是指向最后调用它的那个对象。

改变this指向

那我们怎么才能改变this指向呢,总结一下

  1. 使用ES6的箭头函数
  2. 在函数内部使用_this=this;
  3. 使用call、apply、bind
  4. new 实例化一个对象

继续看一个栗子:

var name = "outerName";
var test = {
    name:'mm',
    fn1:function(){
        console.log(this.name);
    },
    fn2:function(){
        setTimeout(function(){
            this.fn1(); 
        },0);
    }
};
test.fn2(); //this.fn1 is not a funtion

箭头函数
ES6中的箭头函数是可以避免ES5中的this的坑的,箭头函数始终指向定义时的this,而非执行时。
箭头函数中没有this绑定,必须通过查找作用域链来觉得其值,如果箭头函数被非箭头函数包含,那么this绑定的是最近一层非箭头函数的this,否则,this为undefined.
调整后的栗子:

var name = "outerName";
var test = {
    name:'mm',
    fn1:function(){
        console.log(this.name);
    },
    fn2:function(){
        setTimeout(() => {
            this.fn1(); 
        },0);
    }
};
test.fn2(); //mm

在函数内部使用_this = this
_this指的是test对象

var name = "outerName";
var test = {
    name:'mm',
    fn1:function(){
        console.log(this.name);
    },
    fn2:function(){
        var _this = this;
        setTimeout(function(){
            _this.fn1(); 
        },0);
    }
};
test.fn2(); //mm

使用call,apply,bind

var name = "outerName";
var test = {
    name:'mm',
    fn1:function(){
        console.log(this.name);
    },
    fn2:function(){
        setTimeout(function(){
            this.fn1(); 
        }.apply(test),0);
    }
};
test.fn2(); //mm
var name = "outerName";
var test = {
    name:'mm',
    fn1:function(){
        console.log(this.name);
    },
    fn2:function(){
        setTimeout(function(){
            this.fn1(); 
        }.call(test),0);
    }
};
test.fn2(); //mm
var name = "outerName";
var test = {
    name:'mm',
    fn1:function(){
        console.log(this.name);
    },
    fn2:function(){
        setTimeout(function(){
            this.fn1(); 
        }.bind(test)(),0);
    }
};
test.fn2(); //mm

具体有什么区别呢
看下MDN上的解释

apply
语法:
fun.apply(thisArg,[argsArray]);
参数
thisArg
在fun函数运行时指定的this值,需要注意的是,指定的this的值不一定是该函数执行时真正的this值,如果这个函数处于非严格模式下,则指定为nullundefined时会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象。
argsArray
一个数组或者类数组对象,其中数组原始将作为单独的参数传给fun函数。如果该参数的值为null或undefined,则表示不需要传入任何参数,从ECMAScript5开始可以使用类数组对象。

call
语法
fun.call(thisArg,arg1,arg2,...)
参数
thisArg
同上apply
arg1,agr2,...
指定的参数列表

bind
语法
fun.bind(thisArg[,arg1[,arg2[,...]]])
参数
thisArg
当绑定函数被调用时,该参数会作为原函数运行时的this指向。当使用new操作符调用绑定函数时,该参数无效。
arg1,arg2,...
当绑定函数被调用时,这些参数将置于实参之前传递给被绑定的方法。

在总结一下:
apply,call,bind都是用来改变函数的this对象的指向;
第一个参数都是this要指向的对象,也就是指定的上下文;
都可以利用后续参数传参;
apply,call是立即调用,bind是返回对应函数,需要手动调用。

总结

以上是脚本宝典为你收集整理的

浅谈javascript里面的this、call、apply、bind

全部内容,希望文章能够帮你解决

浅谈javascript里面的this、call、apply、bind

所遇到的程序开发问题,欢迎加入QQ群277859234一起讨论学习。如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典网站推荐给程序员好友。 本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。

80%的人都看过