事件处理函数中this的指向以及函数上下文的继承

96
small_a
2017.01.21 20:37* 字数 677

转载自martin的博客

最近在写程序的时候,一直有一个疑问,就是事件处理函数在绑定之后,该事件绑定的回调函数的this的指向以及该函数可以访问的作用域是怎么样的 。今天有空做了一下测试,总结一下:
1. 事件处理函数绑定之后,this指向该事件绑定的元素。
2. 事件处理函数可以访问的作用域:包括了该绑定发生时的上下文。

this的测试

这个测试很简单,写一个html代码对this进行输出就可以验证this的指向。我的测试代码如下。body onload触发init函数,对body绑定了onclick函数,该函数输出this的值,结果表明输出的就是body节点。所以在事件处理函数中,this指向绑定的元素,当然,用bind是可以修改this的指向。

<html>

<head>
    <meta charset="utf-8">
</head>

<body onload = 'init()'>
    <p>给body绑定了onclick事件</p>
    <p>点击body</p>
    <p>在控制台输出this的值</p>
    <script>
        var obj = {
          name:'xiaobo',
          age:'23'
        };
        function init() {
            document.body.onclick = function() {
                console.log(this)//body
            };
        }
        // function init() {
        //     document.body.onclick = function() {
        //         console.log(this)//obj
        //     }.bind(obj);
        // }
    </script>
</body>

</html>

作用域测试

在js中,函数的作用域往往是内部的函数可以访问外部函数的作用域,而外部的函数无法访问内部的作用域,能够访问外部函数作用域的函数也成为闭包。事件绑定操作有DOM2,DOM0,IE的方法,不论用哪种方法,都可以进行绑定,我的疑问在于绑定的事件处理函数,它的作用域是哪里,能不能访问外部函数的作用域。为了了解这一点,我做了下面这个测试。

<html>

<head>
    <meta charset="utf-8">
</head>

<body onload = 'init()'>
    <p>给body绑定了onclick事件</p>
    <p>点击body</p>
    <p>在控制台输出this的值</p>
    <script>
        var obj = {
          name:'xiaobo',
          age:'23'
        };
        function init() {
            var obj2 = {
              name:'xiaobo2',
              age:'25'
            }
            document.body.onclick = function() {
                console.log(obj2);//obj2
                console.log(obj);//obj
            };
        }
        // function init() {
        //     document.body.onclick = function() {
        //         console.log(this)
        //     }.bind(obj);
        // }
    </script>
</body>

</html>

在上述代码中,body.onclick的事件处理函数,输出了init函数中定义的obj2,全局定义的obj,均能进行输出,证明onclick的回调函数继承了事件绑定的上下文,也就是事件处理函数(回调函数)能够拥有事件绑定的时候的上下文(本例中,事件是在init函数中进行绑定,所以回调函数继承了init这个作用域,能够访问到obj2)同时,Init本身也是定义在全局中,所以回调函数也可以访问到全局作用域。

总结

通过这两个测试,可以很明显的看出来this的指向以及上下文的继承,虽然在上面只列出了采用DOM0进行事件绑定的例子,但是DOM2的事件回调中this和上下文的继承关系都是这样的,IE中没有进行测试。IE嘛。。。

前端
Web note ad 1