1

我正在尝试在 elem 的 onclick 中访问 MainObj 的属性。有没有更好的方法来设计它,所以引用不会是“MainObj.config.url”,而是类似 this.config.url

示例代码:

var MainObj = {
      config: { url: 'http://www.mysite.com/'},
      func: function()
      {
          elem.onclick = function() {
           var url_pre = MainObj.config.url+this.getAttribute('href');

           window.open(url_pre, '_new');
          };
      }

}
4

3 回答 3

4

对象内部的“this”总是指代它自己(对象)。只需将上下文保存到变量中并使用它。该变量通常称为“_this”、“self”或“_self”(这里我使用_self):

var MainObj = {
  config: { url: 'http://www.mysite.com/'},
  func: function()
  {
      var _self = this;
       elem.onclick = function() {
       var url_pre = _self.config.url+this.getAttribute('href');

       window.open(url_pre, '_new');
      };
  }
}
于 2013-01-16T08:27:35.643 回答
3

您可以使用模块模式

var MainObj = (function () {
      var config = { url: 'http://www.mysite.com/'};
      return {
         func: function() {
             elem.onclick = function() {
                 var url_pre = config.url+this.getAttribute('href');
                 window.open(url_pre, '_new');
             };
          }
      };
}());

首先我们config在本地函数范围内定义对象。之后,我们在 return 语句中返回一个对象字面量。该对象包含func稍后可以调用的函数,例如:MainObj.func.

于 2013-01-16T08:27:28.083 回答
1

肯定有更好的方法......但我必须说:在方法中绑定事件处理程序是 - 我很抱歉 - 一个糟糕的想法。
您可能想查看 MDN,了解它对this关键字的说明,因为this它使许多人感到困惑和绊倒。例如,在您的代码段this中使用正确:它将引用 elem. 话虽如此,这就是你可以做的:

var MainObj = (function()
{
    var that = {config: { url: 'http://www.google.com/'}};//create closure var, which can be referenced whenever you need it
    that.func = function()
    {
        elem.onclick = function(e)
        {
            e = e || window.event;
            window.open(that.config.url + this.getAttribute('href'));
        };
    };
    return that;//expose
}());

但正如我所说,在方法中绑定事件处理程序并不是要走的路:

MainObj.func();
MainObj.func();//shouldn't be possible, but it is

为什么不呢,只需这样做:

var MainObj = (function()
{
    var that = {config: { url: 'http://www.google.com/'}};
    that.handler = function(e)
    {
        e = e || window.event;
        window.open(that.config.url + this.getAttribute('href'));
    };
    that.init = function(elem)
    {//pass elem as argument
        elem.onclick = that.handler;
        delete that.init;//don't init twice
        delete that.handler;//doesn't delete the function, but the reference too it
    };
    return that;//expose
}());
MainObj.init(document.body);

即便如此,这根本不是我编写此代码的方式但我确实时不时地倾向于使事情过于复杂。但是一定要研究一下 JS 中调用上下文是如何确定的,以及闭包、对象引用和 GC 是如何工作的……这是值得的。

更新:
根据 OP 的要求 - 另一种方法

(function()
{
    'use strict';
    var config = {url: 'http://www.google.com/'},
    handlers = {load: function(e)
        {
           document.getElementById('container').addEventListener('click',handlers.click,false);
        },
        click: function(e)
        {
            e = e || window.event;
            var target = e.target || e.srcElement;
            //which element has been clicked?
            if (target.tagName.toLowerCase() === 'a')
            {
                window.open(config.url + target.getAttribute('href'));
                if (e.preventDefault)
                {
                    e.preventDefault();
                    e.stopPropagation();
                }
                e.returnValue = false;
                e.cancelBubble = true;
                return false;//overkill
            }
            switch(target.id)
            {
                case 'foo':
                    //handle click for #foo element
                return;
                case 'bar': //handle bar
                return;
                default:
                   if (target.className.indexOf('clickClass') === -1)
                   {
                       return;
                   }
            }
            //treat elements with class clickClass here
        }
    };
    document.addEventListener('load',handlers.load,false);//<-- ~= init
}());

这只是一个例子,远未完成。像调用这样的事情preventDefault,我倾向于避免(为了 X 浏览器的兼容性和易用性,我增加了Event.prototype.
我不会发布大量指向我自己的问题的链接,但请查看我的个人资料并检查 JavaScript 问题。您可能会感兴趣的几个示例(包括一个关于如何在 X 浏览器上下文中增强 Event.prototype 的示例)

于 2013-01-16T08:36:16.350 回答