this 、call与apply的使用

this

js 的this总是指向一个对象,而具体指向哪个对象是在运行时基于函数的环境动态绑定的,而非函数被声明时的环境

this的指向

除去with和eval情况,this的指向大致分为以下4种

  • 作为对象的方法调用
  • 作为普通函数调用
  • 构造器调用
  • call和apply调用
  1. 作为对象的方法调用,this指向该对象

    var obj = {
        a:1,
        getA:function(){
            alert:(this === obj)//输出 true
            alert:(this.a)//输出 1
        }
    }
    
  2. 作为普通函数调用,此时this指向全局,如在浏览器中指向window对象

    window.name = 'globalName'
    
    var myObject = {
        name:'obj',
        getName:function(){
            console.log(this.name)
        }
    }
    var getName = myObject.getName
    getName() // 输出globalName,即全局。
    
  3. 构造器调用:通常情况下,构造器里的this指向new返回的对象

    如果构造器显式的返回一个object对象,this会指向显式返回的对象

  4. call与apply,可以动态地改变传入函数的this。call和apply很好的体现了js的函数式语言特性。

call和apply的区别

  1. apply和call接收的第一个参数都指定函数体内this的指向。

  2. 第二个参数,apply接收一个数组或类数组,call从第二个参数开始,每个参数都被依次传入函数作为参数。

  3. 如果第一个参数为null,函数体内的this指向默认的宿主对象,即window等

  4. 有时候我们使用 call 或者 apply 的目的不在于指定 this 指向,而是另有用途,比如借用其他对象的方法。那么我们可以传入 null 来代替某个具体的对象:

    Math.max.apply( null, [ 1, 2, 5, 3, 4 ] ) // 输出:5
    

call和apply的用途

  1. 改变函数内部this的指向

    在实际开发中,经常会遇到 this 指向被不经意改变的场景,比如有一个 div 节点,div 节点的 onclick 事件中的 this 本来是指向这个 div 的:

    document.getElementById( 'div1' ).onclick = function(){ 
     alert( this.id ); // 输出:div1 
    };
    

    假如该事件函数中有一个内部函数 func,在事件内部调用 func 函数时,func 函数体内的 this就指向了 window,而不是我们预期的 div,见如下代码:

    document.getElementById( 'div1' ).onclick = function(){ 
     alert( this.id ); // 输出:div1 
     var func = function(){ 
     alert ( this.id ); // 输出:undefined 
     } 
     func(); 
    };
    

    这时候我们用 call 来修正 func 函数内的 this,使其依然指向 div:

    document.getElementById( 'div1' ).onclick = function(){ 
     var func = function(){ 
     alert ( this.id ); // 输出:div1 
     } 
     func.call( this ); 
    };
    
  2. Function.prototype.bind:用于指定函数内部this指向

  3. 借用其他对象的方法

    • 借用构造函数,实现类似继承的效果

      var A = function( name ){ 
        this.name = name; 
      }; 
      var B = function(){ 
        A.apply( this, arguments ); 
      }; 
      B.prototype.getName = function(){ 
        return this.name; 
      }; 
      var b = new B( 'sven' ); 
      console.log( b.getName() ); // 输出: 'sven'
      
    • arguments借用数数组的方法

      在操作 arguments 的时候,我们经常非常频繁地找 Array.prototype.push 对象借用方法。

      可以借用Array.prototype方法的对象需要满足以下两个条件

      • 对象本身要可以存储属性
      • 对象的length属性可读写
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值