this机制个人理解

1.让this指向本身的方法

首先this并不是指向本身的,它指向谁取决于它的调用位置。

function classA(num){
            console.log('classA'+num);
            this.count++;//this的定义位置在classA作用域中
        }
        classA.count=0;
        for(var i=0;i<=10;i++){
            if(i>5){
                classA(i);//this的调用位置在全局作用域中
            }
        }
    console.log(classA.count);//结果count是全局变量的0

 1.1使用词法作用域(在函数内部调用函数本身)   

function classA(num){
            console.log('classA'+num);
            classA.count++;//每次都调用自身的count
        }
        classA.count=0;
        for(var i=0;i<=10;i++){
            if(i>5){
                classA(i);
            }
        }
console.log(classA.count);

1.2强制让this指回函数本身(使用了call方法)

function classA(num){
            console.log('classA'+num);
            this.count++;
        }
        classA.count=0;
        for(var i=0;i<=10;i++){
            if(i>5){
                classA.call(classA,i);//使用call改变this的上下文,使其指向classA
            }
        }
  console.log(classA.count);

 2.this指向谁完全取决于它在什么地方被调用,不取决于它的定义位置,和函数声明的位置没有任何的关系。

   2.1怎么找调用位置

    调用位置就在当前正在执行的函数的前一个调用中。(调用栈)

  2.2函数的执行过程中调用位置如何决定this的绑定对象(绑定规则)

      (1)默认绑定

          函数直接被调用,没有任何的函数引用来调用它,这时候this绑定的是全局对象。默认绑定无法应用其他规则。

     注意:将全局对象用于默认绑定的前提是是在非严格模式下,如果是在严格模式(strict mode )下,this会绑定到undefined。

function foo(){
            this.a;
        }
        foo();//默认绑定:foo直接被调用,这时候this指向全局对象window

   (2)隐式绑定

     调用位置是否有上下文对象,或者说是否被都个对象拥有或包含。

function foo(){
            console.log(this.a);
}
var obj={
     a:2,
   foo:foo//函数foo被包含在obj对象中
}
 obj.foo();//调用位置被将this绑定到foo上下文obj上

  注意:隐式绑定可能会丢失绑定的对象,进而应用默认绑定,将this绑定到全局对象或undefined上。   

 function foo(){
        console.log(this.a);
       }
       function dooFoo(fn){
        fn();
       }
       var obj={
           a:2,
           foo:foo
       }
       var a="oops,global",
       dooFoo(obj.foo);//oops,global//根据调用位置,被转移成默认绑定

     (3)显示绑定(call()和apply())

           硬绑定:创建一个函数,并在它的内部手动调用foo.call(obj),因此强制把foo的this绑定到了obj,无论之后如何调用函数bar,它总会手动的在obj上调用foo。例子:

function foo(){
  console.log(this.a);
}
var obj={
   a=2;
}
var bar={
    foo.call(obj);//创建一个bar,手动的将foo的this绑定到obj上。
}

bar();//2
setTimeout(bar,100);//2
//注意硬绑定的bar不可能再修改它的this
bar.call(window);//2

          应用场景1:创建一个包裹函数      

function foo(something){
        console.log(this.a,something);
        return this.a+something;
      }
      var obj={
        a:2
      };
      var bar=function(){
        return foo.apply(obj,arguments);//创建一个bar函数,然后将this硬绑定到obj上,并将arguments作为参数传入foo
      };
      var b=bar(3);
console.log(b);

应用场景2:创建了一个可以重复使用的辅助函数

由于硬绑定是一种非常常用的模式,所以ES5提供内置方法:Function.prototype.bind().

    foo.bind(obj);

API调用的“上下文”

(4)new 绑定

    new来调用函数的时候(构造函数调用)自动执行下面的操作。

     4.1创建一个全新的对象;

     4.2这个新对象会被执行[[Prototype]]连接;

     4.3这个新对象会绑定到函数调用的this上;

     4.4如果函数没有返回其他对象,则new表达式中的函数调用会自动返回这个新对象。

           var classA=new ClassA();

       其内部的执行过程:

            

var classA={ };
classA._proto_=ClassA.prototype;
ClassA.call(classA);

  this绑定的优先级:

     new绑定>显示绑定>隐式绑定>默认绑定

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值