JS中call()、apply()、bind()的用法

eg1:
var name = '小王', age = 17;
var obj = {
    name: '小张',
    objAge: this.age,
    myFun: function(){
        console.log(this.name+"年龄"+this.age)
    }
}
obj.objAge;   // 17
obj.myFun() ;  // 小张年龄 undefined

eg2:
var fav = ‘啦啦’
function shows(){
  console.log(this.fav);
}
shows();  // 啦啦

第一个打印里面的 this 指向 obj,第二个全局声明的 shows() 函数 this 是 window; 

1. call()、apply()、bind()都是用来重新定义this这个对象的。

var name = '小王', age = 17;
var obj = {
    name: '小张',
    objAge: this.age,
    myFun: function() {
        console.log(this.name+"年龄"+this.age)
    }
}
var db = {
    name:'德玛',
    age: 99,
}
obj.myFun.call(db);    // 德玛年龄 99
obj.myFun.apply(db);    // 德玛年龄 99
obj.myFun.bind(db)();     // 德玛年龄 99

2. 区别 :对比call()、bind()、apply()的传参

var name = '小王', age = 17;
var obj = {
    name: '小张',
    objAge: this.age,
    myFun: function(from,to) {
        console.log(this.name+"年龄"+this.age,"来自"+ from + "去往"+ to)
    }
}
var db = {
    name:'德玛',
    age: 99,
}
obj.myFun.call(db,'成都','上海');    // 德玛年龄 99  来自成都去往上海
obj.myFun.apply(db,['成都','上海']);    // 德玛年龄 99  来自成都去往上海
obj.myFun.bind(db,'成都','上海')();   // 德玛年龄 99  来自成都去往上海
obj.myFun.bind(db,['成都','上海'])();   // 德玛年龄 99  来自成都,去往 undefined

· call( ) 是接收一个及其以上的参数,第一个参数表示this要指向的对象,其余参数表示调用函数需要传入的参数,返回调用函数的返回结果,属于立即执行函数;
· apply( ) 是接收两个参数,第一个参数表示this要指向的对象,第二参数表示调用函数需要传入的参数所组成的数组,返回调用函数的返回结果,属于立即执行函数;
· bind( ) 是接收一个及其以上的参数,和call()一致,但是其返回是一个函数,而不是调用函数的返回结果;
当然,三者的参数不限定是 string 类型,允许是各种类型,包括函数 、 object 等等!

3. 作用

       在js中,所有的函数在被调用的时候都会默认传入两个参数,一个是this,还有一个是arguments。在默认情况下this都是指当前的调用函数的对象。但是有时候我们需要改变this的指向,也就是说使函数可以被其他对象来调用,那么我们应该怎样做呢?这时候我们就可以使用call,apply和bind方法了。

       在面向对象的JS中,我们了解到在JS中,一切都是对象。因为一切都是对象,我们开始明白我们可以为函数设置和访问其他属性。而this提供了一种更优雅的方式隐式“传递”一个对象的引用。

  关于this,我们常见的误区:认为this指向函数本身

function f1() {
    console.log(this)
}
f1() // window 

        函数的调用方式决定了this的值。它指向什么完全取决于函数在哪里被调用,也就是说,谁调用,谁负责。而bind()、apply()、call()则是可以更改this指向的方法。请看下面例子:

var a = {
    user:"bahg",
    fn:function(){
        console.log(this.user);
    }
}
var b = a.fn;
b(); //undefined

        我们是想打印对象a里面的user却打印出来undefined是怎么回事呢?因为b()相当于window.b(),this指向window,如果我们直接执行a.fn()是可以的:

var a = {
    user:"bahg",
    fn:function(){
        console.log(this.user);
    }
}
a.fn(); //bahg

        这里能够打印是因为,这里的this指向的是函数a,那为什么上面的不指向a?我们如果需要了解this的指向问题,请看 this指向问题_93 Million Miles-的博客-CSDN博客https://blog.csdn.net/m0_52545254/article/details/125758510?spm=1001.2014.3001.5501这篇文章。

       虽然这种方法可以达到我们的目的,但是有时候我们不得不将这个对象保存到另外的一个变量中,那么就可以通过call、apply、bind方法。

4. 使用

(1).  call

var a = {
    user:"bahg",
    fn:function(){
        console.log(this.user); 
    }
}
var b = a.fn;
b.call(a);   // bahg

此时打印的就不再是undefined了,通过call方法使得b的this指向a对象,而不是window。call方法除了第一个参数以外还可以添加多个参数,这些参数会传入函数,如下:

var a = {
    user:"bahg",
    fn:function(a,b){
        console.log(this.user); //bahg
        console.log(a+b); //3
    }
}
var b = a.fn;
b.call(a,1,2);

(2).  apply
       apply方法和call方法有些相似,它也可以改变this的指向。区别在于传递多个参数时必须使用数组,如下:

var a = {
    user:"bahg",
    fn:function(a,b){
        console.log(this.user); /bahg
        console.log(a+b); //11
    }
}
var b = a.fn;
b.apply(a,[10,1]);

注意:如果call和apply的第一个参数写的是null,那么this指向的是window对象
(3).  bind

var a = {
    user:"bahg",
    fn:function(a,b,c){
        console.log(this.user); //bahg
        console.log(a,b,c); //10 1 2
    }
}
var b = a.fn;

// b.bind(a); 不会输出任何结果
// var c = b.bind(a);
// console.log(c);   输出 function() { [native code] }
// var c = b.bind(a,10,1,2); 
// c();   // 输出结果

       bind方法可以让对应的函数想什么时候调就什么时候调用,并且可以将参数在执行的时候添加,这是它们的区别,可以根据自己的实际情况来选择使用。
-------------------------------------------------------------------------------------------------------------------------------
部分内容转载于JS中call()和apply()以及bind()的使用及区别 - BAHG - 博客园

猜你喜欢

转载自blog.csdn.net/m0_52545254/article/details/125736945