详解 JavaScript 中的 this

版权声明:本文为博主原创文章,若转载请注明出处且不得删改。(如有错误请提出指正,部分文章会参考其他文章,已经表明参考出处,如有侵权请联系删除) https://blog.csdn.net/qq_34902437/article/details/81477465

参考

《JavaScript 设计模式与开发实践》

前言

JavaScript 的 this 总是指向一个对象,这个对象就是运行时局域函数的执行环境来动态绑定。

this 指向的四种情况

  1. 作为对象的方法调用
  2. 作为普通函数(方法)调用
  3. 构造器(构造函数)调用
  4. call 和 apply 的调用

作为对象的属性方法被调用

作为对象的方法被调用的时候,this 指向该对象。

一个实例

var obj = {
    name:"张三",
    //getName 此时是对象 obj 的一个属性(方法)
    getName:function(){
        alert(this.name);
    }
}

//张三
obj.getName();

作为普通函数被调用

当函数不是作为对象属性被调用的时候,就是作为普通函数被调用。此时 this 指向全局对象,在浏览器环境中就是 window 对象

一个实例

window.name = "张三";

var obj = function(){
    alert(this.name);
}

//张三
obj();

一个容易出错的地方

window.name = "全局对象";

var obj = {
    name:"属性对象",
    getName:function(){
        alert(this.name);
    }
}

var obj2 = obj.getName();
//属性对象
obj2;

var obj3 = obj.getName;
//全局对象
obj3();

分析:对于 obj2 ,我们把 obj 的方法 getName()赋给了 obj2 , 我们知道方法也是对象,所以是可以这样进行的,因为赋值本身是对象属性的调用,所以 this 指向对象。而对于 obj3,因为 是把 obj.getName 的指针赋给了 obj3 (如果函数没有加圆弧括号是指函数指针),所以, obj3 此时作为普通函数的函数名,所以 this 指向全局对象。

另一个容易出错的地方
比如我们对某个 元素进行操作的时候(比如一个点击事件),如果我们相对这个操作执行一个回调函数,但是此时回调函数是一个普通函数,它的 this 指向 window 对象,而不是我们想要的 这个元素节点,我们怎么办呢,通过一个实例来了解。

    //window 可以不要,因为默认是 window
    window.id = 'window';

    document.getElementById("div1").onclick = function(){
        // 弹出警告框 div1
        alert(this.id);
        var callback = function(){
            alert(this.id);
        }

        // 弹出警告框 window
        callback();
    }

正式因为 callback( ) 函数不是某个对象的属性,所以调用全局,但是我们往往希望是调用 “这个” 元素结点,所以有下面的改进方式。

    //window 可以不要,因为默认是 window
    window.id = 'window';

    document.getElementById("div1").onclick = function(){
        // 弹出警告框 div1
        alert(this.id);
        var improve = this;
        var callback = function(){
            alert(improve.id);
        }

        // 弹出警告框 div1
        callback();
    }

我们把这个函数的 this 付给一个变量 improve,然后后面在 callback ()中调用 improve 就可以解决这个问题了。

作为构造器(构造函数)被调用

构造函数和普通函数的区别在于,调用的时候,构造函数是通过 new 关键字调用
默认情况下,构造函数会自动返回一个对象,而 this 就是指向这个对象的。

一个实例

    var con = function(){
        this.name = "构造函数";
    }

//构造函数调用
    var obj = new con();
//弹出警告框 构造函数
    alert(obj.name);

注意:如果在构造函数中显式的 return 一个对象,那么将调用这个显式的内容

    var con = function(){
        this.name = "构造函数";
        return this.name = "这个是显式调用"
    }

    var obj = new con();
    alert(obj.name);

call 和 apply

在借用构造函数的继承方式中(当然还有其他继承的方式)我们使用 call 和 apply 来在子类中调用父类,这个时候就要用到 call 或者 apply 的方法中的 this 上下文,这里不展开说明,有兴趣的同学可以参考《JavaScript 高级教程-继承》的章节。

猜你喜欢

转载自blog.csdn.net/qq_34902437/article/details/81477465