为什么`this`不等于`Object`,为什么属性`undefined`?

时间:2014-10-02 10:59:07

标签: javascript object

此对象实现了一个提供事件侦听器的模式。它至少适用于IE 11和Chrome。

但我不明白为什么,我有两个问题。

在按键事件监听器中,有一条警告显示this等于[object HTMLInputElement]this.elementundefined

  1. 为什么this不等于Object
  2. 为什么this.element undefined? (注意它是在init方法中初始化的。)
  3. 请参阅此JSFiddle

    这是JavaScript:

    function CustomEditor(id) {
        'use strict';
        this.element = null;
        this.id = id;
        this.init();
    };
    
    CustomEditor.prototype.addEvent = function (event, callback) {
        'use strict';
        return this.element.addEventListener(event, callback, false);
    };
    
    CustomEditor.prototype.init = function () {
        'use strict';
        this.element = document.getElementById(this.id);
        this.addEvent('keypress', this.onCustomKeyPress);
    };
    
    
    CustomEditor.prototype.onCustomKeyPress = function () {
        'use strict';
        // alert("keypress event handler");
        this.style.backgroundColor = "#000";
        this.style.color = "#ff0";
        alert('this = ' + this + '\n\nthis.element = ' + this.element);
    };
    
    
    // create and initialize custom editor
    ce = new CustomEditor('myInput1');
    document.getElementById('myInput1').value = 'a';
    alert('ce = ' + ce + '\n\nce.element = ' + ce.element);
    

    编辑:来自@Bergi&的评论@lombausch,我理解我在this和上下文(周末战士在这里)的误解。我对我的对象进行了以下修改,现在this具有我需要的上下文。 (我使用call而不是bind,因此代码适用于较旧的浏览器。)

    MyObj.prototype.addEvent = function (event, callback, caller) {
        'use strict';
        if (typeof window.addEventListener === 'function') {
            return this.element.addEventListener(event, function () {
                callback.call(caller);
            }, false);
        }
        // for older versions of IE, order of test is important
        return this.element.attachEvent('on' + event, function () {
            callback.call(caller);
        });
    };
    

    JSFiddle

    但是一个新问题onCustomKeypress有权访问事件接口/对象的模式需要进行哪些更改?

    事件接口是事件监听器的第一个参数,但我似乎无法将其传递给回调函数。例如,这不起作用:

      MyObj.prototype.onCustomKeyPress = function (e) {
    

1 个答案:

答案 0 :(得分:0)

  

(我使用调用而非绑定,因此代码适用于较旧的浏览器。)

为什么呢? bind显然要简单得多。如果您希望它与旧版浏览器一起使用,只需在代码中的某处包含this simple polyfill即可。

  

必须对onCustomKeypress的模式进行哪些更改才能访问事件接口/对象?

无。问题仍然是你的addEvent函数,它现在可以使用正确的上下文调用callback但没有参数。两种解决方案:

  • 请改用arguments objectapply

    …(…, function() {
        callback.apply(caller, arguments);
    } …
    
  • 只需将事件参数传递给call - 它在上下文之后需要任意数量的正常参数:

    MyObj.prototype.addEvent = function(event, callback, caller) {
        'use strict';
        if (typeof window.addEventListener === 'function') {
            this.element.addEventListener(event, function(e) {
                callback.call(caller, e);
            }, false);
        } else {
            // for older versions of IE, order of test is important
            this.element.attachEvent('on' + event, function() {
                callback.call(caller, window.event);
            });
        }
    };