程序员

懒人学js:怎么理解this在js里的指向问题

2018-06-06  本文已影响23人  麦劲

尝试用简单直观的方法,为学编程的朋友提供一种思路。

this,在编程语言里,指代某个引用了“this所在的函数”的内存空间。

C++java等语言里,当声明一个,并实例化一个对象时,this指的是这个对象所在的(复制出来的)内存空间。

图片1.png

所以用this.xx的语法可以引用该内存块内的各种变量。

c++等程序经过编译成机器码后,每个this都有固定的内存块指向,所以this的指向很明确。

js是一种脚本解释型语言,支持函数式编程,所有函数在执行前,都是以字符串的形式存在的。

图片2.png

除了可以在a1里直接引用

a1.f1();

实例a1里的函数f1的函数内容,还可以通过赋值语句传给其他对象使用(这是非函数式编程语言做不到的)


var k1=a1.f1;

k1();

这时,函数的实际执行内存空间,就变成了k1所在的内存空间。

那么这个空间是哪里呢?

js里,当某个对象没有显式声明时,都会自动挂载在全局对象window上。

所以上述例子k1();相当于window.k1();函数中的this,指代的就是window了。

图片3.png
而当k1有显式声明的所有者时

var owner={};

owner.k1=a1.f1;

owner.k1();

执行时,this所在的内存空间为owner,所以这里this指代的是owner

PS:这里可以再深究owner所在的内存空间,其实也是window,但是this只会指向最终引用它的那一块内存空间,不会再往上指向。

完整示例如下

var p = 2;     //挂载在window上的p=2

var a1 = {

    p: 1,    //a1里的p=1

    f1: function() {

        console.log(this.p);

    }

}

a1.f1(); //这里输出 1

k1 = a1.f1;

k1();  //这里输出 2

var owner = {};

owner.p = 3;    //挂载在owner里的p=3

owner.k1 = a1.f1;

owner.k1();  //这里输出 3

几种特殊情况

  1. 使用严格模式时(在代码首行加上'use strict'),只有直接引用时this会生效,通过赋值给其他对象使用的话,this会报错。

  2. 箭头函数里的this,会自动绑定定义时所在的内存空间,不会发生指向变化。

  3. 闭包所在的一阶函数内的this,因为闭包会自动挂载在window下,这时候this指代window

  4. js支持在函数内定义另一个函数,这时候定义出来的函数如果没有显式执行,也会自动挂载在window上。

function a(){
     function b(){
        this....
    }
    return b();  //b自动挂载在window上执行,相当于window.b()
}
a();    //这时函数b里的this指代window
上一篇 下一篇

猜你喜欢

热点阅读