this的详细分析加案例

this对象是在函数运行时候基于函数的执行环境(上下文)绑定的

  1. 方法调用模式
  2. 函数调用模式
  3. 改造器调用模式
  4. apply,call,bind调用模式

1.方法调用模式

函数有所属对象,也就是这个函数是myObject.打点声明的的时候this是这个对象的本身,不可以说永远this都是myObject.

当一个函数被保存在为对象的一个属性的时,我们称它为一个方法,当一个方法被调用时,this被绑定到该对象;

    var myObject = {
        value :0,//记得这里是逗号不是分号
        increment :function(inc){
            console.log(this.value);//this为myObject
        }
    }
        myObject.increment();//0


2.函数调用模式


 当函数并非一个对象的属性时,那么它被当做一个函数来调用,this被绑定到全局对象(因为这个时候foo这个函数的上下文是window绑定的,this就指向window);
          

    // 当执行myObject.getVlue时候

    var myObject = { value: 100 }//创建myObject对象
    myObject.getVlue = function () {
      console.log(this.value);//100  这里的this值为myObject对象
      var foo = function () {
        console.log(this);//window; 调用foo()他的对象winfdow,所以函数的上下文(this)为window
        console.log(this.value);//undefined,window没有设置value的值
      }
      foo(); //函数上下文是window,所以这里的this是window,文是window
    }
    console.log(myObject.getVlue());//没有设置返回值return


 这里的foo函数就相当于,方法中的函数:这个函数与方法中的this是不同的(作用链的关系),这里的foo函数可以是一些其他的函数
 注意:这里有个很麻烦的东西就是myObject.getVlue()函数中的this与foo()函数中的this不同为了为了让他们相同怎么办呢?
 来来:就是赋值呵呵myObject.getVlue()函数中的this赋值给一个变量(that)就可以了
          

var myObject = {value: 100}//创建myObject对象
myObject.getVlue = function(){
    console.log(this.value);//100这里的this值为myObject对象
    that = this;//关键吧myObject对象转给了that这个变量(因为foo函数的上下文为window,想在foo函数中用myobject对象就把myobject对象赋值出来)
    var foo = function(){
        console.log(this);//window; 调用foo()他的对象winfdow,所以函数的上下文(this)为window
        console.log(that)//为myObject
        console.log(this.value);//undefined,window没有设置value的值
        console.log(that.value);//100
     }
     foo();//函数上下文是window,所以这里的this是window,文是window
}
console.log(myObject.getVlue());//没有设置返回值return

3.构造器中的this:值向新的函数


   js中,我们通过new关键词来调用构造函数,此时this会绑定在该对象上
            

    var someClass = function () {
      this.value = 100;
    }
    someClass();
    console.log(window.value);//100说明了这个时候的this还是指向全局对象

    var myCreate = new someClass();//构造对象;
    console.log(myCreate.value);//这里this值向了myCreate

集合以上3个点来搞下面的这个题
            

    var name = "222";
    var a = {
      name: "111",
      say: function () {
        console.log(this.name);
      }
    }
    var fun = a.say;
    fun(); // 222
    a.say(); // 111 
    var b = {
      name: "333",
      say: function (fun) {
        fun();
      }
    }
    b.say(a.say); // 222 //这里为什么是222 这里的this为什么不是呢?应为这里b.say(a.say)执行的是function(fun){}函数,难后函数里面再执行fun(),这里的fun()为全局的执行上下文
    b.say = a.say;
    b.say(); // 333

这个题目真的是难的,但也不难就是看引用他的时候函数的执行上下文是谁

1.fun = a.say :定义了一个变量fun指向了a.say中的一个函数,所以当执行fun()的时候,fun()的执行期上下文为window,而和a.say()中this的执行是不一样的

2.a.say()函数上下文为那么就是a了

3.为什么是222,这里可以理解为 形参数fun等与了实参a.say,那么fun()的执行期一样也就是window

4.b.say(),这里也要注意虽然答案很好得到,但是我们要知道是为什么?这里的赋值这是该变了一下引用地址,当我们顺的那个指针去找函数上下文的时候那么就是b了,其实也就是说虽然里面执行的函数是在对象a中的但是呢?我们通过b.say = a.say;已经把函数执行其改为了b了

例子

this其实就是执行上下文中(词法环境中的一部分),而这里obj.a中是在全局执行上下中所以this为windew

 

    a = 1
    obj = {
      a: 3,
      b: this.a,   
      c: function () {
        console.log(this); //{a: 3, b: 1, c: ƒ}
        return this;
      }
    }
    console.log(obj.b) //1
    console.log(obj.c()) //{a: 3, b: 1, c: ƒ}

 

4.apply和call调用以及bind绑定:指向绑定对象;      

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

三者的差别

1.bind方法返回一个新的函数,你必须调用它才可以执行.

2.call的参数和bind一样第二第三第 n 个参数全都用逗号分隔,直接放到后面 obj.myFun.call(db,'成都', ... ,'string' ).

3.  apply 的所有传的参数都必须放在一个数组里面传进去 obj.myFun.apply(db,['成都', ..., 'string' ])
当然,三者的参数不限定是 string 类型,允许是各种类型,包括函数 、 object 等等!

用途

bind:有的时候当你只是想定义不想执行的时候用bind(),比如React在JSX元素上定义事件的时候

call applp:在使用便需要立马调用的时候

 

  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值