JS this指示器

this指示器估计是很多人都会很头疼的一个东西,它的指向永远都让人觉得捉摸不定。今天我就通过这篇文章来记录一下我对this指示器的一些学习笔记与自己的理解。
如果有错误或者叙述不当的地方,请大家不吝赐教!

this是什么?

要理解this的用法,就要先知道this到底是何物。
this在JS中是一个关键字,是指在函数运行时自动生成的一个内部对象,指向函数执行时的环境对象,换句话说this也就是代表着是谁在调用这个函数。

this的几种应用场景

  • 在全局环境中执行函数
    var name = "hu";
    function fn1(){
        var name = "zhou";
        alert(this.name);
        alert(this);
    };
    fn1();

运行上面代码可以看到结果输出

hu;
[object Window]

可见在全局环境中执行函数,函数中this指向的是全局对象window,window就是fn1执行时的环境对象。

  • 函数作为对象的属性执行的时候
    var name = "hu";
    var obj = {
        name : "zhou",
        getName : function(){
            alert(this.name);
            alert(this);
        } 
    };
    obj.getName();

运行以上代码得到结果:

zhou;
[object Object];

可以很明显的看出来,输出的name是obj对象中的name属性并非全局的name属性,this指向的是obj对象。
此时obj就是调用getName函数的对象。getName函数是在obj的作用域下执行的。

  • 在构造函数中使用
    function Constructor(){
        this.name = "hu";
        this.age = "20";
    }
    var person = new Constructor();
    alert(person.name);
    alert(person.age);

运行以上代码会看到结果:

hu;
20;

person是Constructor的一个实例,可以看出在通过new操作符创建Constructor的实例时this指向的是person对象。
那么,创建实例这个过程是怎么实现的呢?为什么person对象会是构造函数Constructor的环境对象呢?
那就需要了解通过new来创建实例的过程:

    • 首先创建一个Constructor的实例对象;

    • 将对象的作用域绑定到这个对象;

    • 再通过构造函数的内容初始化该对象;

    • 构造函数返回该对象并赋值给person变量,当然person变量保存的是指向该对象的指针。

所以了解了new操作符创建实例的过程后this指向就很容易理解了

  • 通过apply(),call()调用
    apply()和call()函数一样,可以改变函数的执行环境对象。
    var name = "hu";
    var person = {
        name : "zhou";
    };
    function fn1(){
        alert(this.name);
    }
    fn1();

执行以上代码,可以看到结果为

hu;

因为在第一种情况中已经说明过,在全局环境中执行,this指向的是全局对象。那边下面来改写代码:

    fn1.apply(person);//fn1.call(person);

运行以上代码可以得到结果:

zhou;

这就是apply(),call()改变函数执行环境的作用,此时fn1的作用域就是person对象,所以this指向的就是person对象。

  • 事件侦听器
    var target = $(" #target ");
    window.click(function(eve){
        alert(this);
        alert(eve.target);
    });
    target.click();

执行以上代码可以看到结果:

[object Window];
[object HTMLELement];

从以上结果可以看出,当通过事件触发事件侦听器的时候,this指向的是事件的注册对象,而event.target指向的是事件触发是真正的对象。

那么,为什么要使用this呢?

首先看一段代码:

var getPersonName = (function(){
    var person = {
        name : "hu",
        getName : getName
    };
    function getName(){
        return person.name;
    };
    return person.getName;
})();
getPersonName();

在以上代码中,通过一个匿名函数创建了一个私有对象person,并把person的getName方法暴露给外界。
通过调用person.getName方法可以正确的拿到person对象的name属性,但是这样的代码耦合程度太高,getName函数没有办法重用,只能用于person对象。
假设这样一个场景,假设有一天person的名字不再是person,改成dog了,那getName函数也得更改,如果只有一个person要改名还可以更改,但是如果成百上千的person都要改名呢?
所以可以改写如下代码:

function getName(){
    return this.name;
}

这样改写getName函数之后可以降低函数与对象之间的耦合度,而且getName函数也可以在不同的对象中重用。

此篇博客就先到此,如果以后有更好的总结或者理解,我会补充更新。写的不好,请见谅。

说明:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值