JavaScript 中 this 的指向问题

一、this指向问题

(非箭头函数只看调用形式)

1. 直接调用形式:"test()";

  • 直接不带任何引用形式去调用函数,this指向window对象,在严格模式下,是undefined(后文解释)
setTimeout(fn,time);//window
function test(){
    setTimeout(function(){
        console.log(this);
    })
} 
test();   //window

2. "xxx.test()";

  • 谁调用这个函数,this就绑定在谁身上。
  • aaa.bbb.ccc.text(); //指向ccc

3. "test.call(xxx)"/"test.apply(xxx)"/"test.bind()"

  • 指定this

4. "new test()"

var a = 1;
function test (a) {
    this.a = a;
}
var b = new test(2);
console.log(b.a);//2,this指的是new出来的对象b

5. 箭头函数this

  • 普通函数只有在调用的时候才会确定该函数内this的指向。
  • 箭头函数的this在函数定义的时候就已经确定了,它的this指向的是它的外层作用域this的指向。
{
    var b = 100;
    const a = {
        b :200,
        test:function A(){
            var B = () => {
                var C = () => {
                    console.log(this.b);//A的上下文,即a(该箭头函数所在环境为A)
                }
                C();
            }
            B();
        }
    }
    a.test(); //200
}
{ //obj上下文
    var x=11;
    var obj={
        x:22,
        say:()=>{
            console.log(this.x); //obj的上下文,即{}包括的环境(该箭头函数所在环境为obj)
        }
    }
    obj.say(); //11
} //obj上下文

二、深入理解

1. 全部转换为call方式

  • 第一种和第二种形式的函数可以等价变成fun.call(context,p1,p2),其中context就是this。

    func(p1,p2) ==> func.call(undefined,p1,p2)
    obj.child.method(p1,p2) ==> obj.child.method.call(obj.child,p1,p2)

  • 浏览器里面有一条规则:如果传进来的context为null或者undefined,那么window对象就是默认的context,在严格模式下,context是undefined

2. []语法

function fn (){
     console.log(this) ;
}
var arr = [fn, fn2];
arr[0]();    //this指的是数组arr
  • 我们可以把 arr[0]( )想象为arr.0( ),虽然后者的语法错了,但是形式与转换代码里的 obj.child.method(p1, p2) 对应上了,于是就可以愉快的转换了:

arr[0]()
假想为 arr.0()
然后转换为 arr.0.call(arr)
那么里面的 this 就是 arr 了

3. 事件绑定中this指事件本身

三、如何确定 this 的值:

  • 看源码中对应的函数是怎么被 call 的(这是最靠谱的办法)
    看文档
  • console.log(this)

你可能感兴趣的:(JavaScript 中 this 的指向问题)