首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >你对this的理解正确吗?有趣又神奇的this对象

你对this的理解正确吗?有趣又神奇的this对象

作者头像
写PHP的老王
发布2020-06-04 14:44:11
5010
发布2020-06-04 14:44:11
举报
文章被收录于专栏:写PHP的老王写PHP的老王

在每个面向对象编程语言中都会涉及到一个指向当前对象的值,this( 当然,python不是的)。但是this本身在很多时候都是有"歧义"的,因为不同的理解容易造成意想不到的bug产生。

比如在jquery中的ajax请求,经常会看到下面的代码:

$('#button').click(function(){

    var that = this;
    $.ajax({
        url:'/xxxx/xxxx',
        'data':{},
        'success':function(res){
            if(res.code == 0)
            {
                $(that).hide();
            }
        }
    })

})

之所以需要在请求之前将this对象赋值给that,是因为在成功回调函数中的"this"并不是之前的"this"了。除了通过一个临时变量that保存之外,还可以使用bind的方式制定this。

相同的,在php中也存在回调函数,匿名类对象,闭包等。这些场景都会导致this的指向内容歧义化。

class TestFoo {
    public $foo = 'TestFoo';

    public function getCallback(){
        $currentFoo = $this->foo;
        return function() use ($currentFoo) {
            echo 'current '.$currentFoo.',callback '.$this->foo."\n";
        };
    }
}

$testFoo = new TestFoo();
$closure = $testFoo->getCallback();
call_user_func_array($closure, []);

$context = new \StdClass;
$context->foo = "Hello World";
$boundClosure = $closure->bindTo($context);
$boundClosure();

上面代码分别是输出

current TestFoo,callback TestFoo
current TestFoo,callback Hello World

在php5.4之前的版本,上面的代码其实是会有问题的。必须要写成that的形式

class TestFoo {
    public $foo = 'TestFoo';

    public function getCallback(){
        $currentFoo = $this->foo;
        $that = $this;
        return function() use ($currentFoo,$that) {
            echo 'current '.$currentFoo.',callback '.$that->foo."\n";
        };
    }
}

对于匿名类,则会有更加复杂的

class TestFoo {
    public $foo = 'TestFoo';
    protected $logger;
    public $name = "out";

    public function getCallback(){
        $currentFoo = $this->foo;
        $this->testInnerClass(new class {
            private $name = "innerlogger";
            public function log($msg)
            {
                echo $this->name.' log '.$msg."\n";
            }
        });
        $this->logger->log('test');
        return function() use ($currentFoo) {
            echo 'current '.$currentFoo.',callback '.$this->foo."\n";
        };
    }


    public function testInnerClass($log){
        $this->logger = $log;
    }


}

$testFoo = new TestFoo();
$closure = $testFoo->getCallback();
call_user_func_array($closure, []);

上面代码输出内容是:

innerlogger log test
current TestFoo,callback TestFoo

通过上面的分析,相信大家对this会有新的认识。在编码过程中,要注意this对象的实际指向,避免产生不必要的bug。这种问题,如果产生bug,是很难排查的。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 写PHP的老王 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档