0

假设我有这样的设置。

var Account = function(data) {
  this.data = data;
  this.domElement = (function(){ code that generates DOM element that will represent this account })();
  this.domElement.objectReference = this;
}

Account.prototype = {
  show: function() { this.domElement.classList.remove('hidden'); },
  hide: function() { this.domElement.classList.add('hidden') }
}

我的问题是关于最后一行:this.domElement.objectReference = this;

拥有这将是一件有用的事情,因为这样我就可以将事件侦听器添加到我的 DOM 元素中,并且仍然可以访问对象本身。例如,我可以添加会影响我的 DOM 元素的方法,例如 hide() 和 show(),而不必直接使用 CSS 修改 DOM 元素的可见性。

我测试了这段代码,它像我想要的那样工作,但我很好奇这是否会导致内存泄漏或其他一些不愉快的事情,或者它是否可以接受?

谢谢!卢卡

4

3 回答 3

2

我知道@PaulS 已经回答了这个问题。已经,但我发现答案反直觉(不希望从 Account 构造函数返回 DOM 元素)并且过于以 DOM 为中心,但同时实现非常简单,所以我不知道该怎么想;)

无论如何,我只是想展示一种不同的方式。您可以将Account实例存储在地图中并给它们一个唯一的id(也许他们已经有一个),然后将其id作为数据属性存储在 DOM 元素上。最后,您实现一个getById函数或类似的东西来id从侦听器中检索帐户实例。

这就是 jQuery 的data工作原理。

这是一个示例,其中包含您希望从评论中获得的委托事件。

演示

var Account = (function (accounts, id) {

    function Account(data) {
        accounts[this._id = ++id] = this;

        this.el = createEl.call(this);
    }

    Account.prototype = {
        constructor: Account,
        show: function() { this.el.classList.remove('hidden'); },
        hide: function() { this.el.classList.add('hidden'); }
    };

    function createEl() {
        var el = this.el = document.createElement('div');
        el.className = 'account';
        el.innerHTML = el.dataset.accountId = this._id;

        return el;
    }

    Account.getById = function (id) {
        return accounts[id];
    };

    Account.init = function () {
        //add delegate listeners

        document.addEventListener('click', function (e) {
            var target = e.target,
                account = Account.getById(target.dataset.accountId);

            if (!account) return;

            account.hide();
        });
    };

    return Account;
})({}, 0);

//once DOM loaded
Account.init(); //start listening to events

var body = document.body;

body.appendChild(new Account().el);
body.appendChild(new Account().el);
于 2013-10-19T01:37:40.023 回答
1

为什么不domElement作为variable,return它来自您的功能?要保留对构造对象的引用(但仅在this预期的位置),您可以执行if (this instanceof Account) domElement.objectReference = this;

您现在已将自己从循环引用中解救出来,并且可以访问NodeObject。如果您希望丢失对Account实例的直接引用,但希望在稍后“查找”与其相关的节点时需要它,那么这样做会更有帮助。

按要求编码

var Account = function (data) {
    var domElement; // var it
    this.data = data;
    domElement = (function(){/* ... */}()); // use var
    if (this instanceof Account)
        domElement.objectReference = this; // assign `this`
    return domElement;
};
// prototype as before

返回的元素现在是Node,而不是Object;所以你可以像这样访问Account实例

var domElement = new Account();
domElement.objectReference.show(); // for example
于 2013-10-19T00:02:09.737 回答
0

在我看来,在对象本身内部引用对象并没有什么好处。造成这种情况的主要原因是复杂性和模糊性。

如果您稍后在代码中指出您是如何使用它domElement.objectReference的,我相信我或其他人将能够在没有此参考的情况下提供解决方案。

于 2013-10-18T23:37:59.980 回答