我该如何处理“这个”?在包含其他 javascript 对象的 javascript 对象中?

发布于 2024-11-17 01:10:20 字数 1915 浏览 3 评论 0原文

我正在使用 John Resig 的优秀 javascript 类来实现简单的 javascript 继承,并且我有有点麻烦让我思考一些与“this”关键字相关的变量范围问题。

我的扩展类看起来有点像这样,

var EUNode = Class.extend({

    // Methods
    //-------------------------------------------------------------------------------
    init : function(){

        this.div = this.createDiv();
        this.canDoStuff = true;
        this.div.addEventListener(touchstart, this.touchStartHandler, false);

    },



    // Create Div
    //-------------------------------------------------------------------------------
    createDiv : function(){

        // code to create a DIV element, add some classes and do some 
        // other useful stuff

    },

    touchStartHandler : function(event){

        // In here, 'this' refers to the div element, so the 
        // following condition doesn't work
        if(this.canDoStuff){

            // do some stuff

        }

    }

});

我需要能够从 touchStartEventHandler 内部引用 EUNode 实例,所以我尝试了以下操作,

var EUNode = Class.extend({

    // Methods
    //-------------------------------------------------------------------------------
    init : function(){

            this._super();
            // Store a reference to 'this' globally
        self = this; 
        self.div = this.createDiv();
        self.canDoStuff = true;
        self.div.addEventListener(touchstart, self.touchStartHandler, false);

    },

    touchStartHandler : function(event){

        if(self.canDoStuff){

            // Now I can do stuff, but 'self' is now a global variable
                    // which isn't what I want. If there's more than one instance
                    // of EUNode, 'self' references the newest instance.

        }

    }

});

所以我陷入了循环。似乎为了全局限制“self”的范围,我需要使用“this”关键字,但“this”意味着事件处理程序中的其他内容。有什么建议吗?

I'm using John Resig's excellent javascript class for simple javascript inheritance and I'm having a spot of bother getting my head around some variable scope problems in relation to the 'this' keyword.

My extended class looks a little like this

var EUNode = Class.extend({

    // Methods
    //-------------------------------------------------------------------------------
    init : function(){

        this.div = this.createDiv();
        this.canDoStuff = true;
        this.div.addEventListener(touchstart, this.touchStartHandler, false);

    },



    // Create Div
    //-------------------------------------------------------------------------------
    createDiv : function(){

        // code to create a DIV element, add some classes and do some 
        // other useful stuff

    },

    touchStartHandler : function(event){

        // In here, 'this' refers to the div element, so the 
        // following condition doesn't work
        if(this.canDoStuff){

            // do some stuff

        }

    }

});

I need to be able to reference the EUNode instance from inside the touchStartEventHandler, so I tried the following

var EUNode = Class.extend({

    // Methods
    //-------------------------------------------------------------------------------
    init : function(){

            this._super();
            // Store a reference to 'this' globally
        self = this; 
        self.div = this.createDiv();
        self.canDoStuff = true;
        self.div.addEventListener(touchstart, self.touchStartHandler, false);

    },

    touchStartHandler : function(event){

        if(self.canDoStuff){

            // Now I can do stuff, but 'self' is now a global variable
                    // which isn't what I want. If there's more than one instance
                    // of EUNode, 'self' references the newest instance.

        }

    }

});

So I'm stuck in a loop. It seems that in order to limit the scope of "self" globally, I need to use the "this" keyword, but "this" means something else inside event handlers. Any tips?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

天赋异禀 2024-11-24 01:10:20

是的,全局变量是不好的(一般来说)。正如您自己所注意到的,如果您有两个 EUNode 实例,您就会遇到麻烦,因为最后一个实例会覆盖全局 self

您还使 touchStartHandler 依赖于某些全局变量,并且该函数的整个工作可能不再那么清晰。

只需在正确的上下文中调用 touchStartHandler

init : function(){
    var self = this;  // <- local `self`

    this.div = this.createDiv();
    this.canDoStuff = true;

    // pass a closure, making `self` available inside the function
    this.div.addEventListener(touchstart, function(event) {
        self.touchStartHandler(event);
    }, false);
},

在支持 ECMAScript 5 的浏览器中,您还可以使用 .bind() [docs](请参阅链接其他的实现browsers)来绑定元素 this 应该引用:

this.div.addEventListener(touchstart, this.touchStartHandler.bind(this), false);

Yes, global variables are bad (in general). As you noticed yourself, you already get in trouble if you have two EUNode instances because the last one would override the global self.

You are also making touchStartHandler dependent on some global variable, and the whole working of this function might not be so clear anymore.

Just call touchStartHandler in the right context:

init : function(){
    var self = this;  // <- local `self`

    this.div = this.createDiv();
    this.canDoStuff = true;

    // pass a closure, making `self` available inside the function
    this.div.addEventListener(touchstart, function(event) {
        self.touchStartHandler(event);
    }, false);
},

In browsers supporting ECMAScript 5 you can also use .bind() [docs] (see link for an implementation for other browsers) to bind the element this should refer to:

this.div.addEventListener(touchstart, this.touchStartHandler.bind(this), false);
-柠檬树下少年和吉他 2024-11-24 01:10:20

当您建立事件处理程序时,只需将对“touchStartHandler()”的调用包装在匿名函数中,以便您通过类的适当实例来调用它。

换句话说:

var boundHandler = function(event) { yourInstance.touchStartHandler(event); };

然后函数“boundHandler”可用于处理事件,并且实际代码将始终使用 this 引用正确的对象来设置。

在较新的浏览器中还有一个名为“.bind()”的函数,可以让您执行相同的操作。

When you establish the event handler, just wrap the call to "touchStartHandler()" in an anonymous function, such that you call it through the appropriate instance of your class.

In other words:

var boundHandler = function(event) { yourInstance.touchStartHandler(event); };

Then the function "boundHandler" can be used to handle the events, and the real code will always be set up with this referencing the right object.

There's also a function in newer browsers called ".bind()" that lets you do the same thing.

深爱不及久伴 2024-11-24 01:10:20

而不是

self.div.addEventListener(touchstart, self.touchStartHandler, false);

尝试

self.div.addEventListener(touchstart, function(event) { self.touchStartHandler(event) }, false);

Instead of

self.div.addEventListener(touchstart, self.touchStartHandler, false);

Try

self.div.addEventListener(touchstart, function(event) { self.touchStartHandler(event) }, false);
只等公子 2024-11-24 01:10:20

self.touchStartHandler.bind(self)

self.touchStartHandler.bind(self)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文