javascript运行上下文 问题
PHP中文网
PHP中文网 2017-04-10 15:48:42
[JavaScript讨论组]
var element = document.getElementById('element');
 
var user = {
 firstname: 'Wilson',
 greeting: function(){
   alert('My name is ' + this.firstname);
 }
};
 
// Attach user.greeting as a callback
element.addEventListener('click', user.greeting);
// alert => 'My name is undefined'

为什么运行的时候,拿不到上下文的值firstname的值

PHP中文网
PHP中文网

认证0级讲师

全部回复(2)
天蓬老师

这不是上下文件的问题,是 this 的问题。

像下面这么改下就对了:

element.addEventListener('click', user.greeting.bind(user));
阿神

@边城狂人 已经把问题解释清楚了,只是做点补充说明。

问题是怎么出现的

JS中的this只与函数调用方式有关,与定义时的上下文,函数作用域,都无关。有如下情况:

user.greeting()      // this --> user

var handler = user.greeting;
handler()            // this --> window

当程序执行到

element.addEventListener('click', user.greeting);

user.greeting作为addEventListener的第二个参数,假设这个参数就叫handler。可以想象,在addEventListener的内部,进行了类似

var handler = user.greeting;   // 这步在传递参数时完成
handler()            // this --> window

的过程,this的指向就发生了改变。

如何修复

this的指向只与函数调用方式有关,函数调用方式一共四种:

func();

obj.func();

func.apply/call();

new func();

要修复这个问题,需要用到apply/call这种调用方式。我们可以想象bind是这样一个函数:

function bind ( func, target ) {
    return function () {
        func.apply( target, arguments );
    }
}

Function.prototype['bind'] = function ( target ) {
    return bind( this, target );
}

这样,就可以使用element.addEventListener('click', user.greeting.bind(user));来解决这个问题了。当然,这里的bind是非常简化、不可用的,比如可以看到bindreturn的函数已经不是原函数了,为了保持一致性应该绑定原型链。这一系列完整的操作在MDN文档中都可以看到。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号